Privacy & GDPR API

GDPR compliance endpoints for data export and deletion (Right to Access and Right to be Forgotten)

Updated Dec 16, 2025
Edit on GitHub

Privacy & GDPR API

The Privacy API provides GDPR-compliant endpoints for exercising user privacy rights, including the Right to Access (data export) and the Right to be Forgotten (data deletion/anonymization).

Overview

The SSO platform implements comprehensive GDPR compliance features:

  • Right to Access: Users can export all personal data held by the platform
  • Right to be Forgotten: Users can request anonymization of their personal data
  • Audit Logging: All privacy operations are logged for compliance
  • Data Minimization: Only necessary data is collected and retained
  • Purpose Limitation: Data is only used for its intended purpose

Endpoints Summary

Method Path Description
GET /api/privacy/export/:user_id Export all user data (Right to Access)
DELETE /api/privacy/forget/:user_id Anonymize user data (Right to be Forgotten)

Right to Access

GET /api/privacy/export/:user_id

Export a comprehensive data package containing all personal information held by the platform for a specific user.

Permissions:

  • Users can export their own data
  • Organization owners can export data for their organization members
  • Platform owners can export any user’s data

Headers:

Header Value Required
Authorization Bearer {jwt} Yes

Path Parameters:

Parameter Type Description
user_id string User ID to export data for

Example Request (Self-Export):

curl -X GET https://sso.example.com/api/privacy/export/user-id-123 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Example Request (Organization Owner):

curl -X GET https://sso.example.com/api/privacy/export/member-user-id-456 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Success Response (200 OK):

{
  "user_id": "user-id-123",
  "email": "user@example.com",
  "created_at": "2024-06-15T10:00:00Z",
  "memberships": [
    {
      "organization_id": "org-id-456",
      "organization_slug": "acme-corp",
      "role": "admin",
      "joined_at": "2024-06-15T10:05:00Z"
    },
    {
      "organization_id": "org-id-789",
      "organization_slug": "dev-team",
      "role": "member",
      "joined_at": "2024-08-20T14:30:00Z"
    }
  ],
  "login_events_count": 247,
  "login_events": [
    {
      "id": "login-event-abc",
      "timestamp": "2025-01-15T09:30:00Z",
      "ip_address": "203.0.113.42",
      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
      "provider": "github",
      "success": true,
      "risk_score": 15,
      "risk_factors": "[\"new_device\"]",
      "geo_country": "US",
      "geo_city": "San Francisco"
    }
  ],
  "oauth_identities": [
    {
      "provider": "github",
      "provider_user_id": "github-123456",
      "linked_at": "2024-06-15T10:00:00Z"
    },
    {
      "provider": "google",
      "provider_user_id": "google-789012",
      "linked_at": "2024-07-10T14:20:00Z"
    }
  ],
  "mfa_events": [
    {
      "event_type": "totp_enabled",
      "timestamp": "2024-08-01T16:00:00Z",
      "success": true
    },
    {
      "event_type": "totp_verified",
      "timestamp": "2025-01-15T09:31:00Z",
      "success": true
    },
    {
      "event_type": "recovery_code_used",
      "timestamp": "2024-12-20T11:45:00Z",
      "success": true
    }
  ],
  "passkeys": [
    {
      "id": "passkey-id-xyz",
      "name": "My YubiKey 5",
      "aaguid": "fa2b99dc-9e39-4257-8f92-4a30d23c4118",
      "backup_eligible": false,
      "created_at": "2024-09-15T10:00:00Z",
      "last_used_at": "2025-01-14T08:30:00Z"
    }
  ]
}

Data Categories Exported:

Category Description Fields
User Profile Basic account information user_id, email, created_at
Memberships Organization affiliations organization_id, organization_slug, role, joined_at
Login Events Authentication history timestamp, ip_address, user_agent, provider, risk_score, geo_location
OAuth Identities Linked social accounts provider, provider_user_id, linked_at
MFA Events Multi-factor authentication activity event_type, timestamp, success
Passkeys WebAuthn credentials id, name, aaguid, backup_eligible, created_at, last_used_at

