Skip to content

Data Privacy & GDPR

Gatewyse provides two admin operations for handling data-subject requests under the GDPR: a data export (right of access) and an erasure (right to be forgotten). Both are RBAC-gated and strictly tenant-scoped — an administrator can only export or erase users within their own tenant.

Data Export (Article 15)

Retrieve a complete, secret-free bundle of a single user’s data as a downloadable JSON file.

GET /api/admin/users/:id/data-export
  • Permission: requires the users:read permission.
  • Scope: tenant-scoped. The user must belong to the caller’s tenant, or the request returns 404 Not Found.
  • Response: application/json served as a file attachment (Content-Disposition: attachment; filename="data-export-<id>.json"), pretty-printed.

The bundle assembles the user’s data across collections within the tenant:

FieldContents
exportedAtISO-8601 timestamp of when the bundle was generated.
subjectThe userId and tenantId the export covers.
profileThe user record, with all secrets stripped (passwordHash, mfaSecret, recoveryCodes, passwordHistory are excluded).
apiKeysThe user’s API keys, with the stored key hash (keyHash) removed.
usageRecordsThe user’s usage records.
requestLogsA capped, most-recent sample of the user’s request logs (see below).

Request-log sampling

To keep the export synchronous and bounded, request logs are capped at a sample of the 5000 most recent entries. The requestLogs object reports both the true size and whether the sample was truncated:

"requestLogs": {
"totalCount": 41230,
"sampleLimit": 5000,
"truncated": true,
"records": [ /* up to 5000 most-recent request logs */ ]
}

The export is read-only — it never modifies the user or their data. It is secret-free by construction: password hashes, MFA secrets, recovery codes, password history, and API-key hashes are all excluded.

Erasure / Right to be Forgotten (Article 17)

Anonymize a user’s personal data in place and scrub the personal content captured in their request logs.

POST /api/admin/users/:id/erase
Content-Type: application/json
{ "confirm": true }
  • Permission: requires the users:delete permission.
  • Scope: tenant-scoped — the user must belong to the caller’s tenant.
  • Confirmation: the body must include { "confirm": true }. Any other body is rejected with a validation error (Erasure requires { "confirm": true }). This is a destructive operation with no automatic undo.

What erasure does

The user record is anonymized, not deleted, so foreign-key references from other collections stay valid:

  • Email is replaced with erased-<userId>@deleted.invalid (the user id keeps the anonymized address unique under the tenant’s email index).
  • Name is cleared.
  • Status is set to deactivated.
  • Auth secrets are wiped: password hash, MFA secret, recovery codes, password history, and any SSO linkage (externalId, ssoProviderId) are removed; MFA is turned off.
  • Request/response bodies captured in the user’s request logs are unset (scrubbed). The response reports how many log documents were scrubbed.

What erasure preserves

The append-only audit chain is left intact. Audit entries are tamper-evident integrity records that reference the (now anonymized) user id — they are not a store of the erased personal data, so removing them would break the audit chain’s verifiability without improving privacy.

Response

{
"data": {
"message": "User data erased",
"userAnonymized": true,
"requestLogsScrubbed": 128
}
}