Skip to content

VII.5VII · The programdefense

Retirement & decommissioning

Retiring an AI system is not deleting an endpoint - it is revoking an identity, destroying key material, proving a vector store actually forgot, and keeping exactly the evidence you are still legally obliged to keep and nothing more.

The six things that outlive the system

flowchart TB
  S["Retirement decision<br/>stop-use criteria met"] --> ID["1 · Identities and tokens<br/>NHIs, OAuth grants, keys"]
  ID --> W["2 · Weights, adapters,<br/>checkpoints, registry entries"]
  W --> V["3 · Vector stores<br/>and their entitlements"]
  V --> L["4 · Prompt and trace logs<br/>plus provider-side copies"]
  L --> D["5 · Duties to KEEP<br/>regulatory, contractual, legal hold"]
  D --> E["6 · Evidence of retirement"]
  classDef d fill:#0f1a18,stroke:#5bd1c5,color:#bdeee2;
  classDef l fill:#1a160f,stroke:#e4a23f,color:#f0d9ad;
  class S,ID,W,V,L,E d;
  class D l;

Duty-to-keep is amber because it inverts the exercise. Every other box asks “is it gone?”; this one asks “was I allowed to remove it?”, and getting that wrong is the more expensive error.

1. Identities and tokens go first

An agent’s reach is its credential, not its host (IV.6 · Agent identity & access (NHI)). Retiring the workload while leaving the identity live produces the orphaned NHI that VII.4 · Finding the AI you do not know about rediscovers in six months as somebody else’s shadow AI.

Sourced: a stateless JWT stays valid until its exp regardless of what you revoke, so revocation is only real if the resource server introspects (RFC 7662, OAuth 2.0 Token Introspection) or the workload identity is disabled at source. The revocation endpoint and its token_type_hint parameter are RFC 7009, OAuth 2.0 Token Revocation - a different RFC from introspection, and the sentence below uses both.

Identity teardown - revoke, then disable re-issue, then remove the grant
# 1) Revoke live tokens (RFC 7009), and disable the workload identity so new ones
# cannot be minted.
curl -s -X POST https://<idp>/oauth2/revoke -d token=<access_token> -d token_type_hint=access_token
az ad sp update --id <agent-app-id> --set accountEnabled=false # Entra
aws iam delete-role-policy --role-name agent-<id> --policy-name standing-access
# 2) Remove the OAuth consents. These survive network-level teardown completely.
# Graph: DELETE /oauth2PermissionGrants/{id}
# DELETE /servicePrincipals/{id}/appRoleAssignments/{id}
gh api -X DELETE /orgs/<org>/installations/<installation_id> # GitHub App uninstall
# 3) Kill the standing secrets, not just the sessions.
aws secretsmanager delete-secret --secret-id agent/<id>/provider-key \
--force-delete-without-recovery
# 4) Prove it: the identity should appear in NO successful authorization after cutover.
# Leave the DENY in place and monitor for 30 days - callers you did not know about
# surface here, and each is an undocumented dependency, not a bug in the teardown.

2. Weights, adapters and checkpoints

Sourced: NIST SP 800-88 Revision 2, “Guidelines for Media Sanitization” (September 2025) is the current reference and treats cryptographic erase as a first-class technique, with its assurance conditional on the key management around it.

Reasoned: for model artifacts, crypto-erase is usually the only practical option, because the artifact is replicated across a registry, an object store, a cache on every serving node, and an unknown number of snapshots. You cannot chase every copy. You can destroy one key. That is the payoff of the encrypted-weights pattern in I.6 · Protecting weights in use.

Crypto-shred the artifact, then check what would have blocked you
# Destroy the wrapping key. Every ciphertext copy of the weights dies with it.
aws kms schedule-key-deletion --key-id <weights-wrap-key> --pending-window-in-days 7
# Azure: az keyvault key delete + purge (purge protection may impose a delay).
# BEFORE you promise "deleted", check the two things that silently prevent it:
aws s3api get-object-lock-configuration --bucket <weights-bucket> # WORM retention?
aws s3api list-object-versions --bucket <weights-bucket> --prefix <model>/ \
--query 'Versions[].{k:Key,v:VersionId}' # old versions persist

Sourced, and load-bearing: under S3 Object Lock compliance mode an object version “can’t be overwritten or deleted by any user, including the root user in your AWS account,” retention cannot be shortened, and “the only way to delete an object under the compliance mode before its retention date expires is to delete the associated AWS account.” If someone applied a compliance-mode lock to a bucket holding training data or checkpoints, a deletion commitment to a regulator is one you cannot keep. Check before you make it.

Reasoned: deregister the model as a governed retirement, not a silent delete, so VII.4 does not rediscover it. And keep the deny policy in place after retirement - a policy deny on the retired version is what stops an old client resurrecting the endpoint.

3. Vector stores and their entitlements

