API reference

/v1/security-jwt-key-sets

8 operations · 8 support API keys

← All groups · First call? Read the tutorial: auth, permissions, requests and responses, common failures

MethodPathSummaryAuth
GET/v1/security-jwt-key-setsList JWT key setsAPI keySession
POST/v1/security-jwt-key-setsCreate a JWT key setAPI keySession
GET/v1/security-jwt-key-sets/{set_id}Get a JWT key setAPI keySession
PUT/v1/security-jwt-key-sets/{set_id}Replace a JWT key setAPI keySession
DELETE/v1/security-jwt-key-sets/{set_id}Delete a JWT key setAPI keySession
GET/v1/security-jwt-key-sets/{set_id}/referencesList the policies naming a JWT key setAPI keySession
POST/v1/security-jwt-key-sets/{set_id}/refreshFetch a JWT key set's JWKS nowAPI keySession
POST/v1/security-jwt-key-sets/{set_id}/test-tokenCheck a token against a JWT key setAPI keySession

Contract file:api/openapi/v1/control.yaml

Operation details

GET /v1/security-jwt-key-sets

List JWT key sets

operationId
listSecurityJWTKeySets
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.read. Tenant identities only. key_count counts the keys of an allowed algorithm (what the nodes get); reference_count the tenant's live policies naming the set.

Responses

listSecurityJWTKeySets Responses
StatusDescription
200Sets by name.

Fields:items: array<SecurityJWTKeySet>

401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
500The request could not be completed because of an internal failure.

What to do on failure

  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/security-jwt-key-sets

Create a JWT key set

operationId
createSecurityJWTKeySet
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.manage; tenant only. A remote set is fetched once (https, public addresses only, checked after DNS); a failed fetch still creates it with fetch_state failing and no keys, except a URL resolving to a non-public address (validation_error jwks_url blocked_address). A static set takes a JWK Set in jwks: public keys only (a private member refuses it: jwks contains_private_key), RSA 2048-8192 / EC P-256 / Ed25519, at least one of an allowed algorithm (jwks no_usable_key). Other field reasons: jwks_url not_https, jwks invalid_json / too_many_keys. At most 50 live sets per tenant (422 jwt_key_set_limit). Audit security.jwt_key_set.create.

Parameters

createSecurityJWTKeySet Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—

Request body

application/json · Required:Yes

createSecurityJWTKeySet Request body
NameTypeRequiredDescription
namestringYes—
descriptionstringNo—
sourcestring: remote / staticYesFixed at creation.
jwks_urlstring(uri)Noremote only; https, public address.
refresh_secondsintegerNoremote only.
jwksobjectNostatic only; a JWK Set ({keys: [...]}), public keys only, at most 256 KiB.
algorithmsarray<string: RS256 / ES256 / EdDSA>Yes—
token_sourcesarray<SecurityJWTTokenSource>YesThe node takes the first token found
issuerstringNoEmpty skips the iss check.
audiencesarray<string>NoEmpty skips the aud check.
require_expbooleanNo—
clock_skew_secondsintegerNo—
failure_statusinteger: 403 / 401NoWhat a blocking jwt_invalid rule answers: 403 the block page, 401 with WWW-Authenticate: Bearer.

Responses

createSecurityJWTKeySet Responses
StatusDescription
201Created, or an identical request replayed.

Fields:id: string(uuid) name: string description: string source: string: remote / static jwks_url?: string refresh_seconds?: integer algorithms: array<string> token_sources: array<SecurityJWTTokenSource> issuer?: string audiences: array<string> require_exp: boolean clock_skew_seconds: integer failure_status: integer: 403 / 401 keys: array<SecurityJWTKey> ignored_keys: array<object> key_count: integer keys_revision: integer fetch_state: string: none / ok / failing fetch_failures: integer fetch_error?: string: dns / blocked_address / tls / http_status / too_large / content_type / invalid_json / contains_private_key / no_usable_key / network fetched_at?: string(date-time) next_fetch_at?: string(date-time) refresh_available_at?: string(date-time) reference_count: integer revision: integer updated_at: string(date-time)

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
409The requested state conflicts with an existing resource or idempotency fact.
422The request is well formed but breaks a business rule (error.code names it).
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/security-jwt-key-sets/{set_id}

