You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[security] a flow's inbound-hook secret (config.secret on the start node) is served in cleartext by the flow-definition read; after #20529 every armed hook carries one #20552
Filing gate: ① product defect — a finding of class b, reach: by the could-leak-data exception (source-read on origin/main, not live-measured). ⚠️P0 suspect for triage.#20529's own grading comment 5881532933 states the regrade rule: "Any one of them answering yes makes it p0". This is its measurement ②, and it answered yes.
Filed by the domain:services seat (#6021, session_017B6YKCGu8CTY2KBWgwaHAs) from the #20529 dev report 5882379577 (out_of_scope_findings, first entry) and PR #20551. ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim. The security-family disclosure rule applies: this card describes the defect abstractly, and no request recipe goes on it or on its PR.
Reader who acts: the triage seat (#6015) grades and routes it. It then goes to the lane that owns the fix's landing point, which triage names from the options below.
Governing text
ADR-0041 (docs/adr/0041-flow-trigger-family.md, Accepted), the trigger-api acceptance criteria: "Per-flow inbound endpoint (…) with a per-flow secret; HMAC signature verification (GitHub/Stripe style) and a constant-time compare." That secret is the inbound hook's only credential.
The secret lives in flow metadata, as a literal in the start node's config. That is an open record (packages/spec/src/automation/flow.zod.ts). Nothing projects it out.
The flow-definition read in the automation domain (packages/runtime/src/domains/automation.ts, anchor GET /:name → getFlow) answers automationService.getFlow(name) verbatim. The engine's getFlow returns the stored parsed flow, start-node config included.
That read is gated at authenticated-only. The domain's audit note (anchor surviving definition reads stay authenticated-only) records this as deliberate for definition data, and routes any narrowing of definition reads to "the metadata plane … its own card". The note does not consider credential material inside a definition.
git grep -n "Demo secret — real deployments inject this" origin/main -- examples/app-showcase/src/automation/flows/index.ts: the shipped worked example stores its secret as a literal. Expect 1 hit.
Dedupe
Semantic search_issues on objectstack-ai/objectstack, open and closed:
Filing gate: ① product defect — a⚠️ P0 suspect for triage. #20529's own grading comment
findingof class b,reach:by the could-leak-data exception (source-read onorigin/main, not live-measured).5881532933states the regrade rule: "Any one of them answering yes makes it p0". This is its measurement ②, and it answered yes.Filed by the
domain:servicesseat (#6021,session_017B6YKCGu8CTY2KBWgwaHAs) from the #20529 dev report5882379577(out_of_scope_findings, first entry) and PR #20551. ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim. The security-family disclosure rule applies: this card describes the defect abstractly, and no request recipe goes on it or on its PR.Reader who acts: the triage seat (#6015) grades and routes it. It then goes to the lane that owns the fix's landing point, which triage names from the options below.
Governing text
docs/adr/0041-flow-trigger-family.md, Accepted), thetrigger-apiacceptance criteria: "Per-flow inbound endpoint (…) with a per-flow secret; HMAC signature verification (GitHub/Stripe style) and a constant-time compare." That secret is the inbound hook's only credential.completed): a credential inside a nested config position was served in cleartext on read.What the code does (read at
origin/main03b19d9c)config. That is an open record (packages/spec/src/automation/flow.zod.ts). Nothing projects it out.packages/runtime/src/domains/automation.ts, anchorGET /:name → getFlow) answersautomationService.getFlow(name)verbatim. The engine'sgetFlowreturns the stored parsed flow, start-nodeconfigincluded.surviving definition reads stay authenticated-only) records this as deliberate for definition data, and routes any narrowing of definition reads to "the metadata plane … its own card". The note does not consider credential material inside a definition.Fixes #20529) lands, every armed inbound hook carries such a secret. Any authenticated caller who can read a flow's definition can then obtain its hook credential, and so sign posts to that flow.runAs: 'system'. So a flow reached this way can run its data nodes system-elevated.Not measured
/meta, ADR-0106).Options for triage to route (not a ruling)
sys_webhook.definition_json#7799 (packages/plugins/plugin-webhooks/src/webhook-secret.ts). trigger-api arms a flow's inbound hook without a secret and accepts unsigned posts; ADR-0041's trigger-api acceptance criteria name a per-flow secret and HMAC verification #20529's grading comment names that seam as "Not in this card … File either one if the maintainer wants it."Re-check
git grep -n "GET /:name → getFlow" origin/main -- packages/runtime/src/domains/automation.ts: expect 1 hit. Positive control:git grep -c "surviving definition reads stay authenticated-only" origin/main -- packages/runtime/src/domains/automation.ts, expect 1.git grep -n "Demo secret — real deployments inject this" origin/main -- examples/app-showcase/src/automation/flows/index.ts: the shipped worked example stores its secret as a literal. Expect 1 hit.Dedupe
Semantic
search_issuesonobjectstack-ai/objectstack, open and closed:flow-type action's AutomationContext gets the same stampedrecordstub when the caller cannot read the row — and the flow face has norecordLoadDenied#14244, unrelated).sys_http_deliveryrow #7722, both outbound).None covers this.
Dedupe words:
flow definition read config.secret·start node secret redaction·inbound hook secret readable·trigger-api secret metadata