Authsome

Consent Plugin

GDPR-compliant consent management with grant, revoke, audit trail, and data export.

The consent plugin provides GDPR-compliant consent tracking for Authsome. It records user consent for specific purposes (marketing, analytics, essential cookies), supports consent withdrawal, maintains a full audit trail, and contributes consent records to GDPR data exports.

Setup

import (
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/plugins/consent"
)

eng, err := authsome.NewEngine(
    authsome.WithStore(store),
    authsome.WithPlugin(consent.New()),
)

To use a persistent consent store instead of the default in-memory store:

authsome.WithPlugin(consent.New(consentPostgresStore))

Implemented interfaces

InterfacePurpose
PluginBase plugin identity ("consent")
OnInitCaptures hooks, relay, chronicle, logger, and base path from the engine
RouteProviderRegisters consent grant, revoke, and list endpoints
MigrationProviderContributes the consents table
DataExportContributorExports all consent records for GDPR data requests

Consent purposes are free-form strings that represent what the user is consenting to. Common purposes include:

PurposeDescription
essentialRequired cookies and functionality
analyticsAnalytics and performance tracking
marketingMarketing communications and targeted advertising
personalizationPersonalized content and recommendations
third_partySharing data with third-party services

You define purposes based on your application's needs. The plugin does not enforce a fixed set of purposes.

POST /v1/auth/consent/grant

{
  "purpose": "marketing",
  "version": "v2.1",
  "app_id": "aapp_01j9..."
}

Response:

{
  "id": "acon_01j9...",
  "user_id": "ausr_01j9...",
  "app_id": "aapp_01j9...",
  "purpose": "marketing",
  "granted": true,
  "version": "v2.1",
  "ip_address": "192.168.1.1",
  "granted_at": "2024-11-01T10:00:00Z",
  "created_at": "2024-11-01T10:00:00Z"
}

Each consent record captures:

  • Purpose -- What the user is consenting to
  • Version -- The policy version this consent applies to (for tracking policy changes)
  • IP address -- The client IP at the time of consent (from X-Forwarded-For, X-Real-IP, or RemoteAddr)
  • Timestamp -- When consent was granted

POST /v1/auth/consent/revoke

{
  "purpose": "marketing",
  "app_id": "aapp_01j9..."
}

Response:

{"status": "revoked"}

Revoking consent marks the record as withdrawn. The original consent record is preserved for audit purposes.

GET /v1/auth/consent

Query parameters:

ParameterTypeDescription
purposestringFilter by consent purpose
cursorstringPagination cursor
limitintResults per page (default 50, max 200)

Response:

{
  "consents": [
    {
      "id": "acon_01j9...",
      "purpose": "marketing",
      "granted": true,
      "version": "v2.1",
      "granted_at": "2024-11-01T10:00:00Z"
    },
    {
      "id": "acon_01j9...",
      "purpose": "analytics",
      "granted": false,
      "version": "v2.0",
      "granted_at": "2024-10-15T08:00:00Z"
    }
  ],
  "next_cursor": "eyJpZCI6..."
}

Every consent operation is recorded through multiple observability channels:

  • Chronicle -- Audit events with action, resource, actor, and metadata
  • Relay -- Webhook events for external systems (consent.granted, consent.revoked)
  • Hook bus -- Internal hook events for other plugins to react to consent changes

GDPR data export

The plugin implements DataExportContributor to include all consent records in user data exports:

func (p *Plugin) ExportUserData(ctx context.Context, userID id.UserID) (string, any, error) {
    consents, _, err := p.store.ListConsents(ctx, &Query{
        UserID: userID,
        Limit:  1000,
    })
    return "consents", consents, err
}

When the engine processes a GDPR data export request, consent records are included under the "consents" key.

The consent plugin can be used with a frontend cookie consent banner:

  1. The frontend displays a cookie consent banner on first visit
  2. When the user makes their choices, the frontend calls POST /v1/auth/consent/grant for each accepted purpose
  3. The frontend stores a local flag to suppress the banner on subsequent visits
  4. When the user changes preferences, call POST /v1/auth/consent/revoke for withdrawn purposes and POST /v1/auth/consent/grant for newly accepted ones

API routes

MethodPathDescription
POST/v1/auth/consent/grantRecord consent for a purpose
POST/v1/auth/consent/revokeWithdraw consent for a purpose
GET/v1/auth/consentList consent records for the authenticated user

All endpoints require authentication (Authorization: Bearer header).

On this page