Get a JWT key set

operationId
getSecurityJWTKeySet
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.read. The set with its normalized public keys and the keys the last JWKS left out.

Parameters

getSecurityJWTKeySet Parameters
NameInTypeRequiredDescription
set_idpathstring(uuid)Yes—

Responses

getSecurityJWTKeySet Responses
StatusDescription
200The set.

Fields:id: string(uuid) name: string description: string source: string: remote / static jwks_url?: string refresh_seconds?: integer algorithms: array<string> token_sources: array<SecurityJWTTokenSource> issuer?: string audiences: array<string> require_exp: boolean clock_skew_seconds: integer failure_status: integer: 403 / 401 keys: array<SecurityJWTKey> ignored_keys: array<object> key_count: integer keys_revision: integer fetch_state: string: none / ok / failing fetch_failures: integer fetch_error?: string: dns / blocked_address / tls / http_status / too_large / content_type / invalid_json / contains_private_key / no_usable_key / network fetched_at?: string(date-time) next_fetch_at?: string(date-time) refresh_available_at?: string(date-time) reference_count: integer revision: integer updated_at: string(date-time)

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

PUT /v1/security-jwt-key-sets/{set_id}

Replace a JWT key set

operationId
updateSecurityJWTKeySet
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.manage and the current revision. source cannot change. A static set sent without jwks keeps its keys. A remote set whose jwks_url changes is fetched first and refused when that fetch fails (validation_error jwks_url fetch_<category>, or blocked_address). Algorithms leaving no key are refused (algorithms no_usable_key). Every tenant whose bound WAF policy names the set is republished (system trigger jwt_key_set). Audit security.jwt_key_set.update.

Parameters

updateSecurityJWTKeySet Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—
set_idpathstring(uuid)Yes—

Request body

application/json · Required:Yes

updateSecurityJWTKeySet Request body
NameTypeRequiredDescription
namestringYes—
descriptionstringNo—
sourcestring: remote / staticYesFixed at creation.
jwks_urlstring(uri)Noremote only; https, public address.
refresh_secondsintegerNoremote only.
jwksobjectNostatic only; a JWK Set ({keys: [...]}), public keys only, at most 256 KiB.
algorithmsarray<string: RS256 / ES256 / EdDSA>Yes—
token_sourcesarray<SecurityJWTTokenSource>YesThe node takes the first token found
issuerstringNoEmpty skips the iss check.
audiencesarray<string>NoEmpty skips the aud check.
require_expbooleanNo—
clock_skew_secondsintegerNo—
failure_statusinteger: 403 / 401NoWhat a blocking jwt_invalid rule answers: 403 the block page, 401 with WWW-Authenticate: Bearer.
expected_revisionintegerYes—

Responses

updateSecurityJWTKeySet Responses
StatusDescription
200Replaced (revision + 1), or an identical request replayed.

Fields:id: string(uuid) name: string description: string source: string: remote / static jwks_url?: string refresh_seconds?: integer algorithms: array<string> token_sources: array<SecurityJWTTokenSource> issuer?: string audiences: array<string> require_exp: boolean clock_skew_seconds: integer failure_status: integer: 403 / 401 keys: array<SecurityJWTKey> ignored_keys: array<object> key_count: integer keys_revision: integer fetch_state: string: none / ok / failing fetch_failures: integer fetch_error?: string: dns / blocked_address / tls / http_status / too_large / content_type / invalid_json / contains_private_key / no_usable_key / network fetched_at?: string(date-time) next_fetch_at?: string(date-time) refresh_available_at?: string(date-time) reference_count: integer revision: integer updated_at: string(date-time)

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

DELETE /v1/security-jwt-key-sets/{set_id}

Delete a JWT key set

operationId
deleteSecurityJWTKeySet
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.manage and the current revision. A set any live policy version names is refused (409 jwt_key_set_in_use). Audit security.jwt_key_set.delete.

Parameters

deleteSecurityJWTKeySet Parameters
NameInTypeRequiredDescription
Idempotency-KeyheaderstringYes—
set_idpathstring(uuid)Yes—
expected_revisionqueryintegerYes—

Responses

