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
| Interface | Purpose |
|---|---|
Plugin | Base plugin identity ("consent") |
OnInit | Captures hooks, relay, chronicle, logger, and base path from the engine |
RouteProvider | Registers consent grant, revoke, and list endpoints |
MigrationProvider | Contributes the consents table |
DataExportContributor | Exports all consent records for GDPR data requests |
Consent types and purposes
Consent purposes are free-form strings that represent what the user is consenting to. Common purposes include:
| Purpose | Description |
|---|---|
essential | Required cookies and functionality |
analytics | Analytics and performance tracking |
marketing | Marketing communications and targeted advertising |
personalization | Personalized content and recommendations |
third_party | Sharing data with third-party services |
You define purposes based on your application's needs. The plugin does not enforce a fixed set of purposes.
Recording consent
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, orRemoteAddr) - Timestamp -- When consent was granted
Consent withdrawal
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.
Listing consent records
GET /v1/auth/consent
Query parameters:
| Parameter | Type | Description |
|---|---|---|
purpose | string | Filter by consent purpose |
cursor | string | Pagination cursor |
limit | int | Results 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..."
}Consent audit trail
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.
Cookie consent integration
The consent plugin can be used with a frontend cookie consent banner:
- The frontend displays a cookie consent banner on first visit
- When the user makes their choices, the frontend calls
POST /v1/auth/consent/grantfor each accepted purpose - The frontend stores a local flag to suppress the banner on subsequent visits
- When the user changes preferences, call
POST /v1/auth/consent/revokefor withdrawn purposes andPOST /v1/auth/consent/grantfor newly accepted ones
API routes
| Method | Path | Description |
|---|---|---|
POST | /v1/auth/consent/grant | Record consent for a purpose |
POST | /v1/auth/consent/revoke | Withdraw consent for a purpose |
GET | /v1/auth/consent | List consent records for the authenticated user |
All endpoints require authentication (Authorization: Bearer header).