10.6 Secrets handling (write-only config fields)
Some config values are secrets — the JWT signing key, API credentials for custom services. RS2 treats designated fields as write-only: you can set and rotate them, but you can't read them back. This makes the normal config edit loop safe by default.
What's a secret
auth.jwtSecret— the token signing key.- Everything under a top-level
secretsblock in the tenant config.
Write-only behavior
| Operation | Behavior |
|---|---|
GET /services/raw |
Secret fields read back as the literal marker "<secret>" — the real value is never returned |
PUT /services/raw with "<secret>" left in place |
The marker is replaced with the stored value — the secret is preserved |
PUT /services/raw with a real value |
Rotates the secret to that value |
PUT with a "<secret>" marker that has no stored counterpart |
400 — you can't mark a field secret without supplying a value |
Why this matters
The everyday edit loop is read → modify → write (10.4). Because secrets read
back as markers and markers are re-expanded to stored values on write, that loop
never destroys a secret — you can edit any other part of the config and PUT
it back without having to know, or re-enter, the JWT key. It's safe to hand a
GET /services/raw payload to a tool or a person without leaking credentials.
Rotating a secret
To change a secret, replace its marker with the new real value and PUT:
// GET returns:
"auth": { "jwtSecret": "<secret>", … }
// To rotate, PUT with:
"auth": { "jwtSecret": "a-new-strong-key", … }
Rotating auth.jwtSecret invalidates existing tokens (they were signed with the
old key), so users re-authenticate — plan rotations accordingly.
Operator hygiene
- Seed
auth.jwtSecretout of band — the runtime and the migrator (Part 11) won't invent one for you; a tenant with auth needs a strong key set before it's useful. - Keep secrets in the
secretsblock for custom-service credentials, and grant only the named secrets a mount needs. Prefer host-side credential injection, so a secret never enters a sandbox or an outbound request spec. - Keep operator-owned credentials in
infras.json, not tenant config. A tenant can reference aninfra:and discover its provided field names, but never read the values (10.7). - Don't put secrets in logs or client-visible responses — and note RS2 won't
surface them through
GET /services/raw, which is the most likely accidental leak path.
The final operator section covers those infras, bootstrap, and production boundaries. Part 11 then brings an existing v1 Restspace configuration across.
← Previous: 10.5 Deploying & rotating code · Manual home · Next: 10.7 Infras, bootstrap, production →