A browser cannot hold a signing key
The credential model is what it holds instead, the kit’s own account of this path is the implementation, the zero-logging commitment covers what does transit us, and what it never stores is what does not.
Shipping one to a page is shipping it to every extension, every debugger, and every copy of that page’s storage.
So the browser gets a sixty-second one
Our server mints a short-lived, single-scope, user-bound token and hands it to your browser, which calls your Worker directly.
Response bodies never touch our origin on that path, and our private key never leaves our server.
sequenceDiagram
autonumber
actor You as You, an admin
participant Pane as The dashboard,<br/>in your browser
participant Ours as Our Worker
box Your Cloudflare account
participant W as Your Worker
participant DB as Your D1
end
You->>Pane: open a pane
Pane->>Ours: ask for a token for this one call
Ours->>Ours: mint it: sixty seconds, one scope,<br/>bound to you and to the body
Ours-->>Pane: the token — the private key never leaves our server
Pane->>W: call the discovered route, on pithy-control-plane
W->>DB: verify against the public key you hold
W->>DB: read the records
DB-->>W: rows
W-->>Pane: the response, straight back
Note over Ours: Response bodies never touch our origin on this path.
Pane-->>You: the pane renders
opt After a secrets:rotate act, and only that one
Pane->>Ours: report the outcome it already validated
Ours->>Ours: write an audit row — secret and environment names, never values
end
opt The only calls we make from our own server
Ours->>W: the connect proving ping, and the key-rotation workflow
W-->>Ours: neither one carries a pane's data
end
The gap in our lifeline between steps 5 and 9 is the argument: that stretch is your browser talking to your Worker, and we are not on it.
Your Worker cannot tell the difference, deliberately
A browser call and a machine call are the same token, verified by the same code.
There is no second token class to get wrong, and no route whose auth model depends on which client made the call.
What does pass through us
Two calls, and neither one carries a pane’s data: the ping that proves a new connection answers, and the key rotation that appends a successor. Both are ours to start, so neither can be made from a browser — only our server holds a private key.
There is no third. No pane fetches through us, because there is nothing here to fetch through: the dashboard has no route that relays a response from your Worker.
One thing does come back to us, and only one. After you rotate a secret, your browser reports the outcome it already read so the act lands in your audit trail. That row carries the names of the secret and the environments — never a value, and nothing at all for any other kind of act.
Where a response does reach our server, the commitment is a zero-logging policy on your data — see the zero-logging commitment.
Every response is validated
A malformed, hostile, or unavailable response from your Worker must not crash a pane or reach your browser unvalidated.
That is a tested boundary rather than an assumption — your Worker is a service we do not control, and it is treated that way.
What the browser is shown
The record is one thing in full. The index lists the things of a kind. The rail names the kinds.
Left to right, always — and the triad is meaning rather than layout, so it holds whatever the things are.
Where scopes show up in the UI
Each declared route names the scope it needs, and the manifest reports what you granted.
So an action you did not grant is grayed out rather than offered and answered with a 403.
The paths are discovered, not assumed
A client that hardcoded /payments would 404 against exactly the adopters who customized anything.
Every capability’s mount point is configurable, and each builds its manifest entry from its resolved config — so the dashboard calls where things actually are.
The one address it cannot discover is the seam’s own, which is why pithy dashboard connect sends it at registration.