Decommissioning
Retiring a vault, or an installation that contains one. The order matters, and one step is irreversible by design.
Secret disposal
Warning
``vault:delete`` is a soft delete.
Secret
sets deleted = 1 and updates tstamp; the row — with its ciphertext,
its wrapped DEK and its nonces — stays in tx_nrvault_secret. The same
is true of vault:cleanup-orphans, which routes through the same
Vault.
There is no hard-delete path in the extension. Do not read "deleted" as "gone".
That is the right default for a live system: it keeps the operation auditable and reversible, and the row is unreadable to anyone without the master key anyway. It is the wrong assumption when decommissioning. For actual disposal you have two options, and they compose:
Crypto-erasure (recommended). Destroy the master key and every secret in the vault becomes permanently unreadable in one step — including soft-deleted rows, including rows in every backup already taken. This is the only measure that reaches copies you no longer control. See Key destruction.
Row removal (for completeness). Drop or truncate the tables at the database level once the audit-retention obligations below are satisfied:
-- Secrets, including soft-deleted rows, and their two ACL relation
-- tables. Dropping only the secret table leaves the MM rows behind.
DROP TABLE tx_nrvault_secret;
DROP TABLE tx_nrvault_secret_begroups_mm;
DROP TABLE tx_nrvault_secret_writegroups_mm;
-- Audit chain. Check your retention obligations FIRST.
DROP TABLE tx_nrvault_audit_log;
-- Vault state also lives in the core registry: the chain tip anchor,
-- and the break-glass session plus per-sink delivery state.
DELETE FROM sys_registry WHERE entry_namespace = 'tx_nrvault_audit_anchor';
DELETE FROM sys_registry WHERE entry_namespace = 'tx_nrvault';
Note
Row removal on its own is weaker than it looks: database backups, replicas, binlogs, filesystem snapshots and storage-level copies keep the ciphertext for as long as their own retention allows. Crypto-erasure is what makes those copies worthless. Do both if the policy demands it; do crypto-erasure if you can only do one.
Rotate credentials out, do not just delete them
A secret in the vault is a copy of a credential that also exists in the system it authenticates against. Deleting the vault copy does not revoke anything.
Before disposal, for every secret still in use: rotate the credential at its origin — the API provider, the SMTP relay, the OAuth client, the deploy key — so that the value the vault held stops working. Then dispose of the vault copy. In that order: a rotation performed after the vault is gone has to be done without the ability to read what is being replaced.
Final evidence export
Do this before anything destructive. Once the master key is gone, the audit chain can no longer be verified — the HMAC key was derived from it — so a verification run after key destruction proves nothing.
-
Verify the chain while the key still exists, and keep the output:
vendor/bin/typo3 vault:audit-verify > decommission-verify.txtCopied! -
Publish a final anchor, so the tip is witnessed externally at the moment of decommissioning:
vendor/bin/typo3 vault:audit-anchorCopied! - Export the audit log in full, over the entire retained period, with
the hash columns included —
uid,previous_hash,entry_hash,hmac_key_epoch. Without them the export is a log, not evidence. - Collect the external evidence from where it actually lives: the anchor file, the syslog archive, the SIEM's retained records. This is the half the installation cannot fabricate, and after decommissioning it is the only half left.
- Record the decommissioning itself — date, operator, which artefacts
were exported, which tables were dropped, when and how the key was
destroyed. A
TABLE_RESETfinding against the final anchor is indistinguishable from a malicious reset without this record.
Evidence collection lists the artefacts in the form an assessor expects.
Retention obligations versus deletion
These pull in opposite directions and nr-vault cannot resolve the conflict for you — it can only make sure you notice it.
- The secrets are the deletion obligation. Credentials have no reason to outlive the system that used them, and a retained ciphertext is a retained risk for as long as any copy of the key might exist.
- The audit log is the retention obligation. It is the record of who accessed which credential and when — frequently the artefact an audit regime requires to be kept, and often for years. It contains no secret values.
They are separable, and separating them is the answer. Destroy the key and
drop tx_nrvault_secret; keep the exported audit evidence for as long as
policy requires. The exported chain remains internally verifiable — each row's
previous_hash still links to its predecessor — but note honestly what is
lost: without the master key, HMAC recomputation is no longer possible, so
from epoch 1 upwards the export becomes a sequence whose links can be
inspected rather than a chain whose authenticity can be re-proved. That is why
the verification output from step 1 above matters: it is the last point at
which authenticity was demonstrable, and it must be captured then, not later.
Note
tx_nrvault_audit_log also holds personal data — actor_username,
ip_address, user_agent. A deletion request under data-protection
law collides with the tamper-evident design: editing or removing a row
breaks the chain by construction, which is the entire point.
ADR-017: Audit metadata retention is where that trade-off is
recorded; resolve it as a policy decision before decommissioning, not
during.
Key destruction
Irreversible. There is no escrow and no vendor-side reset — see Master key loss is data loss.
| Provider | How to destroy the key |
|---|---|
typo3 | Rotate or remove SYS/encryptionKey in
config/, and destroy every backup of
that file. Harder than it sounds — the config directory is
usually in more backups than anyone expects, and encryptionKey
is also used by TYPO3 core for unrelated purposes, so removing it
has effects beyond the vault. |
file | Delete the key file and every copy, including the separate key backup. On a copy-on-write filesystem or a storage layer with snapshots, deletion is not erasure — destroy the snapshots too. |
env | Remove the variable from the injection mechanism and restart. Then check where it was also recorded: CI secret stores, deployment manifests, container inspection output, shell history. |
transit | The cleanest case. Delete the transit key in HashiCorp Vault
(or revoke every policy granting decrypt on it) and the
locally stored wrapped blob becomes undecryptable immediately —
including in every backup that contains it. Then delete the
wrapped file as well. |
- Confirm the evidence export is complete and stored elsewhere.
- Confirm no other installation shares the key material. A key file copied to a staging system is still a live key.
- Destroy the key.
- Verify destruction by attempting a read: a probe decrypt must now fail
with
Master key not found at: …orAuthentication failed - data may have been tampered with. A successful read means a copy survived somewhere — find it. - Drop the tables, if row removal is also required.
Installation cleanup
- Remove the sinks last, not first: they are what records the
decommissioning steps. Turn off
auditSinkWebhookEnabledand friends only after the final anchor has been published. - Unschedule the tasks — the audit anchor and audit verify scheduler tasks, and orphan cleanup — or they will start failing loudly against a vault that no longer exists.
- Revoke the grants. Remove the
tx_nrvault:*custom options frombe_groups, so a later reinstall does not silently inherit a permission model nobody reviewed. - Unpin the settings. Remove the
$GLOBALSentries from['TYPO3_ CONF_ VARS'] ['SYS'] ['nr Vault'] config/, and the extension configuration block itself fromsystem/ additional. php config/— the pins are only the part that lives insystem/ settings. php additional.php. - Remove the extension, and remember that removing it does not remove its tables.
- Clean up the KMS side if
transitwas used: revoke the token, remove the policy, delete the transit key.