deleteSecurityJWTKeySet Responses
StatusDescription
204Deleted.
400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

GET /v1/security-jwt-key-sets/{set_id}/references

List the policies naming a JWT key set

operationId
listSecurityJWTKeySetReferences
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.read. The tenant's live policies with a version naming the set; rule_count is from the latest such version.

Parameters

listSecurityJWTKeySetReferences Parameters
NameInTypeRequiredDescription
set_idpathstring(uuid)Yes—

Responses

listSecurityJWTKeySetReferences Responses
StatusDescription
200Policies by name.

Fields:items: array<SecurityStringSetReference>

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/security-jwt-key-sets/{set_id}/refresh

Fetch a JWT key set's JWKS now

operationId
refreshSecurityJWTKeySet
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.manage. Remote sets only (409 jwt_key_set_not_remote); once a minute per set (429 refresh_too_frequent, refresh_available_at says when). A failed fetch keeps the last good keys and is returned in fetch_state / fetch_error, not as an error. New keys republish the tenants naming the set. Audit security.jwt_key_set.refresh.

Parameters

refreshSecurityJWTKeySet Parameters
NameInTypeRequiredDescription
set_idpathstring(uuid)Yes—

Responses

refreshSecurityJWTKeySet Responses
StatusDescription
200The set after the fetch.

Fields:id: string(uuid) name: string description: string source: string: remote / static jwks_url?: string refresh_seconds?: integer algorithms: array<string> token_sources: array<SecurityJWTTokenSource> issuer?: string audiences: array<string> require_exp: boolean clock_skew_seconds: integer failure_status: integer: 403 / 401 keys: array<SecurityJWTKey> ignored_keys: array<object> key_count: integer keys_revision: integer fetch_state: string: none / ok / failing fetch_failures: integer fetch_error?: string: dns / blocked_address / tls / http_status / too_large / content_type / invalid_json / contains_private_key / no_usable_key / network fetched_at?: string(date-time) next_fetch_at?: string(date-time) refresh_available_at?: string(date-time) reference_count: integer revision: integer updated_at: string(date-time)

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
409The requested state conflicts with an existing resource or idempotency fact.
429refresh_too_frequent.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 409 Read the current state first; a retry of the same operation keeps the original Idempotency-Key and body.
  • 429 Rate limited: wait, then retry with lower concurrency.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list

POST /v1/security-jwt-key-sets/{set_id}/test-token

Check a token against a JWT key set

operationId
testSecurityJWTToken
Auth
  • API key: header Authorization: CdncaKey <key_id>.<secret>. Effective permissions are the key scopes intersected with the owner’s current permissions.
  • Session: the Bearer session of a signed-in control plane user, used by the customer in their own control plane; a plugin must never ask for it.
Required permissions

The contract has no separate permission annotation; see the description below and the 403 response.

Description (from the contract)

Requires security_policies.read. Verifies the token as the nodes would (same algorithms, keys, issuer, audiences, exp / nbf and skew). The token is not stored, audited or logged.

Parameters

testSecurityJWTToken Parameters
NameInTypeRequiredDescription
set_idpathstring(uuid)Yes—

Request body

application/json · Required:Yes

testSecurityJWTToken Request body
NameTypeRequiredDescription
tokenstringYes—

Responses

testSecurityJWTToken Responses
StatusDescription
200The result.

Fields:valid: boolean reason?: string: missing / malformed / alg_not_allowed / key_not_found / bad_signature / expired / exp_required / not_yet_valid / issuer_mismatch / audience_mismatch header?: object claims?: object

400The request body or parameters are invalid.
401Authentication failed or the session is invalid.
403The authenticated principal is not allowed to perform the action.
404The requested resource was not found.
500The request could not be completed because of an internal failure.

What to do on failure

  • 400 Fix the parameters or body per the field list; do not retry unchanged.
  • 401 Check the credential format and whether it expired or was rotated.
  • 403 Check the key scopes, the owner’s current permissions and the tenant scope; never switch to a more privileged account.
  • 404 The resource does not exist or belongs to another tenant.
  • 500 Outcome unknown: read back by ID or list first, then decide whether to retry with the original Idempotency-Key.

↑ Back to list