Key Destruction
Applies to: the Key Management SDK, the Key Management CLI and the Admin Console
Version: 3.4.0
A key, or one version of it, is destroyed in three steps that no single principal can complete alone:
- Request. A workload (through the Key Management SDK or CLI) or a person (in the Admin Console) requests the destruction. The request opens a quorum request; nothing about the key changes yet.
- Approval. A person other than the requester approves the request in the Admin Console, after authenticating again. The approval schedules the destruction.
- Execution. When the cooling-off period ends, the platform destroys exactly the approved material on its own. No caller runs the destruction.
1. Requesting a destruction
| What | Operation | Scope | Precondition |
|---|---|---|---|
| A whole key | POST /api/v3/admin/tenants/{tenantId}/keys/{kid}/mark-for-destruction | admin.keys.mark-for-destruction | The key is ARCHIVED |
| One version | POST /api/v3/admin/tenants/{tenantId}/keys/{stableKid}/materials/{version}/mark-for-destruction | admin.tenant.keys.materials.mark-for-destruction | The version is RETIRED, REVOKED or PENDING_PRIMARY |
| Tool | Key | Version |
|---|---|---|
| Key Management SDK | sdk.destruction().requestKey(kid, request) | sdk.destruction().requestVersion(stableKid, version, request) |
| Key Management CLI | ankasecure-km destruction request-key --kid <kid> | ankasecure-km destruction request-version --kid <kid> --material-version <n> |
Both answer 202 Accepted with the quorum request and its Location, whether or not the tenant has a quorum approval policy: with no policy one approval is needed, and an enabled policy can require more. The SDK returns a QuorumRequestReceipt; the CLI prints the pending JSON and exits 0.
A version whose destruction would leave the key with no version outside a destruction is the destruction of the key: it is requested as the key's request, which needs admin.keys.mark-for-destruction and an ARCHIVED key.
The request is refused under a support-access impersonation session (403).
1.1 The cooling-off period
The request may name coolingOffDays, from 7 to 365. When it does not, the value comes from the first of:
- the tenant lifecycle policy's
destruction.coolingOffDefaultDays; - the deployment lifecycle policy's
destruction.coolingOffDefaultDays; - the platform default, 30 days.
The period is counted from the approval, not from the request.
2. Approval
Approval and rejection are made in the Admin Console, by a person other than the requester, after the approver authenticates again. A break-glass session never decides a request. The Key Management SDK and CLI have no approve or reject operation; they read their own requests and withdraw them.
The request is approved for the key's versions as they stood when it was made. If a version is restored, added or destroyed before the approval, the request ends FAILED (quorum-target-changed) and a new request is needed.
On approval:
- every version the destruction covers becomes PENDING_DESTRUCTION, and the key reads PENDING_DESTRUCTION;
- a destruction order is scheduled for the approval instant plus the cooling-off period (
eligibleFrom).
A key's destruction absorbs the orders its versions already wait in: those orders end CANCELLED with supersededBy naming the key's order. Absorbing never brings a version's destruction forward. The key's order runs at the later of its own eligibleFrom and the eligibleFrom of every order it absorbed.
While the destruction waits, no new encryption or signature uses the key, and decryption and verification of historical data remain available where the tenant's lifecycle policy allows them.
3. Execution
The platform's destruction executor looks for due orders every KEY_DESTRUCTION_EXECUTOR_POLL_INTERVAL (default PT5M, from PT1M to PT1H) and once at every start of the service. For a due order it destroys exactly the versions the approval covered:
- the private material is erased from the platform's active storage;
- the versions become DESTROYED, and for a key-level order the key becomes DELETED_LOGICAL, its terminal state;
- the key's metadata, public key and audit trail are kept;
- the order ends EXECUTED.
When the versions are no longer the approved ones, or cannot be erased, nothing is destroyed: the order ends FAILED with a reason, and it is never retried. Cancel the destruction and request it again.
Backups are not altered
Destruction erases the material from the platform's active storage. Backups taken earlier are not altered, and restoring one restores the key as it was when the backup was taken. Retire backups according to your own retention policy.
3.1 A Key ID is never reused
A destroyed key's Key ID stays its own forever within the tenant. Creating or importing a key with a Key ID that any key of the tenant has ever held, destroyed keys included, is refused with 409 key-id-retired.
4. Cancelling
| When | How |
|---|---|
| Before the approval | Withdraw the quorum request: sdk.quorumRequests().cancel(requestId) / ankasecure-km quorum-requests cancel, or in the Admin Console |
| After the approval, before execution | Cancel the destruction: cancel-destruction on the key or the version (admin.keys.cancel-destruction / admin.tenant.keys.materials.cancel-destruction) |
| After execution | Not possible |
Cancelling restores every version of the cancelled order to the status it had before the approval, and a key reads ARCHIVED again. A later destruction needs a new request and a new approval.
| Refusal | When |
|---|---|
409 invalid-key-state | Cancelling a key that is not PENDING_DESTRUCTION |
422 material-status-invalid-transition | Cancelling a version that is not PENDING_DESTRUCTION |
Cancelling a version whose destruction was scheduled with the whole key cancels the key's order as a whole.
5. Destruction orders
GET /api/v3/admin/tenants/{tenantId}/keys/{kid}/destruction-orders (scope admin.keys.read; sdk.destruction().orders(kid), ankasecure-km destruction orders --kid <kid>) lists, newest first, what each approval scheduled:
| Member | Meaning |
|---|---|
scope | KEY (every version the key had left) or MATERIAL (one version of a key that keeps another) |
status | SCHEDULED, EXECUTED, CANCELLED or FAILED |
versions | The versions the order destroys |
coolingOffDays, coolingOffSource | The period and where it came from: REQUEST, TENANT_POLICY, DEPLOYMENT_POLICY or DEFAULT |
quorumRequestId, approvedAt, eligibleFrom | The approval and when the destruction runs |
executedAt, cancelledAt, failedAt, failureReason | How it ended |
supersededBy | On a cancelled version order, the key's order that absorbed it |
A destruction request still waiting for approval is not an order yet; read it through the quorum request. A destroyed key keeps its orders.
6. Alerts
| Condition | Severity | Fires when |
|---|---|---|
key.destruction.failed | CRITICAL | A destruction order ended FAILED since the previous evaluation |
key.destruction.overdue | WARNING | A SCHEDULED order is still waiting more than twice the poll interval plus 30 minutes after its eligibleFrom |
Both are platform alert conditions, routed to the platform's alert destinations.
Version: 3.4.0
Last updated: 2026-10-26