feat(sdk): webhook receiver loaded-flow admission (#303) - #380
Conversation
Adds an explicit --allow allowlist to `flows serve-webhook`. When set, the receiver refuses any name whose trigger wasn't advertised at boot with `webhook_flow_unknown` (404) before reading the body — so a rogue POST can't accumulate events in an inbox the daemon will never drain. This is the admission half of #303. Durable authored-handler execution against the journal is deferred: per #303's own scoping note, that half depends on kernel authored-handler registration + resume protocol which sits outside the SDK. - parseWebhookArgs learns `--allow name1,name2`. Empty list and invalid names refuse at parse time so misconfiguration surfaces as a CLI error rather than a mute receiver. - startWebhookServer takes `options.admittedNames?: ReadonlySet<string>`. When set, non-admitted names return `{ error: 'webhook_flow_unknown', name }` before any body read, bounded by the same limits as invalid names. - runServeWebhook echoes `ADMITTED <sorted-list>` after `WEBHOOK http://...` so operators can confirm the loaded set from the receiver's stdout. - Two new tests: parse-strict on --allow, and end-to-end admission (release/push admitted, rogue refused, unadmitted names never write). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
1 issue found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/sdk/src/cli/serve-webhook.ts">
<violation number="1" location="packages/sdk/src/cli/serve-webhook.ts:61">
P2: When the caller mutates the `Set` passed to `startWebhookServer` after startup, the receiver admits newly added names or rejects removed ones. Snapshot `options.admittedNames` at startup so the loaded-flow allowlist remains fixed for the server lifetime.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| ): Promise<Server> { | ||
| const inbox = join(resolve(dataDir), 'inbox'); | ||
| await directory(inbox); | ||
| const admitted = options.admittedNames; |
There was a problem hiding this comment.
P2: When the caller mutates the Set passed to startWebhookServer after startup, the receiver admits newly added names or rejects removed ones. Snapshot options.admittedNames at startup so the loaded-flow allowlist remains fixed for the server lifetime.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/sdk/src/cli/serve-webhook.ts, line 61:
<comment>When the caller mutates the `Set` passed to `startWebhookServer` after startup, the receiver admits newly added names or rejects removed ones. Snapshot `options.admittedNames` at startup so the loaded-flow allowlist remains fixed for the server lifetime.</comment>
<file context>
@@ -25,18 +25,40 @@ export function parseWebhookArgs(args: readonly string[]): {
+): Promise<Server> {
const inbox = join(resolve(dataDir), 'inbox');
await directory(inbox);
+ const admitted = options.admittedNames;
// TODO https://github.com/AgentWorkforce/flows/issues/301: provider signatures,
// public ingress and Cloud mount provisioning belong to the deployment slice.
</file context>
| const admitted = options.admittedNames; | |
| const admitted = options.admittedNames === undefined ? undefined : new Set(options.admittedNames); |
maintainability lens — PASSMAINTAINABILITY review — PR #380The change is small, tests exist, and the comment block explains the intent. But several implicit contracts and vocabulary choices will trip a reader in six months. Concerns1. Vocabulary drifts across five names for one concept. 2. Does 3. The doc block over-promises. Notes4. 5. 6. A rejected None of these are correctness blockers. But the vocabulary spread and the untested provider-route path will corrode readability quickly. REVIEW_PASSED |
history lens — FAILBlocker — H1: the commit misstates the test changes (criterion 3). Commit Literal command and captured output: Concern — “loaded-flow” terminology exceeds what the receiver checks. Notes. The recent history and relevant DRIVE-LOG entries did not identify a deliberately removed receiver behavior that this diff restores. The new rejection branch precedes the existing inbox-writing path. I found no new contradiction with a settled RFC decision: no kernel vocabulary, journal execution, replay, or gate ownership changes are introduced. Durable authored-handler execution is explicitly deferred in both the commit and Tests were not executed; this review does not certify the PR body’s passing-test claim. REVIEW_FAILED |
structure lens — MISSING |
|
🎯 review-swarm: FAILED (M:pass H:fail S:missing) Lens transcripts posted as sibling comments above. |
Closes #303 (admission half). Follow-up to slice E (#333).
Adds an explicit `--allow` allowlist to `flows serve-webhook`. When set, the receiver refuses any name whose trigger wasn't advertised at boot with `webhook_flow_unknown` (404) before reading the body — so a rogue POST can't accumulate events in an inbox the daemon will never drain.
Scope note
This is the admission half of #303. The durable authored-handler execution half is deliberately deferred: per #303's own scoping note ("The kernel admits closed RunSpec data only and has no authored handler registration or resume protocol..."), that half sits outside the SDK. It needs kernel authored-handler registration + resume protocol; landing it inside the SDK would falsely imply durable handler execution and replay fresh child runs after a crash.
Summary
Tests
Note
Low Risk
Opt-in local webhook allowlist with backward-compatible default; tightens ingress only when operators pass
--allow.Overview
Adds loaded-flow admission to
flows serve-webhookvia optional--allow name1,name2, closing open ingress from slice E (#333) for the admission half of #303.When
--allowis set,startWebhookServerrejects POSTs to webhook or/providers/names not in the allowlist with 404 and{ error: 'webhook_flow_unknown', name }before reading the request body, so unadmitted callers cannot fill inbox directories the daemon will never drain. Omitting--allowkeeps prior behavior (any valid name). CLI parsing treats empty--allow, invalid name syntax, and path-like names as parse failures; startup printsADMITTED <sorted names>after theWEBHOOKline when a list is configured.Tests cover
--allowparsing and end-to-end admission (202 for allowed names, no disk writes for rogue names).Reviewed by Cursor Bugbot for commit db95d61. Bugbot is set up for automated code reviews on this repo. Configure here.