compliance/checklists/*.yaml and are@Jurisdiction('EU') — or the member state, 'EU-DE' — and@Security({ frameworks: [SecurityFramework.GDPR] }).| Article | Asks | prorm | Yours |
|---|---|---|---|
| 5(1)(c) minimisation | hold only what is needed | @Personal on every personal field; the sheet lists what is held | deciding what is needed |
| 5(1)(e) storage limitation | no longer than necessary | @Personal(…, { retention }), DataRetentionPolicy, weekly purge (platform) | the schedule, if not on the platform |
| 6 lawful basis | a basis for every processing | @Personal(…, { basis }) — refused without one under EU; a basis India does not recognise is refused under EU+IN | choosing the right basis; the legitimate-interests assessment |
| 7 consent | demonstrable, withdrawable | ConsentRecord — append-only, versioned, with withdrawal | the consent UI; not bundling |
| 8 children | consent age 13–16 by member state; parental consent below | the age gate on @DataSubjectAge / @ParentalConsent; per-state ages in the registry; the parental flow (platform) | verifying the parent is a parent |
| 9 special categories | explicit basis and purpose | refused without both | the Art. 9(2) exemption you rely on |
| 12–14 transparency | tell them what you do | renderComplianceSheet() is the material for the notice | the notice itself |
| 15 access, 20 portability | within one month, in a usable format | DSARWorkflow, DataPortabilityExporter (JSON/CSV/NDJSON); requestDeadlineDays: 30 on the sheet | identity verification; the deadline tracking table |
| 16 rectification | an update() — and the audit trail records it | the request handling | |
| 17 erasure | RightToErasure with cascade; subject: true keys it | backups; the erasure register | |
| 18 restriction, 21 objection | DSARWorkflow request types | the processing pause itself | |
| 22 automated decisions | — | yours entirely | |
| 25 by design and default | the declaration is the design record; @Security the defaults | ||
| 28 processors | — | your DPA with the platform / host | |
| 30 records of processing | the sheets, one per model | assembling the register | |
| 32 security | encryption, pseudonymisation, integrity, resilience | FieldEncryption, PseudonymizationService, ImmutableRecord, audit trail; backups and restores (platform) | key management; the risk assessment |
| 33 breach to the regulator within 72 h | breachNotificationHours: 72 on the sheet; compliance.breach-clock.72h reminder (platform); BreachDetector | detecting a breach you did not cause; the notification | |
| 34 breach to subjects | — | yours | |
| 35 DPIA | before high-risk processing | PrivacyImpactAssessment records and approvals | doing the assessment |
| 37 DPO | — | yours | |
| 44–49 transfers | adequacy, SCCs, or derogations | CrossBorderLog.checkTransferAllowed(), the transfer log, the transfer-outside finding | the SCCs; the transfer impact assessment |
BreachDetector raises the alert, and the gdpr-72h-breachimport {
BreachDetector,
forwardBreachAlerts,
registerNotifier,
useEscalationPolicy,
WebhookNotifier,
} from 'ts-prorm-orm';
// The preset's channels: dpo, security, counsel, manager, exec.
registerNotifier(
'dpo',
new WebhookNotifier({ url: 'https://hooks.example.com/dpo', secret: process.env.DPO_HOOK_SECRET }),
);
registerNotifier(
'security',
new WebhookNotifier({ url: 'https://hooks.example.com/sec', secret: process.env.SEC_HOOK_SECRET }),
);
const manager = useEscalationPolicy(prorm, 'gdpr-72h-breach');
BreachDetector.create(prorm, { alertCallback: forwardBreachAlerts(manager, { tags: ['pii'] }) });manual, and only a person moves it:$ prorm audit attest gdpr.art28-processor-contracts \
--by dpo@example.com --role "Data protection officer" \
--statement "A signed DPA is on file for every processor in the register" \
--evidence DPA-2026-003,DPA-2026-011
✓ Attestation recorded: .prorm/attestations/gdpr.art28-processor-contracts.yamlprorm audit run --framework gdpr reports that item as attested,Attested by dpo@example.com (Data protection officer) on
2026-09-26. It stays attested until the attestation expires (one year after--expires) or the item's freshness window runs out,@Jurisdiction('US-CA') — or 'US-VA', 'US-CO', and the rest. Federal@Security({ frameworks: [SecurityFramework.CCPA] }).| Section | Asks | prorm | Yours |
|---|---|---|---|
| 1798.100 notice at collection | the sheet's "what is held" | the notice | |
| 1798.105 deletion | 45 days | RightToErasure; requestDeadlineDays: 45 | verification; service-provider pass-through |
| 1798.110/115 know | DataPortabilityExporter | ||
| 1798.120 opt out of sale/sharing | ConsentRecord with purpose 'sale'; opt-out-sale on the sheet | the "Do Not Sell" link; honouring GPC | |
| 1798.121 limit sensitive PI | limit-sensitive on the sheet; special categories declared | the limit-use link | |
| 1798.125 non-discrimination | — | yours | |
| 1798.130 verified requests | DSARWorkflow states | the verification | |
| 1798.140(ae) sensitive PI | government-id, location, protected, health, biometric, genetic are special under US-CA | ||
| children under 16 | opt-in to sale | consent age 16 under US-CA (13 in the other states); the age gate | the opt-in flow |
| 1798.150 breach — reasonable security | encryption, masking, the audit trail | the incident response |
@Security({ frameworks: [SecurityFramework.HIPAA] }) with encrypt naming@Jurisdiction('US') marks health special.| Safeguard | Asks | prorm | Yours |
|---|---|---|---|
| §164.312(a)(1) access control | unique user, role-based | RowLevelSecurity; database roles and GRANTs (User management) | the user directory |
| §164.312(a)(2)(iv) encryption at rest | FieldEncryption on PHI columns; dedicated instances and disk encryption (platform) | key custody | |
| §164.312(b) audit controls | ComplianceAuditTrail with user id and IP | log review | |
| §164.312(c) integrity | ImmutableRecord, DataLineage | ||
| §164.312(d) authentication | api keys per database and privilege; auth.failed.* policies (platform) | your identity provider | |
| §164.312(e) transmission security | TLSEnforcer; verify-full at the connection; access.require-verify-full (platform) | ||
| §164.308(a)(7) contingency | backups, restore testing | BackupVerification register; real backups, data.restore-test.90d (platform) | the plan |
| §164.530(j) retention 6 years | DataRetentionPolicy with { years: 6 } on the trail | ||
| business associate agreement | — | yours, with the platform | |
| minimum necessary | masking by role; @Personal purpose | the policy |
@Security({ frameworks: [SecurityFramework.PCI_DSS], encrypt: ['pan'], mask:
{ pan: 'card-first6' } }). Better still: do not store the PAN — tokenise at| Requirement | Asks | prorm | Yours |
|---|---|---|---|
| 3.4 PAN unreadable | FieldEncryption; PseudonymizationService tokens | key management (3.6, 3.7) | |
| 3.4.1 masking on display | first six / last four | Mask(…, { pattern: 'card-first6' | 'card-last4' }) | |
| 3.2 no SAD after authorisation | — | do not store CVV; nothing here helps you store it safely | |
| 4.2 strong cryptography in transit | TLSEnforcer; verify-full | ||
| 6.2 secure development | injection | parameterised queries everywhere; QueryFirewall behind them | code review |
| 7 least privilege | readonly / readwrite / admin keys; database roles | the access matrix | |
| 8.3.9 password / key rotation | ≤ 90 days | credentials.rotate.90d, credentials.key-age.90d, credentials.key-without-expiry (platform) | rotation elsewhere |
| 8.3 lockout on failed attempts | auth.failed.* (platform) | ||
| 10 logging | every access to cardholder data | audit trail; events feed and query log (platform) | 12 months online, review |
| 10.7 log integrity | ImmutableRecord on the trail; WORMStorage's SHA-256 chain (application-level) | storage-level immutability | |
| 11 testing | — | your scans and pen tests | |
| 12 policy | — | yours |
@Security({ frameworks: [SecurityFramework.SOC_2] }) requires audit,| Criterion | Asks | prorm | Yours |
|---|---|---|---|
| CC6.1 logical access | per-database keys with privilege and expiry; auth.failed.*, compliance.owner-without-mfa (platform) | the access review meeting | |
| CC6.2 provisioning and deprovisioning | compliance.access-review.30d, credentials.idle-key.* (platform) | acting on the review | |
| CC6.3 role-based | restrict-readonly policies; credentials.owner-key-exists (platform) | ||
| CC6.6 boundaries | ip allowlists; access.require-ip-allowlist, access.allowlist-cleared.* (platform) | ||
| CC6.7 data in transit / exfiltration | access.bulk-read.* (platform); TLS | DLP beyond the database | |
| CC7.2 anomaly detection | BreachDetector; auth.new-country.*, auth.new-ip.notify (platform) | triage | |
| CC7.3–7.5 incident response | the events feed; policy.fired with outcomes | the runbook | |
| CC8.1 change management | change.schema.*, change.migration.* (platform); migrations | approvals | |
| A1.2 backups | real backups, data.backup-age.*, data.no-backup-ever (platform) | ||
| A1.3 recovery testing | data.restore-test.90d (platform) | running one | |
| CC2.1 / CC3.2 information and risk | compliance.sheet.30d, change.policy-review.90d (platform) | reading them |
@Security({ frameworks: [SecurityFramework.SOX] }) requires audit,| Asks | prorm | Yours |
|---|---|---|
| records cannot be altered | ImmutableRecord; versioning appends | REVOKE UPDATE, DELETE at the database |
| seven-year retention | DataRetentionPolicy with { years: 7 }, and no shorter policy on those tables | |
| write-once storage | WORMStorage state machine with a SHA-256 tamper-evident chain (application-level) | object-lock on the archive |
| who changed what | ComplianceAuditTrail, DataLineage | segregation of duties |
| change control | change.* policies (platform) | approvals |
| Asks | prorm | Yours |
|---|---|---|
| know the age | @DataSubjectAge() on a date of birth | asking for it neutrally |
| verifiable parental consent below the threshold | @ParentalConsent() gate; the parent-nomination → consent flow with the parent named by email and username, consent links that expire (platform) | the verification method COPPA accepts for your risk level |
| parents can review and delete | RightToErasure; a parent's dashboard over the child's account and its restrictions (platform) | |
| no more than needed from a child | child is a special category under US, CA, IN, CN, SG, ZA, ID — needs basis and purpose | |
| the child comes of age | emancipation at 18, automatically (platform) | |
| no purchases by a child | child accounts cannot start billing (platform) |