Sourced: Qdrant “implements deletions as soft deletes using a bitmask, so the index is not rebuilt after each deletion”; “the point is immediately inaccessible via the API”; and “The Vacuum Optimizer handles physical cleanup in the background,” at segment level, once a configurable threshold is passed - the documentation’s example configuration uses deleted_threshold: 0.2, i.e. 20% deleted. Not verified as the system default; read your own config reference. Milvus is described as the same shape (logical delete, physical removal at compaction) but this book did not confirm it against milvus.io in this pass - treat it as unverified.

Sourced, and this is why it matters legally: Singapore’s PDPC, in the Advisory Guidelines on Key Concepts in the PDPA (revised 27 July 2017), Chapter 18, sets out what the Commission considers under the section 25 Retention Limitation Obligation - including “How much effort and resources the organisation would need to expend in order to use or access the personal data again,” and whether the organization “has made a reasonable attempt to destroy, dispose of or delete the personal data in a permanent and complete manner.” Paragraph 18.12 gives the tombstone argument directly, citing deleted personal data in an un-emptied recycling bin as data still retained. “Marked deleted, still on disk, recoverable by an operator, physically removed whenever the optimizer next runs” is a weak answer to that test. Note these are the 2017 revision, pre-dating the 2020 PDPA amendments - say so in a client deliverable.

Retire a vector store and prove it forgot
# 1) Delete by the tenant/ACL metadata you stamped at ingest (V.3), not by vector id.
curl -s -X POST http://<vdb-host>:6333/collections/<collection>/points/delete \
-H 'content-type: application/json' \
-d '{"filter":{"must":[{"key":"tenant","match":{"value":"<retired-system>"}}]}}'
# 2) Force physical reclamation rather than waiting for the vacuum threshold. Prefer
# dropping the whole collection when the system is retired outright:
curl -s -X DELETE http://<vdb-host>:6333/collections/<collection>
# 3) PROVE it. Re-run a query that previously retrieved the data and assert an empty set,
# then confirm the retrieval-side canaries you seeded (VII.3) no longer surface.
# An empty filter must fail closed - never fall back to an unscoped search.
# 4) Retire the ENTITLEMENTS too. The group or role that granted retrieval access is a
# live grant on whatever replaces this store.

Reasoned: treat the embeddings as source data, because they are partially reversible (V.3). “We deleted the documents but kept the index for reuse” is not a deletion.

4. Prompt and trace logs are a retention problem

Sourced - copies you do not control. Anthropic’s API and data retention documentation states that even under a Zero Data Retention arrangement, data may be retained where required by law or where content is flagged by automated trust and safety systems, with flagged inputs and outputs retained for up to 2 years. Stateful features are carved out explicitly: the Files API is “retained until explicitly deleted,” code-execution container data up to 30 days, batch processing has a 29-day retention, and Managed Agents “transcripts persist until you delete them.” Decommissioning has to delete those objects by API, because ending the contract does not.

Sourced - litigation freezes deletion. In The New York Times Company v. Microsoft Corporation et al. (S.D.N.Y., 1:2023cv11195), the docket records that “OpenAI is NOW DIRECTED to preserve and segregate all output log data that would otherwise be deleted on a going forward basis until further order of the Court.” In July 2026 the publisher plaintiffs moved for sanctions alleging deletion continued regardless - an allegation, not a finding. Whatever the outcome, the governance lesson is settled: a deletion policy is an intention, and a preservation obligation outranks it.

5. What you are obliged to keep

ObligationWhat it requiresBasis
EU AI Act Art 18Technical documentation, QMS docs, notified-body decisions and the EU declaration of conformity, kept 10 yearsSourced
EU AI Act Art 19Automatically generated logs, “at least six months, unless provided otherwise”; financial-institution carve-out; applies 2 Aug 2026Sourced
GDPR Art 17(3)Erasure yields to legal obligations and to legal claimsSourced
PDPA s.25 (Singapore)Cease retention or anonymize once the purpose is servedSourced
NIST AI RMF GV-1.7Decommissioning must address retention, future investigations, dependencies, migrationSourced
Customer contracts and DPAsOften impose retention floors and deletion-certificate dutiesReasoned; read the paper

Reasoned: split the estate at retirement into three buckets, not two - destroy now, retain under a defined schedule with access revoked, and preserve under hold. A single “delete everything” instruction gets one of the three wrong every time.

6. The evidence to keep

Reasoned, in full. No standard specifies a decommissioning record for AI systems, so this is the minimum this book would defend in an audit: a dated retirement certificate naming the system and its owner; the stop-use criteria met; the inventory row as it stood at retirement; a per-item disposition (destroyed, retained until date X, preserved under hold Y) with the method and, for crypto-erase, the key identifier and destruction timestamp; the verification evidence (the empty query result, the failed authorization attempt, the storage-reclamation confirmation); the approvals; and the retained audit logs themselves, moved out of the retired system’s own control.

That last point matters most in an investigation: keep the tamper-evident action ledger, and make sure the retired system’s identity cannot write to it (VII.3). A decommissioning that destroys its own audit trail is indistinguishable from a cover-up.