--- id: RT-GATE-12 family: RT-GATE level: core profiles: [runtime] posture: normative-target added: "1.0" changed: "1.0" source: https://flowdrop.io/spec/rules/rt-gate/rt-gate-12 specification: FlowDrop Workflow Specification 1.0-draft licence: CC BY 4.0 --- # RT-GATE-12 — A resolved secret never persists in the gate prompt *RT-GATE (Part II) · level: core · profiles: runtime · added in 1.0* The prompt an operator reads is stored verbatim. A credential that was substituted into an argument must not be stored along with it, while the consent must still bind to the real call. ## The rule > **Normative.** This is the rule. > > 1. Where a secret reference was substituted into a parameter's value, that parameter is tracked by its top-level name and its whole value is replaced with `` in the prompt shown to the operator and persisted with the interrupt. > > 2. Tracking is by parameter rather than by matching the secret's text, because the substitution may be partial or nested inside a structured value. > > 3. The consent arguments keep the real values, so that consents for different secret values remain distinguishable, and only their digest is ever persisted (RT-GATE-3). > > 4. This covers secrets supplied by configuration only: values delivered by an edge or produced upstream are shown as they are, deliberately; the operator is approving what will be sent. ## What it means Redaction works by parameter name, not by searching the resolved value for the secret's own text. That is why a partial substitution (a token pasted into the middle of a longer string) and a nested one (a reference buried inside a structured value) are both replaced wholesale: the whole value disappears behind ``, not just the substring that came from the reference. Matching on the text itself would miss a secret concatenated, templated or re-encoded on its way into the parameter. The consent question does not use the redacted view. What is hashed to bind the operator's approval to this exact call is the real, resolved value, so a call made with one secret and the same call made with a different one are different questions — approving one never approves the other. This only concerns a secret reference resolved from configuration. A value that arrives already filled in — on a wire, or produced by an earlier step — is shown to the operator exactly as it is, on purpose: the operator is approving what will actually be sent, and a value the workflow itself produced is not something the gate has any reason to hide. ## Example A call resolves one parameter with a secret pasted into a longer string and another with the same secret nested inside a structured value; a third parameter carries no secret at all. ```json title="What the call resolved" verdict="resolved" { "url": "https://example.com/hook", "auth": "Bearer sk_live_do_not_leak", "headers": { "Authorization": "Bearer sk_live_do_not_leak" } } ``` ```json title="What the operator is shown" verdict="redacted" { "url": "https://example.com/hook", "auth": "", "headers": "" } ``` ## Related rules - Names: RT-GATE-1, RT-GATE-3 - Referenced by: RT-GATE-3 --- Rule identifiers are permanent and are never renumbered. This specification carries no implementation status: each implementation publishes its own standing against these rules. Licensed CC BY 4.0.