Privacy Notes:

  • Login events are limited to the most recent entries (configurable)
  • Sensitive credentials (password hashes, MFA secrets) are NOT included
  • OAuth access tokens and refresh tokens are NOT included
  • Encrypted data is NOT decrypted for export

Error Responses:

  • 403 Forbidden: User not authorized to export this data
    {
      "error": "You do not have permission to export this user's data"
    }
    
  • 404 Not Found: User does not exist
    {
      "error": "User not found"
    }
    

Use Cases:

User Self-Service Data Export: Users requesting their own data through account settings.

Compliance Audit: Organization owners reviewing what data is stored about their members.

Incident Response: Platform owners investigating security incidents.

Legal Discovery: Responding to legal data requests with comprehensive user data package.


Right to be Forgotten

DELETE /api/privacy/forget/:user_id

Anonymize a user’s personal data in compliance with GDPR Right to be Forgotten. This operation irreversibly removes personally identifiable information (PII) while preserving audit logs and referential integrity.

Permissions:

  • Organization owners can anonymize members of their organization
  • Platform owners can anonymize any user
  • Requires owner permission in ALL organizations where the user is a member

Headers:

Header Value Required
Authorization Bearer {jwt} Yes

Path Parameters:

Parameter Type Description
user_id string User ID to anonymize

Example Request:

curl -X DELETE https://sso.example.com/api/privacy/forget/user-id-123 \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Success Response (200 OK):

{
  "success": true,
  "message": "User data has been anonymized. PII has been removed while preserving audit logs.",
  "user_id": "user-id-123"
}

Anonymization Process:

The following data is anonymized:

Data Type Anonymization Method
Email Replaced with anonymized-{timestamp}@deleted.local
Password Hash Set to NULL
MFA Secret Deleted
MFA Recovery Codes Deleted
OAuth Tokens Deleted (access and refresh tokens)
Passkeys Deleted (WebAuthn credentials)
Sessions Revoked and deleted
Device Trust Tokens Deleted
IP Addresses Replaced with 0.0.0.0 in logs
User Agents Replaced with anonymized in logs

Data Preserved for Compliance:

Data Type Reason
User ID Referential integrity for audit logs
Timestamps Audit trail requirements
Organization Memberships Audit log context
Login Event Counts Aggregate analytics (no PII)
Audit Log Entries Legal and compliance requirements

Restrictions:

Platform Owners Cannot Be Anonymized:

{
  "error": "Platform owners cannot be anonymized"
}

Platform owners must first transfer ownership or be demoted before anonymization.

Requires Owner Permission in All Organizations:

{
  "error": "You must be an owner of organization 'acme-corp' to anonymize this user"
}

If the user is a member of multiple organizations, the requester must be an owner in all of them.

Audit Logging:

All anonymization operations create audit log entries:

{
  "event_type": "user_anonymized",
  "actor_id": "requesting-user-id",
  "target_id": "user-id-123",
  "details": {
    "reason": "GDPR Right to be Forgotten"
  },
  "timestamp": "2025-01-15T14:30:00Z"
}

Irreversibility Warning:

⚠️ This operation cannot be undone. Once a user is anonymized:

  • They cannot login (email and password are destroyed)
  • OAuth connections are severed
  • MFA is disabled
  • Passkeys are deleted
  • All active sessions are terminated

Error Responses:

  • 403 Forbidden: Insufficient permissions
    {
      "error": "You must be an owner of organization 'acme-corp' to anonymize this user"
    }
    
  • 403 Forbidden: Platform owner restriction
    {
      "error": "Platform owners cannot be anonymized"
    }
    
  • 404 Not Found: User does not exist
    {
      "error": "User not found"
    }
    

Use Cases:

GDPR Compliance: Responding to Right to be Forgotten requests from EU users.

