What this is about
A final document stays as long as the law requires, and no longer. This period is called retention. While it runs, nobody can erase the document. Afterwards CRMS erases it on its own.
A legal hold keeps a document in addition, for example because a lawsuit is running. As long as it applies, nothing is erased, not even after the retention has ended.
The retention period
- It is set in
CODAMAI_CRMS_DOCUMENT_RETENTIONas an ISO 8601 period, for exampleP10Yfor ten years, orP6Y6M. - There is no default. As long as document revisions are on, CRMS does not start without it. How long records are kept is a legal obligation of the operator (GoBD, HGB, GMP …). A guessed value erases too early or keeps personal data too long.
- When storing, CRMS computes
retainUntil= time of storing (UTC) + period and writes the result into the revision. It locks the object in the storage with the same date.
The life of a revision
stateDiagram-v2 [*] --> Kept: FINAL stored Kept --> Held: legal hold set Held --> Kept: legal hold released Kept --> Erasable: retainUntil reached Held --> Held: retainUntil reached Erasable --> Held: legal hold set Erasable --> Tombstone: erased Tombstone --> [*]
The legal hold
- It applies to the whole chain: all revisions that still have bytes, and also every revision that is stored while it applies.
- It is recorded in the chain as an entry
LEGAL_HOLD_SETand set in the storage as an S3 legal hold on every object. - Setting and releasing it requires a reason as a key, for example
litigation-holdandlitigation-ended.
POST /crms/documents/7c1e…/legal-hold
{ "reason": "litigation-hold" }204 No ContentThe revision in the address only selects the chain. The hold then applies to all its revisions. You release it with POST /crms/documents/{revision}/legal-hold/release, also with a reason.
| Case | Answer |
|---|---|
| set a hold while one already applies | 409 document-legal-hold-active |
| release a hold while none applies | 409 document-legal-hold-inactive |
When a revision can be erased
| Revision already erased? | Legal hold on the chain? | retainUntil reached? | What happens on erasure |
|---|---|---|---|
| yes | – | – | 410 document-erased |
| no | yes | – | 409 document-legal-hold-active |
| no | no | no | 409 document-retention-active |
| no | no | yes | bytes deleted, key destroyed, tombstone stays |
There is no way to erase before the retention ends. If CRMS tried, the storage would refuse it (document-locked).
What happens on erasure
-
1CRMSchecks legal hold and retention, as in the table above
-
2CRMS→File storagedeletes exactly the object's version
-
3CRMS→Databasedestroys the document key. Its row stays as a tombstone, and the journal gets
document-key-destroyed -
4CRMS→Databaseappends an entry
ERASEDwith user and reason to the chain and writesdocument-erasedinto the journalResult: From now on reading answers 410document-erased. The chain still verifies as intact
The encrypted payload is in the database. It becomes unreadable with the same key. This kind of erasure by destroying the key is called crypto-shredding.
Two ways to erase
When: the normal case, the retention has expired
-
1CRMSworks through the work list every
CODAMAI_CRMS_RETENTION_INTERVAL(defaultPT24H), first in the system, then in every tenant -
2CRMSerases every revision that is due, user
crms-retention, reasonretention-expired -
3CRMSleaves revisions under a legal hold on the list, the next pass tries againResult: Revisions that were due are tombstones
When: someone requests erasure, for example under GDPR Art. 17, and no retention obligation stands in the way any more
-
1Client→CRMSsends
POST /crms/documents/{revision}/erasewith{"reason": "data-subject-request"} -
2CRMSchecks role, legal hold and retention as above
-
3CRMS→Clientanswers 204Result: The revision is a tombstone, and the requester is recorded as the user in the chain
Like the anchoring pass, the retention pass runs in every instance with CODAMAI_CRMS_SCHEDULING_ENABLED=true and reaches all tenants that CIAS knows, suspended and closed ones too.
Who may do what
| Call | Role (default) | Variable |
|---|---|---|
| set and release a legal hold | crms-document-custodian | CODAMAI_CRMS_REST_DOCUMENT_ROLES_HOLD |
| erase | crms-document-eraser | CODAMAI_CRMS_REST_DOCUMENT_ROLES_ERASE |
If the role is missing, CRMS answers 403 document-access-denied before it even looks for the document. So a refusal does not reveal whether the document exists. The full list of roles is in Roles.