An industry-agnostic consent management engine with granular control and complete audit trails.
OpenFGC is an open-source API service that enables developers to implement consent management at any level of granularity β from individual data elements to broad purposes. Designed for scale with complete audit trails and lifecycle management, it provides everything needed to track, validate, and audit user consent across your applications.
| New to the project? | Quick Start |
|---|---|
| Using the API? | API Endpoints |
| Contributing? | Development |
- Features
- Core Concepts
- Technology Stack
- Prerequisites
- Project Structure
- Quick Start
- API Endpoints
- Development
- Flexible Consent Model: Define consent elements (data points), group them into purposes, and track user approvals for any industry or solution
- Complete Consent Lifecycle Management: Create, retrieve, update, revoke, and validate user consents with full status tracking
- Audit Trails: Every status change is recorded for accountability and compliance
- Multi-tenancy: Organization-level data isolation via
org-idheader - Authorization Resources: Track granular authorization status per user per consent
- Attribute Search: Query consents by custom metadata (key or key-value pairs)
- Expiration Handling: Automatic consent expiration with cascading status updates
OpenFGC is built on three core concepts:
βββββββββββββββββββββββββββββ
β Consent Elements β Data points or actions
β (What) β e.g., user_email, location_tracking
βββββββββββββββββββββββββββββ
β β²
1:N β β 1:M
βΌ β
βββββββββββββββββββββββββββββ
β Consent Purposes β Logical groupings of elements
β (Why) β e.g., marketing, analytics
βββββββββββββββββββββββββββββ
β β²
1:N β β 1:M
βΌ β
βββββββββββββββββββββββββββββ
β Consents β User approval record
β (Record) β Links user β purposes β elements
βββββββββββββββββββββββββββββ
The Consent Element is the most granular unit of data or specific activity being consented to.
- Definition: The most granular unitβa specific data point (e.g., email address) or processing action (e.g., sharing with third parties).
The Consent Purpose provides the context and legal justification for the collection.
- Definition: A logical grouping of elements under a single objective. Instead of asking users about each data point, you present the reason for the request (e.g., "Marketing Communications" includes email and phone).
The Consent is the immutable evidence of a userβs decision regarding specific Purposes.
- Definition: The record of a user's decision. Tracks who approved what, when, and maintains the full status lifecycle (Created β Active β Expired/Revoked) with audit trail.
- Go 1.25+
- Web Framework: net/http (standard library) with gorilla/mux style routing
- Database: MySQL 8.0+ or PostgreSQL 14+ (recommended for production; SQLite supported for development only)
- ORM/Data Access: sqlx
- Architecture: Domain-driven layered architecture
- Transaction Management: Atomic operations
- Go 1.25 or higher
- MySQL 8.0+ or PostgreSQL 14+ (recommended for production)
- sqlite3 (optional, if using SQLite)
- Make (optional, for build commands)
openfgc/
βββ api/ # OpenAPI specifications
β βββ consent-management-API.yaml # Consent API spec
βββ consent-server/ # Main application
β βββ cmd/
β β βββ server/
β β βββ main.go # Application entry point
β β βββ servicemanager.go # Service initialization
β βββ internal/
β β βββ authresource/ # Authorization resource module
β β βββ consent/ # Consent module
β β βββ consentelement/ # Consent element module
β β βββ consentpurpose/ # Consent purpose module
β β βββ system/ # Shared system components
β β βββ config/ # Configuration management
β β βββ database/ # Database client & transactions
β β βββ error/ # Error handling
β β βββ healthcheck/ # Health check endpoints
β β βββ log/ # Logging infrastructure
β β βββ middleware/ # HTTP middleware
β β βββ stores/ # Store registry
β β βββ utils/ # Utilities
β βββ dbscripts/
β β βββ db_schema_mysql.sql # Consent tables schema (MySQL)
β β βββ db_schema_postgres.sql # Consent tables schema (PostgreSQL)
β β βββ db_schema_sqlite.sql # Consent tables schema (SQLite)
β β βββ WIP-db_schema_config_mysql.sql # Config tables schema
β βββ docs/ # Internal documentation
βββ tests/
β βββ integration/ # Integration tests
β βββ consent/ # Consent API tests
β βββ consentelement/ # Consent element tests
β βββ consentpurpose/ # Consent purpose tests
β βββ main.go # Test runner
βββ build.sh # Build script
βββ start.sh # Server startup script
βββ target/ # Build output directory (generated)
β βββ server/ # Runnable server artifacts
β βββ dist/ # Distribution packages
βββ version.txt # Version information
MySQL:
# Create database
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS consent_mgt;"
# Import schema
mysql -u root -p consent_mgt < consent-server/dbscripts/db_schema_mysql.sqlPostgreSQL:
# Create database
psql -U postgres -c "CREATE DATABASE consent_mgt;"
# Import schema
psql -U postgres -d consent_mgt -f consent-server/dbscripts/db_schema_postgres.sqlUsing build.sh (Recommended)
# Build the application (binary only)
./build.sh build
# Create distribution package (binary + zip archive)
./build.sh packageBuild artifacts are created in target/server/:
target/server/consent-server(binary)target/server/repository/conf/(config directory)target/server/api/(API specs)target/server/dbscripts/(database scripts)
Update configuration file at target/server/repository/conf/deployment.yaml:
server:
hostname: 0.0.0.0
port: 3000
readTimeout: 30s
writeTimeout: 30s
idleTimeout: 120s
database:
consent:
type: ${OPENFGC_DB_TYPE}
hostname: ${OPENFGC_DB_HOSTNAME}
port: ${OPENFGC_DB_PORT}
database: ${OPENFGC_DB_NAME}
max_open_conns: 25
max_idle_conns: 5
conn_max_lifetime: 5m
user: ${OPENFGC_DB_USER}
password: ${OPENFGC_DB_PASSWORD}
logging:
level: infoFor PostgreSQL, set type: postgres and use the default port 5432:
database:
consent:
type: ${OPENFGC_DB_TYPE}
hostname: ${OPENFGC_DB_HOSTNAME}
port: ${OPENFGC_DB_PORT}
database: ${OPENFGC_DB_NAME}
max_open_conns: 25
max_idle_conns: 5
conn_max_lifetime: 5m
user: ${OPENFGC_DB_USER}
password: ${OPENFGC_DB_PASSWORD}
sslmode: disable # use verify-full for production
options: "" # e.g. sslrootcert=/path/to/ca.crt for production TLSEither change the configuration file directly in deployment.yaml or set the following environment variables before starting the server:
| Variable | Description | Example Values |
|---|---|---|
OPENFGC_DB_TYPE |
Database type | mysql, sqlite, postgres |
OPENFGC_DB_HOSTNAME |
Database hostname | localhost |
OPENFGC_DB_PORT |
Database port | 3306 for MySQL, 5432 for PostgreSQL |
OPENFGC_DB_NAME |
Database name | |
OPENFGC_DB_USER |
Database user | |
OPENFGC_DB_PASSWORD |
Database password |
# Run in normal mode
cd target/server
./start.sh
# Run in debug mode (with remote debugging on port 2345)
./start.sh --debug
# Run in debug mode with custom port
./start.sh --debug --debug-port 3000Server starts at http://localhost:3000
Health check: curl http://localhost:3000/health
Tip: You can import these OpenAPI specifications directly into Postman or similar tools to easily explore and test the API.
All requests require headers:
org-id: Organization identifier
# Navigate to server directory
cd consent-server
# Build binary
go build -o bin/consent-server cmd/server/main.go
# Run
./bin/consent-serverUsing build.sh (Recommended)
# Run unit tests
./build.sh test_unit
# Run integration tests
./build.sh test_integration
# Run all tests
./build.sh testNote: Integration tests use the configuration at
tests/integration/repository/conf/deployment.yaml. If you're using a separate database for testing, ensure it's created and the credentials are updated in this configuration file before running the tests. The test database will be automatically initialized with the required schema.
Manual Execution
# Navigate to test directory
cd tests/integration
# Run all tests
go test ./... -v1. Initialize the database
# Create the database directory
mkdir -p target/server/repository/database
# Initialize the SQLite database with the schema
sqlite3 target/server/repository/database/consent.db < consent-server/dbscripts/db_schema_sqlite.sql2. Update target/server/repository/conf/deployment.yaml
database:
consent:
type: sqlite
# Path to the SQLite database file (relative to the server binary)
path: ./repository/database/consent.db
# Optional DSN query parameters for additional SQLite pragmas
# options: "_pragma=journal_mode(WAL)&_pragma=cache_size(-16000)"
max_open_conns: 25
max_idle_conns: 5
conn_max_lifetime: 5m