Skip to content

Rotate signing keys

POST
/api/v1/admin/settings/keys/rotate
Code sample: Shell / cURL
curl --request POST \
--url http://localhost:9090/api/v1/admin/settings/keys/rotate \
--header 'Authorization: Bearer <token>'

Generate a new signing key. Old key remains for validation.

Keys rotated

Media typeapplication/json
object
success
required
boolean

Example generated

{
"success": true
}

Missing or invalid bearer token

Media typeapplication/json

Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.

object
error_code

Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for catalog-keyed localized codes (e.g. validator.email.required).

string
error_description
required

A sentence for people to read: in the request’s language when error_code is a catalog key, in English otherwise. Route on error_code, not on this text.

string

Example generated

{
"error_code": "example",
"error_description": "example"
}
WWW-Authenticate
string

Bearer challenge on token refusals. An operation may also return a handler-level 401 without this header.

The token is valid but does not authorise this request. Four checks answer here, and a caller distinguishes them by error_code.

INSUFFICIENT_SCOPE comes from the route’s authorisation middleware, before the handler runs: an Admin operation needs one of the scopes its route names, and an Account operation needs authserver:manage-account.

USER_CONTEXT_REQUIRED comes from the same middleware on the Account operations, which also require the token to have been issued for a user: one obtained through the client credentials grant carries no auth_time claim and is refused here.

FORBIDDEN comes from the handler, on the account endpoints that resolve a resource by id and then check it belongs to the caller, so a valid token for the wrong user reaches this rather than a 404.

MANAGE_SCOPE_REQUIRED comes from the handler, on the Admin operations the administrative policy guards. Only authserver:manage creates an administrator, changes one, or changes what reaches one, so no granular scope will ever be enough: the remedy is a token holding authserver:manage, not requesting the route’s scope as for INSUFFICIENT_SCOPE. An administrator is a user, group or client holding any of the six administrative permissions (manage, admin-read, manage-users, manage-clients, manage-settings, browser-sessions), a user directly or through any of its groups, the admin console’s own client whatever it holds, and a client allowed to request the administrative scopes. A granular scope is refused here when it:

  • grants or revokes an administrative permission, directly or by moving a user into or out of a group that holds one, or deletes such a group;
  • writes to an administrator user (profile, credentials, enabled, sessions, consents, attributes, memberships, permissions, deletion), an administrative group (settings, attributes, members, permissions, deletion), or an administrator client (settings, authentication, flows, redirect URIs, web origins, token settings, permissions, logo, deletion);
  • switches whether a client may request the administrative scopes, on or off, on any client;
  • reads an administrator client’s secret;
  • changes the email or the audit-log settings;
  • changes an administrative permission’s description. Granular scopes still read administrators. The refusal is answered after the request’s 400 and 404, writes nothing, carries WWW-Authenticate: Bearer realm="goiabada", error="insufficient_scope", error_description="...", scope="authserver:manage", and leaves an administrator_change_refused audit record.

Every operation this document secures declares a 403. The public client logo endpoint, which carries security: [] and authorises nothing, is the one that does not.

Media typeapplication/json

Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.

object
error_code

Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for catalog-keyed localized codes (e.g. validator.email.required).

string
error_description
required

A sentence for people to read: in the request’s language when error_code is a catalog key, in English otherwise. Route on error_code, not on this text.

string

Example generated

{
"error_code": "example",
"error_description": "example"
}
WWW-Authenticate
string

Bearer challenge on scope and administrative-policy refusals; other forbidden responses omit it.

Another rotation won the race and this call rotated nothing. error_code is ROTATION_IN_PROGRESS. Do not retry: the rotation it conflicted with already happened.

Media typeapplication/json

Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.

object
error_code

Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for catalog-keyed localized codes (e.g. validator.email.required).

string
error_description
required

A sentence for people to read: in the request’s language when error_code is a catalog key, in English otherwise. Route on error_code, not on this text.

string

Example generated

{
"error_code": "example",
"error_description": "example"
}

Error_code is KEY_SET_INCOMPLETE when the deployment has no current or no next key, which is an operator problem rather than a transient one and a retry will not clear it, or INTERNAL_SERVER_ERROR for a storage or key generation failure. Either way the description ends with the request id of the log line, and nothing was rotated: the whole transition is one transaction.

Media typeapplication/json

Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.

object
error_code

Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for catalog-keyed localized codes (e.g. validator.email.required).

string
error_description
required

A sentence for people to read: in the request’s language when error_code is a catalog key, in English otherwise. Route on error_code, not on this text.

string

Example generated

{
"error_code": "example",
"error_description": "example"
}