@crewhaus/data-retention-engine 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/templates/README.md +30 -0
- package/templates/retention-sweep.yml +98 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewhaus/data-retention-engine",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GDPR-shaped data retention: retain / export / purge with cron-style sweeper + audit window override (Section 39)",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"test": "bun test src"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@crewhaus/errors": "0.3.
|
|
18
|
+
"@crewhaus/errors": "0.3.2"
|
|
19
19
|
},
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"author": {
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
|
-
"files": ["dist", "README.md", "LICENSE", "NOTICE"]
|
|
38
|
+
"files": ["dist", "templates", "README.md", "LICENSE", "NOTICE"]
|
|
39
39
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# data-retention-engine templates
|
|
2
|
+
|
|
3
|
+
Copy-in starting points for operating Section 39 GDPR/TTL retention on a
|
|
4
|
+
schedule. These are **templates, not active workflows** — nothing in this
|
|
5
|
+
directory runs from inside the factory repo.
|
|
6
|
+
|
|
7
|
+
- [`retention-sweep.yml`](retention-sweep.yml) — GitHub Actions cron
|
|
8
|
+
template. Copy it into your deployment repository's `.github/workflows/`
|
|
9
|
+
and edit the `<PLACEHOLDER>` comments. It chains the schedulable CLI
|
|
10
|
+
surfaces this package pairs with:
|
|
11
|
+
|
|
12
|
+
1. `crewhaus retention sweep [--dry-run] [--dir <root>]` — enforce
|
|
13
|
+
`.crewhaus/retention.json` (per-store `maxAgeDays`, session `pins`,
|
|
14
|
+
deferring `auditWindows`) over the harness stores. Sessions expire by
|
|
15
|
+
file mtime under session-store's own eviction rules; the hash-chained
|
|
16
|
+
audit log is **never deleted** (export-only — any deletion breaks
|
|
17
|
+
`verify()`'s cross-file chain). Real runs append a
|
|
18
|
+
`retention_enforcement` evidence record to `.crewhaus/audit`.
|
|
19
|
+
2. `crewhaus audit verify --dir .crewhaus/audit` — post-sweep tamper
|
|
20
|
+
tripwire over the same chain the sweep just appended to.
|
|
21
|
+
|
|
22
|
+
The companion verbs share the sweep's rules (and all honor `--dry-run`):
|
|
23
|
+
`crewhaus retention export <outDir> [--since <date>]` (right-to-export —
|
|
24
|
+
copies records out, raw) and `crewhaus retention purge [--before <date>]`
|
|
25
|
+
(right-to-delete).
|
|
26
|
+
|
|
27
|
+
**Restoring stores onto a runner? Preserve mtimes.** Retention is
|
|
28
|
+
mtime-keyed, and `aws s3 sync`-style restores stamp files with the
|
|
29
|
+
download time — the sweep then silently never fires. Use the tar-based
|
|
30
|
+
round-trip shown in the template's `<STORE>` comments.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# retention-sweep.yml — scheduled GDPR/TTL retention enforcement TEMPLATE.
|
|
2
|
+
#
|
|
3
|
+
# This is a TEMPLATE, not an active workflow: copy it into your deployment
|
|
4
|
+
# repository's `.github/workflows/` and edit the <PLACEHOLDER> comments.
|
|
5
|
+
# One cron line then enforces `.crewhaus/retention.json` over the harness
|
|
6
|
+
# stores on a schedule — expired sessions are deleted under the exact rules
|
|
7
|
+
# session-store's own TTL eviction uses, while the hash-chained audit log is
|
|
8
|
+
# NEVER deleted (any deletion, even a whole oldest day file, would break
|
|
9
|
+
# `crewhaus audit verify`'s tamper check — audit is export-only). Every real
|
|
10
|
+
# sweep appends a `retention_enforcement` record to `.crewhaus/audit`, so the
|
|
11
|
+
# enforcement itself is tamper-evidenced.
|
|
12
|
+
#
|
|
13
|
+
# Prerequisites:
|
|
14
|
+
# - The runner can reach the harness directory that owns `.crewhaus/`
|
|
15
|
+
# (sessions + audit). Stores live where your agents RUN, so on an
|
|
16
|
+
# ephemeral CI runner you typically restore/mount them first — AND
|
|
17
|
+
# persist them back after the sweep, or the deletions (and the appended
|
|
18
|
+
# evidence record) evaporate with the runner (see the <STORE> steps).
|
|
19
|
+
# - Optional: a `.crewhaus/retention.json` in the harness directory. Without
|
|
20
|
+
# one the sweep uses the safe defaults (sessions expire after 30 days —
|
|
21
|
+
# session-store's TTL — no pins, no audit windows):
|
|
22
|
+
# {
|
|
23
|
+
# "version": 1,
|
|
24
|
+
# "sessions": { "maxAgeDays": 30 },
|
|
25
|
+
# "pins": ["sess_0123456789abcdef"],
|
|
26
|
+
# "auditWindows": [
|
|
27
|
+
# { "frameworkId": "soc2", "controlId": "CC6.1",
|
|
28
|
+
# "expiresAt": "2026-08-01T00:00:00Z" }
|
|
29
|
+
# ]
|
|
30
|
+
# }
|
|
31
|
+
|
|
32
|
+
name: retention-sweep
|
|
33
|
+
|
|
34
|
+
on:
|
|
35
|
+
schedule:
|
|
36
|
+
# <CRON> Daily at 04:23 UTC. The sweep is idempotent — anything already
|
|
37
|
+
# deleted or still inside its retention window is simply reported as
|
|
38
|
+
# kept — so a more (or less) frequent cron is equally safe.
|
|
39
|
+
- cron: "23 4 * * *"
|
|
40
|
+
# Manual runs for right-to-delete requests (pair with `retention export`
|
|
41
|
+
# first when the data subject also asked for a copy).
|
|
42
|
+
workflow_dispatch: {}
|
|
43
|
+
|
|
44
|
+
jobs:
|
|
45
|
+
sweep:
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v4
|
|
49
|
+
|
|
50
|
+
# <STORE> Make the harness `.crewhaus/` stores available to this job.
|
|
51
|
+
# Replace with however your deployment persists them (restore from
|
|
52
|
+
# object storage, mount a volume, run on the host that owns them, ...).
|
|
53
|
+
# Skip it entirely if this workflow already runs on that machine.
|
|
54
|
+
#
|
|
55
|
+
# WARNING — mtimes must survive the round-trip. Session retention is
|
|
56
|
+
# keyed on each file's filesystem MTIME (the same rule session-store's
|
|
57
|
+
# own TTL eviction uses), and `aws s3 sync` (like most object-store
|
|
58
|
+
# download tools) stamps restored files with the DOWNLOAD time — every
|
|
59
|
+
# session then looks freshly touched and the sweep silently never
|
|
60
|
+
# deletes anything on a restored runner. Persist/restore an archive
|
|
61
|
+
# that preserves mtimes instead, e.g. tar (which records and restores
|
|
62
|
+
# them by default):
|
|
63
|
+
# persist: tar -czf crewhaus-store.tgz .crewhaus
|
|
64
|
+
# aws s3 cp crewhaus-store.tgz s3://<YOUR-BUCKET>/
|
|
65
|
+
# restore: aws s3 cp s3://<YOUR-BUCKET>/crewhaus-store.tgz .
|
|
66
|
+
# tar -xpzf crewhaus-store.tgz
|
|
67
|
+
# - name: Restore harness stores
|
|
68
|
+
# run: aws s3 sync s3://<YOUR-BUCKET>/crewhaus-store .crewhaus
|
|
69
|
+
|
|
70
|
+
- name: Install crewhaus
|
|
71
|
+
# Any channel works: npm i -g crewhaus, brew install crewhaus/tap/crewhaus, ...
|
|
72
|
+
run: npm install -g crewhaus
|
|
73
|
+
|
|
74
|
+
- name: Dry-run first — log what the sweep will delete and why
|
|
75
|
+
# Deletes nothing and appends no evidence; the report lands in the
|
|
76
|
+
# job log so a surprising deletion set is visible BEFORE it happens.
|
|
77
|
+
run: crewhaus retention sweep --dry-run
|
|
78
|
+
|
|
79
|
+
- name: Enforce retention
|
|
80
|
+
# Deletes expired sessions (honoring retention.json pins + audit
|
|
81
|
+
# windows; audit day files are never deleted) and appends the
|
|
82
|
+
# tamper-evident `retention_enforcement` record to .crewhaus/audit.
|
|
83
|
+
run: crewhaus retention sweep
|
|
84
|
+
|
|
85
|
+
- name: Verify the audit chain still checks out
|
|
86
|
+
# The sweep's evidence append must land on an intact chain — a broken
|
|
87
|
+
# link here means the store was tampered with out-of-band.
|
|
88
|
+
run: crewhaus audit verify --dir .crewhaus/audit
|
|
89
|
+
|
|
90
|
+
# <STORE> Persist the swept stores back if you restored them above —
|
|
91
|
+
# otherwise the deletions AND the evidence record are lost with the
|
|
92
|
+
# runner and the next sweep re-reports the same expired sessions.
|
|
93
|
+
# Use the mtime-preserving tar round-trip from the restore step above,
|
|
94
|
+
# NOT a bare `aws s3 sync` (see the WARNING there).
|
|
95
|
+
# - name: Persist harness stores
|
|
96
|
+
# run: |
|
|
97
|
+
# tar -czf crewhaus-store.tgz .crewhaus
|
|
98
|
+
# aws s3 cp crewhaus-store.tgz s3://<YOUR-BUCKET>/crewhaus-store.tgz
|