Update the signing key policy

PATCH /v1/signing-keys/policy · permission signing-keys:write

Updates the signing key policy with a JSON merge patch (application/merge-patch+json, RFC 7396). If-Match is required: missing gives 428, a stale version gives 412. If the policy was never written the version is "0". A patch that changes nothing writes nothing and keeps the version.

Changing algorithm generates a new next key with the new algorithm right away; it can become active at the earliest 7 days later, so verifiers that cache the JWKS see it first (an earlier immediate rotation fails with 409 next_key_too_young). The active key keeps signing until then. Changing rotation_interval_days moves next_rotation_at. A successful change writes the signing_key.policy_updated management audit record.

Request

Field Type Required Description
If-Match header yes The ETag of the policy as last read ("0" if never written). Missing: 428; stale: 412.
algorithm string no RS256, ES256, PS256 or EdDSA. Cannot be null.
rotation_interval_days integer no 30-365. Cannot be null.
storage string no wrapped (the private key is stored encrypted under the environment key and used only inside the signing service). transit (key held in the key management service) is not available yet and is rejected with 422. Cannot be null.

Response

200 OK with the updated policy and the new ETag.

{
  "algorithm": "ES256",
  "rotation_interval_days": 90,
  "storage": "wrapped",
  "next_rotation_at": "2026-12-04T09:30:00.123456Z",
  "updated_at": "2026-10-05T09:30:00.123456Z"
}

Errors

HTTP code When
400 unknown_field The patch contains an unknown or read-only field, or is not a JSON object (malformed_request).
412 precondition_failed If-Match does not match the current version.
415 unsupported_media_type The content type is not application/merge-patch+json.
422 validation_failed A value is invalid (invalid_value), out of range (out_of_range), set to null (invalid), or storage is transit.
428 precondition_required The If-Match header is missing.
401 unauthenticated The credential is missing, invalid or revoked.
403 insufficient_permissions The credential lacks the required permission.
429 rate_limited The rate limit was exceeded; retry after the Retry-After period.
501 not_implemented The operation is not available in this deployment yet; retrying does not change the result.
503 service_unavailable A dependency is temporarily unavailable; retry after the Retry-After period.

Example

curl -X PATCH https://api.eu.keenauth.com/v1/signing-keys/policy \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "0"' \
  -d '{"algorithm":"ES256","rotation_interval_days":90}'