Skip to main content

Crate cratefield_module_privacy

Crate cratefield_module_privacy 

Source
Expand description

cratefield-module-privacy: what this deployment holds about a person, and everything it holds about one.

The module knows no venture’s schema. Every table it reads is one another module declared through Module::personal_data, composed at build into the PersonalDataCatalog this reads — declaring a table is the whole wiring, so a composed venture gets subject access over whatever else it composed, per table, with none of its own.

Data held outside the harness — a warehouse, a CRM, another product’s database — is reached by registering a provider with Privacy::provider; each is called over one signed HTTP contract, and requires() grows the HttpClient and Defer ports it needs with it. The other end of that same contract is Privacy::serve_provider: a deployment that holds such a system of its own, or is itself the system another deployment reaches, can answer /v1/privacy/provider/* over the same declarations, with the same signature and the same answer.

What catches a table nobody declared is cratefield_core::undeclared_tables, through cratefield_testing::conformance — a kit check, not a build error (issue #268). Silence is legitimate for a module with no tables, and a venture should not be unable to boot because some module’s author has not got to this yet. Declaring a table the module does not own is still a build error, which is the rule this one was confused with.

cratefield-module-privacy — Answer the request.

cratefield-module-privacy on crates.io cratefield-module-privacy documentation MIT

§cratefield-module-privacy

Subject access and erasure over whatever a venture composed.

The module knows no venture’s schema. Every table it reads is one another module declared through Module::personal_data, composed at build into a catalog. Compose it and a deployment can answer “what do you hold about me” — and erase it — with no per-venture wiring.

An app’s own Postgres or CRM is outside that catalog, so the routes also reach external providers: HTTP endpoints the venture registers with Privacy::new().provider(…) and that hold personal data the harness never sees. The protocol, a TypeScript reference provider and the error kinds are in docs/PRIVACY.md.

  • GET /v1/privacy/manifest — what this deployment holds, per table: the kind, what erasure would do, and the sentence the owning module wrote. Unauthenticated: it describes the deployment, not a person.
  • GET /v1/privacy/export?subject=<id> — every row every module holds for one subject. Admin-guarded. A column the owning module declared as redacted is named and printed as [redacted] rather than copied: a push token or a Web Push endpoint is a bearer capability, and an export is a file somebody forwards.
  • POST /v1/privacy/erase — what erasure would do, per table, with row counts and a short-lived signed token. Writes nothing.
  • POST /v1/privacy/erase/confirm — carries it out, in one batch, and counts the rows again afterwards rather than trusting the statements. The subject comes from the token, never from the body.

And, when the deployment opts in with Privacy::new().serve_provider("PRIVACY_PROVIDER_SECRET"), the other end of the same protocol — this deployment answering a signed caller that it is itself a system someone else holds data in:

  • POST /v1/privacy/provider/export — the same tables, rows and redactions the local export renders, for one subject.
  • POST /v1/privacy/provider/erase/plan — per table, delete, anonymise or retain with the reason it is kept.
  • POST /v1/privacy/provider/erase/apply — the erasure, atomically, verified by counting what is left.

The HMAC over the raw body is the authorisation on those three — a caller on another deployment has no account here and no admin token to present — and the secret is read from the config port at request time, so a deployment without one refuses every call rather than opening.

What it can reach locally is exactly what the composed modules declared — plus any external providers registered on it. A module that owns a table and declares nothing about it is outside the routes, which is why cratefield_testing::conformance fails one that does (issue #244).


MIT. Built in the open for Cratefield, a Factory Zero venture.

Structs§

HttpProvider
One external system holding data about a subject; built with HttpProvider::new and registered with Privacy::provider.
Privacy
Subject access and erasure over whatever the venture composed, plus the external providers a venture registered.

Constants§

SIGNATURE_HEADER
The header every provider call carries, under the in-repo signing idiom (module-webhooks signs deliveries the same way, so one receiver-side verifier covers both).