This page maps library features to GDPR obligations. It is not legal advice and not a compliance certification. The operator remains the data controller.
1. Personal Data theauth-go Stores by Default
The following table lists every personal data field stored by the library’s built-in storage adapters (memory, Postgres, MySQL and SQLite). Operators using a custom storage adapter may vary.
Data not stored by theauth-go:
- Raw passwords (only Argon2id PHC strings).
- Raw session tokens, magic-link tokens, or SCIM tokens (only SHA-256 hashes).
- TOTP secrets in plaintext (only AES-256-GCM ciphertext).
- Private signing keys in the database (Ed25519 private keys live in process memory only).
2. Data Subject Rights — How to Satisfy Each
For each GDPR right, this section describes which library API satisfies the request and what the operator must build on top.Article 15 — Right of Access
What the data subject can request: A copy of all personal data held about them, the purposes of processing, retention periods, and third-party disclosures. Library APIs that provide the data:
Operator gap: The operator must expose an export endpoint that calls these APIs, aggregates the results, and returns a structured response (JSON, CSV, or PDF as appropriate) to the authenticated data subject or their authorized representative. The library provides the data; the endpoint is the operator’s responsibility.
Article 16 — Right to Rectification
What the data subject can request: Correction of inaccurate or incomplete personal data. Library API:patchUser admin endpoint accepts name, email field updates (internal/admin/). SCIM PATCH operations also support incremental updates.
Operator gap: The operator must expose a user-facing profile update form or endpoint that calls patchUser. If the user’s email is their login identifier, the operator must verify ownership of the new address before applying the change.
Article 17 — Right to Erasure (Right to Be Forgotten)
What the data subject can request: Deletion of their personal data when the data is no longer necessary or when they withdraw consent. Library behavior:removeUseradmin handler (internal/admin/) removes the user from their organization.- Database foreign key constraints cascade deletion of sessions, OAuth accounts, WebAuthn credentials, TOTP secrets, SAML identities, and magic links when a user row is deleted (cascade behavior enforced at the storage layer).
audit_eventsrows referenceactor_user_idbut are not automatically deleted on user removal because audit integrity requires them. Theactor_user_idfield may be replaced with a tombstone value (e.g., a zeroed ULID) by an operator-written sweep without losing the event record.
- Implement a hard-delete or anonymize endpoint that removes the user row and triggers cascades.
- Implement an audit event anonymization sweep that replaces
actor_user_id,ip, anduser_agentwith tombstone values for the erased subject, if full GDPR erasure of audit trails is required. - If backup retention exceeds the erasure window, document this in the DPN and implement a backup purge or crypto-shredding strategy.
Article 18 — Right to Restriction of Processing
What the data subject can request: That their data not be actively processed while a dispute is resolved. Library API: None. ThepatchUser admin handler accepts a status field in its request body but never persists or acts on it (it currently only applies roleIds changes) — there is no user-suspension state anywhere in the User model, the users table, or the Storage interface. The closest built-in primitive is revokeSession (internal/admin/), which invalidates the user’s active sessions but does not prevent them from signing in again.
Operator gap (critical): There is no built-in restriction-of-processing flag. To honor Article 18, the operator must add their own suspension state (e.g., an application-level status column consulted at the top of every auth flow) and revoke existing sessions via revokeSession when a restriction request is received. Build the review-and-lift process on top of that operator-owned state.
Article 20 — Right to Data Portability
What the data subject can request: Their personal data in a structured, commonly used, machine-readable format. Library APIs: Same APIs as Article 15 (right of access). The data returned is already structured (JSON). Operator gap: Format and expose the export. The operator controls the response format; JSON or CSV are both acceptable under GDPR portability requirements.Article 21 — Right to Object
What the data subject can request: That processing stop, particularly for direct marketing or legitimate-interest grounds. Library API: Session revocation is available viarevokeSession (internal/admin/), which invalidates a session immediately. This stops that session but, as noted under Article 18, there is no library-level account suspension to prevent the user from signing in again with a fresh session.
Operator gap: Build an objection intake form. Revoke active sessions via revokeSession as an immediate step, and layer an operator-owned suspension/deactivation flag on top if processing must stop entirely rather than just ending the current session. Log the objection and the action taken.
Article 22 — Rights Related to Automated Decision-Making
What the data subject can request: Not to be subject to solely automated decisions with significant effects. Library relevance: theauth-go does not implement any automated decision-making, profiling, or scoring logic. Authentication outcomes (success/failure) are deterministic based on credentials and configured policy; they are not ML-based inferences. Operator gap: If the operator builds automated decision-making above theauth-go (e.g., fraud scoring), they must address Article 22 independently.3. Data Retention
Default TTLs
Audit Event Retention
Audit events are INSERT-only (theStorage interface exposes no update or delete path for audit_events) and have no built-in TTL. This is intentional for security, but it is append-only, not cryptographically tamper-evident: nothing in the library prevents a party with direct database access from rewriting rows, and no Merkle-chaining or signing is implemented (see the threat model, “Audit log tampering”). The append-only design still creates a tension with GDPR data minimization.
Operator actions required:
- Define a retention period appropriate to your legal obligations (e.g., 12 months for security logs, 7 years for financial audit trails).
- Implement a scheduled sweep that deletes or anonymizes
audit_eventsrows older than the retention period. - If you forward audit events to an external SIEM, configure the SIEM’s own retention policy to match your DPN.
Sweep Patterns
Expired rows (magic links, sessions, oauth codes) are not automatically purged by the library. The operator must run periodic SQL sweeps:4. Data Residency and Cross-Border Transfers
Where theauth-go Stores Data
theauth-go stores data in the operator’s chosen database (Postgres, MySQL, SQLite, or the in-memory store for testing). The library does not run any service of its own and sends no telemetry. Personal data leaves the process only through integrations the operator configures: audit sinks, the email sender, OAuth and SAML identity providers, and the optionalBreachChecker (the bundled Have I Been Pwned checker sends a hash prefix, not the password).
The operator controls:
- The database server location (region/AZ).
- Whether replication crosses borders.
- Whether backup destinations cross borders.
Audit Sink Cross-Border Risk
When the operator configures an audit sink, events containing personal data (user ID, IP, user agent) may be transmitted to the sink’s endpoint. Built-in sinks:
Operator obligation: Before enabling any sink that sends data to a third-party vendor, sign a Data Processing Agreement (DPA) with that vendor. Ensure the vendor’s processing location is within your permitted data protection boundary, or implement an appropriate transfer mechanism (Standard Contractual Clauses, Adequacy Decision, etc.).
OAuth Provider Redirects
During OAuth social login, the user’s browser is redirected to the operator-configured OAuth provider (GitHub, Google, Apple, etc.). The browser interaction is between the user and the provider; theauth-go does not proxy it. The provider’s own privacy policies and data transfers apply to that interaction.Sub-processor List
theauth-go is a Go library, not a SaaS service. It has no sub-processors. The library code runs entirely within the operator’s process. The operator’s infrastructure vendors (cloud provider, database vendor, SIEM vendor) are the operator’s sub-processors, not theauth-go’s.5. Privacy-by-Design Defaults
Credential Storage
- Passwords: Argon2id with
m=64 MiB, t=3, p=4(crypto/password.go). Parameters are embedded in the PHC string so future work-factor increases can be applied on next login without data migration. - Session tokens, magic-link tokens, SCIM tokens: stored as SHA-256 hashes only; raw values are returned to clients in cookies or email links and are not persisted.
- TOTP secrets: AES-256-GCM encrypted before storage (
internal/totp/service.go). The encryption key must be supplied by the operator viaConfig.EncryptionKeyor the audit config.
Secrets and Email Addresses in Logs
The default audit redactor strips the following keys at any JSON nesting depth before any sink receives an event (internal/audit/redact.go):
passwordsecrettokencoderefresh_tokenaccess_token
email.Noop no longer contain email addresses; they carry a user_id or a 12-hex email_ref hash instead. Your own logging, reverse proxy and email provider are outside this. The default redactor is applied unconditionally after any custom redactor; a custom redactor cannot re-introduce a stripped key (internal/audit/).
Session Cookie Security
Since v2.6.0, cookies are also marked
Secure per request when BaseURL is https, the connection is TLS, or a TrustedProxies peer sends X-Forwarded-Proto: https. A slog.Warn is emitted at startup when SecureCookie=false and BaseURL is not https, unless SuppressSecureCookieWarning=true. Production deployments should set SecureCookie=true.
IP and User Agent in Sessions
IP address and user agent are stored on every session row for security audit purposes. There is no built-in knob to disable this collection because it is used for anomaly detection and audit tracing. Operator options if collection is not permitted:- Deploy theauth-go behind a proxy that strips or replaces the real IP before it reaches the library (the library reads the IP via
httpx.ClientIP, which respectsTrustedProxiesconfiguration). - After session creation, run an anonymization sweep that replaces the IP column with a zeroed value.
Argon2id Work Factor
The default work factor ism=64 MiB, t=3, p=4. Check it against current OWASP guidance for your risk level. The work factor is not exposed as a config knob for password hashing; it is a constant in crypto/password.go and can be increased by upgrading to a future library version. PasswordPolicy.AllowLegacyBcrypt (v2.6.0 honors it at signin, step-up and password change) accepts older bcrypt hashes and OnLegacyHashAccepted fires after a successful upgrade to Argon2id.
6. Operator’s GDPR Checklist
The following is a practical checklist for operators deploying theauth-go in an EU/EEA context. Before go-live:- Publish a Privacy Notice (DPN) that lists every data field in Section 1 of this document and explains the lawful basis for each.
- Define a data retention schedule for each data category in Section 3.
- Set
Config.SecureCookie = truein all production environments. - Store the TOTP encryption key (
Config.EncryptionKey) in a secrets manager separate from the database. - Identify all audit sink destinations; sign DPAs with each vendor before enabling the sink.
- Choose database region(s) consistent with your DPN’s data residency commitments.
- Build a data export endpoint that calls:
UserByID, session listing,listOAuthAccounts, WebAuthn credential listing, TOTP enrollment status, SAML identity listing,QueryAuditEventsfiltered by user ID. - Build an erasure endpoint that: deletes the user row (cascades to sessions, OAuth accounts, WebAuthn credentials, TOTP secrets, magic links), anonymizes
audit_eventsrows (replaceactor_user_id,ip,user_agentwith tombstone values). - Wire both endpoints to an authenticated data-subject request intake form.
- Run scheduled sweeps to purge expired sessions, magic links, and other short-TTL rows.
- Run a scheduled sweep to delete or anonymize
audit_eventsrows beyond your retention period. - Review role grants on a defined cadence (at minimum quarterly) using
audit_eventsrows forrole.grantedandrole.revoked. - Update your DPN if you add new audit sinks or collect additional metadata fields.
- Conduct a DPIA (Data Protection Impact Assessment) if your use of theauth-go involves high-risk processing (large scale, sensitive categories, systematic monitoring).