Data processing & personal-data inventory (RoPA-ready)
Diátaxis quadrant: Reference. Audience: Data Protection Officers and privacy counsel completing a GDPR Article 30 record of processing activities (RoPA) for a deployment that fronts an origin with humanymous Gate (“Gate” after first mention).
This page is a descriptive inventory of the personal data Gate observes and stores in the reference implementation, written so that a DPO can lift the field-by-field detail directly into an Article 30 record and a pseudonymization policy note. It is not a compliance certification. Gate is processing tooling that supports your Article 30 and Article 17 obligations; it does not by itself make any deployment compliant.
Note: This repository is a reference implementation, not a production-hardened build. The categories, stored forms, and retention tiers below describe the reference build. A production deployment adds controls (prod-delta) but must not remove the pseudonymization and erasure guarantees described here. See Production vs. reference.
1. Controller and processor framing
Gate does not determine the purposes of the operator’s business processing. In GDPR terms:
- The operator that deploys Gate is the data controller. You decide why traffic is scored (protecting your origin from automated access), you set the legal basis, and you own the retention schedule and the erasure obligation.
- Gate is processing tooling operated under your control. It observes request signals, derives pseudonyms, records decisions to a tamper-evident audit log, and enforces verdicts at the edge. It fronts your origin app and does not control it.
Where Gate is operated by a third party on your behalf, that operator is your Article 28 processor; the topology and evidence in this document describe what that processor would be processing. This page does not assess any controller–processor contract.
1b. Collection-time transparency notice (GDPR Art. 13/14)
Gate itself does not discharge your duty to inform — that is a controller obligation you must satisfy at collection time (privacy policy + a layered notice). Use this as a starting snippet and adapt it to your deployment:
Automated security screening. To protect this service from automated abuse we analyse technical characteristics of your connection and browser (IP address, TLS and HTTP fingerprints, User-Agent and client hints, a device fingerprint, and interaction timings — never the keys you type). The legal basis is our legitimate interest in the security of our network and service (GDPR Art. 6(1)(f); a legitimate-interest assessment is on file). Data is used only for security, is not sold or used for advertising, and is retained per our retention schedule. You can request access or erasure, and contest an automated decision, at [email protected]. See our full privacy policy for details.
Publish the concrete retention periods, your identity as controller, and your DPO/contact alongside this notice.
2. The observe-versus-store distinction (core of the inventory)
The single most important fact for a RoPA entry is that the identifiers Gate observes are not the data Gate stores.
- Observed identifiers are read transiently during scoring, in memory, for the duration of a request lifecycle (see How Gate sees a request).
- Stored identifiers exist in the audit log only as per-subject-key-derived pseudonyms — a 64-hex value produced by a scrypt KDF-stretched derivation. Raw identifiers (IP, JA3/JA4, HTTP/2 fingerprint, UA, UA-CH, SNI, device fingerprint) are never written to the audit log in raw form.
Operational stores outside the audit-log pseudonymization (disclose these in your RoPA). The pseudonymization above covers the audit log. Two operational stores hold identifiers in a different form, and an adopter must account for them separately:
- Ban ledger. When shared-fleet mode (
-redis) is enabled, an IP/fingerprint ban is stored in Redis under a key that encodes the raw identifier (e.g.hmn:ban:ip:203.0.113.4); the value is HMAC-sealed. This is a legitimate-interest security record, but the key is a personal identifier held in the coordinator. It is bounded by a finite retention horizon (≈400 days even for “permanent” bans; a re-asserted ban refreshes it), and is lifted via the console/admin API. Single-node (default, in-memory) mode holds the same ban map in process memory only. Add the ban store to your RoPA and your Article 17 procedure (lift = erase).- Cross-session correlation registry. An in-memory, TTL-bounded graph of
fingerprint → {/24 subnets, session ids}used to detect residential-proxy rotation. It is per-process, never persisted, and swept on its TTL; it holds a transient device graph in raw form for the correlation window only. Note it as transient in-memory processing; it is not written to disk.
This means the “personal data at rest” and the “personal data observed in transit” are two different rows in your analysis. Section 3 enumerates both.
3. Personal-data inventory (field by field)
Detection-layer references (L1–L7) are defined in How Gate sees a request. “Observed form” is what Gate reads during scoring; “Stored form” is what is persisted to the audit log.
| # | Identifier / signal | Detection layer | Purpose of processing | Observed form (transient) | Stored form (at rest) |
|---|---|---|---|---|---|
| 1 | IP address | L5 (network/protocol) | Automated-traffic detection; rate metering; ban keying | Raw source address, in memory | 64-hex pseudonym only |
| 2 | JA3 / JA4 TLS fingerprint | L5 | TLS-stack consistency vs. claimed browser | Raw fingerprint, in memory | 64-hex pseudonym only |
| 3 | HTTP/2 fingerprint | L5 | Protocol-stack consistency; HTTP/2 abuse detection | Raw fingerprint, in memory | 64-hex pseudonym only |
| 4 | User-Agent (UA) | L1 / L6 | Claimed-client baseline; cross-check vs. TLS/JS | Raw header, in memory | 64-hex pseudonym only |
| 5 | User-Agent Client Hints (UA-CH) | L6 | Cross-check of UA against UA-CH and JS evidence | Raw hints, in memory | 64-hex pseudonym only |
| 6 | SNI (server name indication) | L5 | TLS handshake context | Raw SNI, in memory | 64-hex pseudonym only |
| 7 | Device fingerprint (canvas/WebGL/audio hash, screen, hardware) | L2 | Client fingerprint; cross-session correlation of automated traffic | Derived fingerprint, in memory | 64-hex pseudonym only |
| 8 | Behavioral signals (mouse, keystroke, scroll dynamics; isTrusted) |
L4 | Human-interaction evidence; automation cadence detection | Event-derived features, in memory | Pseudonymized / aggregated in the record |
| 9 | Session id | Control plane | Subject key that binds a subject’s pseudonyms together | Session identifier, in memory | Acts as the subject key; see section 4 |
| 10 | Verdict, risk score, contributing signal ids, route/host | L7 / edge | The decision record itself (audit evidence) | Computed at the edge | Recorded in the audit log |
| 11 | Resource-watermark ledger (session id + keyed IP pseudonym) | L5 (resource/watermark) | Per-session forensic leak-tracing of served resources | Session id + HMAC(masterKey, IP) token, in memory | In-memory only, ~24h TTL; self-expires — NOT persisted to the audit log and OUT of the crypto-shred erasure scope (it is not resolvable after TTL). |
Note: Rows 1–8 are read to compute a verdict and are not persisted in raw form. What persists is the pseudonym plus the decision metadata in row 10. The decision metadata references internal signal ids (for example
x.ua_vs_ja4); these are internal signal names and are never surfaced to the end user, who sees only plain language and an incident handle.
Biometric-data scope (design position). humanymous records timings only for the behavioral signals in row 8 — inter-event intervals for pointer/keystroke/scroll and the
isTrustedflag. Key values (which keys were pressed) are never captured or stored. Timing dynamics are not used for unique biometric identification of a natural person; they are used as automation-cadence evidence and are stored pseudonymized/aggregated. Whether timing dynamics nonetheless meet Article 4(14)/Article 9 “biometric data” for your specific deployment remains a controller determination — record it in your RoPA. The reference build applies no Article 9 special-category handling by default.
Note (low significance). Gate sets three client-side cookies/tokens as part of enforcement — the verdict trust token (
hmn_vt), the rotating request-integrity token (RIT), and the attestation step-up proof (hmn_su, minted on an attested route after a Pass solve). These are session-scoped, short-TTL, and not persisted to the audit log; each expires on its own and is discarded. They carry no new identifier: they bind only to data already inventoried above — the IP/subnet (row 1), the device fingerprint (row 7), and the session id (row 9). They therefore add no new personal-data category to this inventory. Record them, if at all, as transient enforcement state derived from existing rows.
4. Pseudonymization policy note
This section is the pseudonymization policy statement a DPO can cite directly.
- Every raw identifier is stored only as a pseudonym. The stored value is a 64-hex string.
- Derivation. Pseudonyms are produced with a scrypt key-derivation function, KDF-stretched with work factor N = 2¹². The stretching raises the cost of a brute-force reversal attempt against the stored pseudonym.
- The subject key is the session id. Pseudonyms for a given subject are derived under that subject’s key, which is the session id. This is what binds a subject’s several pseudonyms (their IP pseudonym, their fingerprint pseudonym, and so on) into one resolvable subject when the vault is present.
- The linkage material lives in a vault. The per-subject linkage keys that make re-identification possible are held in a vault, sealed with the node keystore (scrypt N = 2¹⁵ plus AES-256-GCM) when a keystore is configured. See Key management.
Confirmed in source: For each subject — keyed by the session id — the vault mints a random 32-byte linkage key (
K_subj) on first use and holds it in the vault; the session id is the handle to that key, not the key material itself. Each field’s pseudonym isscrypt(K_subj, salt = raw_field_value, N = 2¹², r = 8, p = 1, dkLen = 32), rendered as a 64-hex string (when stretching is disabled the reference falls back toHMAC-SHA256(K_subj, raw_field_value), the same 64-hex shape). The raw field value doubles as the scrypt salt, which provides per-field domain separation: two different identifiers under the same subject produce unlinkable pseudonyms, while the same identifier under the same subject is deterministic — so a subject’s own events stay linkable. There is no separate global pepper and no additional per-field salt; destroyingK_subj(crypto-shred) severs all of that subject’s pseudonyms at once.
5. Pseudonymous, not anonymous
For the RoPA classification, state this explicitly:
The audit data is pseudonymous, not anonymous (GDPR Recital 26; Article 4(5)). Because a vault of linkage keys can, under controlled conditions, resolve a pseudonym back to the subject it was derived from, the pseudonyms remain personal data and stay within the scope of the GDPR. Do not record this processing as anonymization or as outside GDPR scope.
Re-identification is not a routine product operation. Gate exposes no re-identification API and performs none in-process. Anyone who holds the sealed keystore and HMN_UNSEAL can resolve pseudonyms offline, alone, with no second approver and no audit record of that offline act. Dual-control in the product covers erasure, permanent/CIDR bans, and the kill switch — not re-identification. Organizational custody of the keystore is the entire control surface (see RBAC and separation of duties for product dual-control, and Key management for keystore custody).
6. Record-level tagging (legal basis and data class)
Audit records carry a single record-level tag — data_class — that supports your Article 30 mapping; legal basis is not tagged per traffic record but is captured on the erasure path. The legal basis is a controller determination: Gate does not choose the lawful basis for your traffic processing, and you should set and record it (for most bot-mitigation deployments this is a legitimate-interest or legal-obligation analysis you perform, not one Gate asserts).
Confirmed in source: In the reference the only record-level tag field is
data_class(JSONdata_class,omitempty) on the audit record; there is no per-recordlegal_basisfield. The reference defines no enumerated value set fordata_classand never populates it (carried for forward schema compatibility, empty in emitted records), so any data-class vocabulary is an operator/prod-delta you define. Legal basis is captured elsewhere: it is a required free-text field on the crypto-shred erasure path (LegalBasis, e.g."GDPR Art.17"or"PIPA"), recorded on the erasure request/decision and certificate — not as a tag on ordinary traffic records.
7. Retention tiers (declared, not enforced)
Records are never physically deleted as part of the erasure model (erasure works by destroying key material — see section 8). The reference names HOT / WARM / COLD horizons for documentation and a pure Tier(age) classifier used in tests:
| Label | Declared horizon | Runtime enforcement |
|---|---|---|
| HOT | ~90 days | None |
| WARM | ~1 year | None |
| COLD | ~7 years | None (and not WORM media) |
Honest residual: Without
-audit-walthe chain is RAM-only and lost on restart. With-audit-walthe WAL grows without bound. Neither path implements a retention schedule. Set calendar retention, archival, and delete/retire policy yourself (prod-delta). The Ledger Retention card is hardcoded labels, not live policy.
Confirmed in source:
RetentionPolicy.Tier(age)has no non-test production caller that prunes or relocates storage. Physical WORM retirement is not shipped.
8. Erasure mechanism (cryptographic erasure)
The right-to-erasure mechanism is cryptographic erasure (crypto-shred): the erasure request destroys the per-subject linkage key that binds a subject’s pseudonyms to the identifiers they were derived from. The audit records remain in place and cryptographically verifiable; once the key is gone, the pseudonyms can no longer be resolved back to the subject.
Crypto-shred is DPO-gated and dual-control, with a cancellable hold window before the shred commits. The full procedure, role gates, and hold-window handling are in the Right-to-erasure (crypto-shred) runbook.
Warning: Cryptographic erasure is irreversible. Destroying the per-subject linkage key cannot be undone, and there is no recovery path once the shred commits. Confirm the subject-to-pseudonym mapping before you request erasure, and use the hold window as your final checkpoint.
Gate supports your Article 17 obligation by giving you a targeted, auditable erasure primitive and a sealed erasure certificate on execution — sealed when the hold window elapses and the shred runs, not at commit, and a cancelled erasure produces no certificate. It does not discharge the obligation for you; intake, subject verification, and the decision to erase remain controller responsibilities.
9. Residual risk (state this honestly in your DPIA)
Pseudonymization reduces re-identification risk; it does not eliminate it. State the residual plainly:
- Several of the observed identifiers are low-entropy (for example an IP address, or a UA string shared by many clients). A low-entropy identifier held behind a pseudonym is re-identifiable only if the underlying key material leaks — that is, if an adversary obtains the vault linkage key that resolves the pseudonym. Absent that key, the 64-hex pseudonym does not by itself reveal the subject.
- Crypto-shred destroys exactly that key material. After a subject’s linkage key is shredded, the low-entropy identifiers behind that subject’s pseudonyms can no longer be resolved from the audit log, because the resolving key no longer exists.
- The honest boundary is therefore key custody: the strength of the pseudonymization is the strength of vault-key protection and dual-control, plus the scrypt stretching that raises the cost of brute-forcing a pseudonym directly.
10. Backups (operator responsibility)
Any backup that includes the vault or the node keystore is a re-identifiable copy of the linkage material and must be held under controls equivalent to the live vault. A backup taken before an erasure also holds a copy of the key that the erasure destroyed; that copy would re-enable resolution unless it is retired under the same schedule.
Warning: Backups of the vault or keystore are outside the crypto-shred boundary. If you back up the sealed keystore or vault, you are responsible for ensuring that an erasure is propagated to — or the corresponding key material is retired from — those copies. Otherwise a restore can re-establish linkage that a live shred already destroyed.
Confirmed in source: The reference produces no on-disk copy of the vault beyond the single sealed keystore file. The vault’s per-subject linkage keys are serialized (
Vault.Snapshot) into theVaultfield ofKeyMaterialand sealed — together with the signing and HMAC keys — into one file written bySealKeys(scrypt-derived AES-256-GCM, mode 0600). No separate vault file is written anywhere, and the durable audit sinks (WAL, Redis, ClickHouse) persist only pseudonymized records, never linkage-key material. Your backups of that one keystore file are the entire on-disk vault surface to inventory.
Related pages
- How Gate sees a request — the pseudonymization model and the L1–L7 layers referenced above.
- Right-to-erasure (crypto-shred) runbook — the Article 17 procedure.
- Compliance & DPO start here — orientation for the DPO role.
- RBAC and separation of duties — the dual-control model that gates erasure, permanent/CIDR bans, and the kill switch (not re-identification).
- Key management — keystore, vault, and unseal handling.
- Production vs. reference — what the reference does not ship for production.