Employee Offboarding: Organizations removing ex-employees from their systems.

Account Closure: Users requesting permanent account deletion.

Security Incident Response: Neutralizing compromised accounts while preserving audit trails.


Data Retention Policies

Automatic Deletion

The platform does NOT automatically delete user data. All deletions must be explicitly requested through the API.

Audit Log Retention

Audit logs are retained indefinitely for:

  • Compliance requirements
  • Security investigations
  • Legal obligations

Anonymization preserves audit logs but removes PII from them.

Session Expiration

  • Access Tokens: 15 minutes (900 seconds)
  • Refresh Tokens: 30 days (with activity extension)
  • Device Trust Tokens: 90 days
  • OAuth State Tokens: 15 minutes
  • Magic Link Tokens: 15 minutes

Expired tokens are automatically cleaned up by background jobs.


Privacy-by-Design Features

Data Minimization

The platform only collects data necessary for functionality:

  • No third-party analytics by default
  • No advertising tracking
  • No unnecessary personal information fields
  • Optional fields (phone, address) not collected

Purpose Limitation

Data is only used for its stated purpose:

  • Authentication data for authentication only
  • Audit logs for security and compliance only
  • Contact information for account recovery only

Storage Limitation

Data is deleted when no longer necessary:

  • Expired tokens automatically cleaned up
  • Completed jobs deleted after retention period
  • OAuth states deleted after flow completion

Security by Default

All personal data is protected:

  • Encryption at rest for OAuth tokens
  • Encryption in transit via HTTPS
  • Password hashing with Argon2
  • MFA secrets encrypted

GDPR Compliance Checklist

Organizations using AuthOS can demonstrate GDPR compliance:

  • Right to Access: Users can export their data via /api/privacy/export
  • Right to be Forgotten: Users can request anonymization via /api/privacy/forget
  • Right to Data Portability: Exported data in machine-readable JSON format
  • Right to Rectification: Users can update their profile via user management API
  • Consent Management: OAuth flows require explicit user consent
  • Data Breach Notification: Audit logs enable breach detection and notification
  • Privacy by Design: Minimal data collection, encryption, secure defaults
  • Data Processing Agreements: Platform acts as data processor for organizations

Best Practices

For End Users

  1. Regular Data Review: Export your data periodically to review what’s stored
  2. Minimal Linking: Only link OAuth accounts you actively use
  3. MFA Backup: Save recovery codes before anonymizing an account
  4. Inform Organizations: Notify your organization before requesting anonymization

For Organization Owners

  1. Review Before Anonymization: Export user data before anonymizing for records
  2. Document Requests: Maintain records of privacy requests for compliance
  3. User Communication: Inform users about their privacy rights
  4. Data Audits: Regularly review member data using export functionality

For Platform Owners

  1. Audit Log Retention: Maintain audit logs indefinitely for compliance
  2. Privacy Policy: Keep privacy policy updated and accessible
  3. Incident Response: Use audit logs for breach detection and response
  4. Legal Consultation: Consult legal counsel for complex privacy requests

API Integration Examples

Self-Service Data Export

// User requests their own data
const response = await fetch('https://sso.example.com/api/privacy/export/me', {
  headers: {
    'Authorization': `Bearer ${userToken}`
  }
});

const userData = await response.json();

// Download as JSON file
const blob = new Blob([JSON.stringify(userData, null, 2)], {
  type: 'application/json'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'my-sso-data.json';
a.click();

Organization Member Anonymization

// Organization owner anonymizes a former employee
async function anonymizeFormerEmployee(userId) {
  try {
    const response = await fetch(
      `https://sso.example.com/api/privacy/forget/${userId}`,
      {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${orgOwnerToken}`
        }
      }
    );

    const result = await response.json();

    if (result.success) {
      console.log(`User ${userId} anonymized successfully`);
      // Log to internal compliance system
      await logComplianceAction('user_anonymized', userId);
    }
  } catch (error) {
    console.error('Anonymization failed:', error);
  }
}