Skip to main content

Why sign every request

A DFOS credential is not a bearer token. Every credential-gated request also carries a fresh request proof, signed by your app's own key over that exact request, so holding the credential alone opens nothing. The two headers, the freshness window, and what each refusal status means are in Conventions § Authentication.

What a theft actually gets you​

What leaksWhat the holder can do with it
The credentialRead metadata: which app, which host, which actions, when it expires. Not one API call — every call needs a signature they cannot make.
A single proofReplay one request that has already happened, briefly. It is bound to that method, host, path, and body, so it authorizes nothing else.
The signing keyEverything the credential covers. This is the artifact that matters, which is why it lives in your server's environment.

That leaves one thing to protect properly: the key. A browser cannot hold an Ed25519 key non-extractably, so the browser holds an ordinary session cookie and your server signs. Key custody covers where that key lives and how it reaches a deployed server.

Sign coordinates you wrote, not coordinates you were handed​

A backend that signs whatever {method, path, body} a page asks it to has built a confused deputy: an XSS on that page, or simply a hostile client, obtains proofs for arbitrary requests against every credential the backend holds. The key never leaked, and it did not need to.

Give each call its own route with the coordinates written into the file, and let the session decide only which credential to spend. Where a parameter is genuinely necessary — a space identifier for a membership check — confine it to a named slot in a request you wrote, with a tight charset and proper encoding, never a set of coordinates you accept whole. The normative version is in API security notes.

Next​