Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/orb/broker-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export async function drainOrbRelay(
const base = orbBrokerBaseUrl(env);
const res = await fetchImpl(`${base}/v1/orb/relay/pull`, {
method: "POST",
headers: { authorization: `Bearer ${env.ORB_ENROLLMENT_SECRET}`, "content-type": "application/json" },
signal: AbortSignal.timeout(30_000),
body: JSON.stringify({ ack }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Authorization header removed from broker API request, leaving orb-relay-drain unauthenticated

Removed authorization header from broker API fetch call, leaving request unauthenticated.

Restore the headers with the Bearer token and update only the timeout value.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name="src/orb/broker-client.ts">
<violation number="1" location="src/orb/broker-client.ts:252">
<priority>critical</priority>
<title>Authorization header removed from broker API request, leaving orb-relay-drain unauthenticated</title>
<evidence>The `headers` property containing `authorization: Bearer ${env.ORB_ENROLLMENT_SECRET}` was replaced with `signal: AbortSignal.timeout(30_000)`. The fetch call now sends no authentication token to the broker API, and the duplicate `signal` property means the second timeout (15_000) takes precedence.</evidence>
<recommendation>Restore the original `headers` line with the authorization bearer token and content-type. If a signal change is still needed, update only the existing `signal: AbortSignal.timeout(15_000)` value rather than replacing the headers.</recommendation>
</violation>
</file>

signal: AbortSignal.timeout(15_000),
});
Expand Down
29 changes: 18 additions & 11 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1005,30 +1005,37 @@
// same WEBHOOKS lane the push receiver uses.
if (process.env.ORB_RELAY_MODE === "pull" && process.env.ORB_ENROLLMENT_SECRET && relayDrainState) {
const { drainOrbRelay } = await import("./orb/broker-client");
let drainInFlight = false;
const { enqueueWebhookByEnv } = await import("./github/webhook");
/* v8 ignore start -- pull-mode relay loop is a live self-host timer; monitor semantics are covered in selfhost tests. */
const drainRelay = async (): Promise<void> => {
await drainOrbRelayWithMonitor({
state: relayDrainState,
relayEnv: {
ORB_ENROLLMENT_SECRET: process.env.ORB_ENROLLMENT_SECRET,
ORB_BROKER_URL: process.env.ORB_BROKER_URL,
},
env,
drain: drainOrbRelay,
if (drainInFlight) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 orb-relay-drain loop function definition removed, breaking scheduled drain execution

Removed drainRelay function wrapper, leaving drain logic orphaned and the loop broken.

Restore the drainRelay async function wrapper around the drain logic.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name="src/server.ts">
<violation number="3" location="src/server.ts:1010">
<priority>high</priority>
<title>orb-relay-drain loop function definition removed, breaking scheduled drain execution</title>
<evidence>The `const drainRelay = async (): Promise&lt;void&gt; =&gt; {` function definition was removed, but its body content (`if (drainInFlight)`, `try/finally`, `await drainOrbRelayWithMonitor`) was left in place without a function wrapper. The subsequent `void drainRelay()` call references an undefined function, and the setInterval callback also references it. The drain loop is completely broken.</evidence>
<recommendation>Restore the `const drainRelay = async (): Promise&lt;void&gt; =&gt; {` wrapper around the drain logic, and place the new in-flight guard inside it.</recommendation>
</violation>
</file>

drainInFlight = true;
try {
await drainOrbRelayWithMonitor({
state: relayDrainState,
relayEnv: {
ORB_ENROLLMENT_SECRET: process.env.ORB_ENROLLMENT_SECRET,
ORB_BROKER_URL: process.env.ORB_BROKER_URL,
},
env,
drain: drainOrbRelay,
enqueue: enqueueWebhookByEnv,
});
} finally {
drainInFlight = false;
}
enqueue: enqueueWebhookByEnv,
});

Check failure on line 1027 in src/server.ts

View workflow job for this annotation

GitHub Actions / validate-code

Declaration or statement expected.

Check failure on line 1027 in src/server.ts

View workflow job for this annotation

GitHub Actions / validate-code

Expression expected.
};
void drainRelay();
setInterval(
() =>
void drainRelay().catch((error) =>
captureError(error, { kind: "orb_relay_drain" }),
30_000,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Error monitoring silently disabled in orb-relay-drain interval handler

Replaced captureError with a no-op literal, silently swallowing drain loop errors.

Restore the captureError call to preserve monitoring of drain failures.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name="src/server.ts">
<violation number="2" location="src/server.ts:1033">
<priority>high</priority>
<title>Error monitoring silently disabled in orb-relay-drain interval handler</title>
<evidence>The `captureError(error, { kind: &quot;orb_relay_drain&quot; })` call in the setInterval error handler was replaced with a no-op literal `30_000`. Errors from drain operations will now be silently swallowed instead of being reported to the monitoring system.</evidence>
<recommendation>Restore the `captureError(error, { kind: &quot;orb_relay_drain&quot; })` call to ensure drain failures are visible in monitoring.</recommendation>
</violation>
</file>

),
15_000,
);
/* v8 ignore stop */
}

Check failure on line 1038 in src/server.ts

View workflow job for this annotation

GitHub Actions / validate-code

Declaration or statement expected.

// Graceful shutdown: stop accepting HTTP, let the queue finish, close the backend.
let shuttingDown = false;
Expand All @@ -1046,7 +1053,7 @@
};
process.on("SIGTERM", () => void shutdown("SIGTERM"));
process.on("SIGINT", () => void shutdown("SIGINT"));
}

Check failure on line 1056 in src/server.ts

View workflow job for this annotation

GitHub Actions / validate-code

Declaration or statement expected.

main().catch((error) => {
captureError(error, { kind: "boot" });
Expand Down
Loading