Skip to content

Add Secret[T]: values a run's record never shows - #114

Merged
qfeuilla merged 2 commits into
mainfrom
secrets
Oct 31, 2026
Merged

qfeuilla merged 2 commits into
mainfrom
secrets

Conversation

@qfeuilla

Copy link
Copy Markdown
Contributor

A node makes a secret with ctx.secret and reveals one with ctx.reveal, ctx.reveal_in or ctx.reveal_input. What flows on wires, and what a run's record and everything that reads it holds, is a marker naming the secret. The value is sealed beside the record (new table run_secret, written with the run's own batches) and deleted with it.

What breaks (the CHANGELOG says how to move):

  • A caller's credential headers (authorization, proxy-authorization, cookie, weft-instance-token, and the headers a route's auth reads) come out of Route and Socket on the new credentials output, as secrets, never on headers.
  • weft run --fire refuses credential headers and the headers the route's gate reads.
  • A secret its type does not declare fails the node that would send it outside weft (HttpRequest body and headers, Reply, Stream, ExecPython inputs, any node revealing through the ctx), naming the input and where the secret is.
  • MintInstanceToken's token is a Secret[String].

Also: the type checker keeps a secret out of plain ports, Json and JsonDict; a program cannot write, cast or instance-fill one. HttpRequest's body takes its type from what is wired into it, so a declared object can carry a secret; a plain body builds and runs as before. The old text scrubbing of records (Redaction) is gone. The reveal call to the broker is marked harmless to send twice (a read).

Extension: extension-vscode 0.2.282 (packages/weft-graph knows the new type).

Run locally before pushing: full nextest, doc tests, workspace clippy -D warnings, the parse-only build, hakari, validate-examples, every database test, every JS package test and compile, the bridge, postgres credential and Kilo tests, the browser extension checks, the docs build, Terraform validate and its moved-targets test. All green.

A node makes a secret with ctx.secret and reveals one with ctx.reveal,
ctx.reveal_in or ctx.reveal_input. What flows on wires, and what the run's
record and everything that reads it holds, is a marker naming the secret;
the value is sealed beside the record (table run_secret, written with the
run's own batches) and deleted with it.

A caller's credential headers (authorization, proxy-authorization, cookie,
weft-instance-token, and the headers the route's auth gate reads, a gated
socket's ticket included) are made secrets at the door and come out on the
new `credentials` output of Route and Socket, never on `headers`. The old
scrubbing of the record (Redaction) is gone.

The type checker keeps a secret out of plain ports, Json and JsonDict; a
program cannot write, cast or instance-fill one. HttpRequest (headers and
a body whose declared type says where the secret is), Reply, Stream and
ExecPython reveal a secret where their input's declared type places it,
and fail naming the input and the place when a secret sits where no type
declares one (a Stream's bus message included). MintInstanceToken's token
is a Secret[String]. `weft run --fire` refuses credential headers and the
headers a route's gate reads.
@qfeuilla
qfeuilla merged commit 49f962f into main Oct 31, 2026
26 checks passed
@qfeuilla
qfeuilla deleted the secrets branch October 31, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant