Skip to content

Forbidden

URI: https://docs.ankatech.co/errors/forbidden
HTTP Status: 403 Forbidden

When you see this

You are authenticated but do not have permission to perform the requested operation or access the specified resource.

Common Causes

  • Your credentials (API key, token, or session) are valid but lack the required role or scope.
  • You attempted an operation not allowed by key lifecycle policy (e.g. trying to sign with an expired key).
  • You tried to access another user's or tenant's resource without proper authorization.
  • You invoked an endpoint restricted to admins or specific service accounts.

Response Example

{
  "type": "https://docs.ankatech.co/errors/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "Access is denied.",
  "instance": "/api/v3/admin/tenants/2f1c9d84-6b2e-4d3a-9f57-0a1b2c3d4e5f/keys",
  "timestamp": 1751500800,
  "extensions": {
    "requestId": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. The example above is an Admin API body, where the correlation identity is extensions.requestId; the Core API and the PQC Handshake API instead emit a top-level correlationId. Read the member your service emits — see Error Index & Overview.

403 is deliberately NOT relayed across an internal service boundary. When an internal upstream refuses the platform's own service-to-service credential, the caller reports Upstream Service Unavailable (502) instead — a platform-side condition must never reach you as if it were a decision about your authorization. See S2S Relay Envelope.

PKCS#7 conversion: which signer or recipient was refused

A PKCS#7 conversion (POST /api/v3/migration/convert-pkcs7-to-jose and its streaming twin) gates every actor's leg — sign for each signer, decrypt for the decrypting recipient, encrypt for every recipient — first by a Capability Grant decision, then by the tenant's key-lifecycle policy. The grant decisions are the re-operations': REENCRYPT from the recipient that opens the content to every recipient (its own pair included) and RESIGN from every signer's key to itself; DECRYPT, ENCRYPT and SIGN grants admit no conversion. A REENCRYPT or RESIGN grant is requested with exactly two assetKids, so a file with N recipients needs N-1 pair grants [opening recipient, recipient], a single-recipient file the in-place grant requested with the kid twice (assetKids: [kid, kid], stored as [kid]), and each signer RESIGN [signer, signer]; there is no wildcard REENCRYPT or RESIGN grant. When either check refuses a leg, the 403 names that actor in extensions.actor:

{
  "type": "https://docs.ankatech.co/errors/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "Operation denied by Capability Grant resolver: not permitted for this key",
  "instance": "/api/v3/migration/convert-pkcs7-to-jose",
  "correlationId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "timestamp": 1768472400,
  "extensions": {
    "actor": { "index": 2, "role": "recipient", "leg": "encrypt" }
  }
}

index is the actor's zero-based position in its own set (SignerInfos or RecipientInfos), role is signer or recipient, and leg is sign, decrypt or encrypt. The detail is the gate's generic refusal and no kid is named. Every actor has resolved to a key by then, and nothing has been decrypted or signed.

Three conversion refusals carry no extensions.actor, because they are decided before any key is looked up: a token that carries no Cryptographic Actor, a calling Actor that holds no REENCRYPT / RESIGN grant for what the file needs, and a named decryptionKid whose own REENCRYPT pair is not granted (answered the same whether or not that key exists). A suspended tenant, Application or Actor is refused before any of them, with no grant charged.

How to Resolve

For Permission Issues:

  1. Verify you are using the correct API credentials and that they have the necessary roles/scopes.
  2. Check the resource's ownership or tenancy—ensure your token is scoped to that project or key.
  3. Review the API's authorization requirements in the documentation.
  4. If you believe you should have access, contact your administrator to request the necessary permissions.

If you continue to receive a 403 error after these steps, please consult the full Developer Hub Reference.