README
¶
Policy Decision Point (PDP)
Authorization service using Open Policy Agent (OPA) that evaluates data access requests and determines consent requirements.
Overview
The PDP provides attribute-based access control (ABAC) with field-level permissions. It uses Open Policy Agent (OPA) v1 with Rego v1 policies and stores policy metadata in PostgreSQL for real-time evaluation.
Technology: Go + Open Policy Agent (OPA) v1 + Rego v1 + PostgreSQL
Port: 8082
Features
- Real-time Policy Evaluation - Policies loaded from database on startup
- Field-level Access Control - Granular permissions for individual data fields
- Consent Management - Automatic consent requirement calculation
- Allow List Management - Dynamic application authorization for restricted fields
- OPA v1 Integration - Modern Open Policy Agent with Rego v1 syntax
- Database-driven - Policy metadata stored in PostgreSQL
Quick Start
Prerequisites
- Go 1.26+
- PostgreSQL 13+
Run the Service
# Copy environment template
cp cmd/pdp/.env.example cmd/pdp/.env
# Edit .env with your database configuration
# DB_HOST=localhost
# DB_PORT=5432
# DB_USERNAME=postgres
# DB_PASSWORD=password
# DB_NAME=pdp
# Run locally (from the repo root)
go run ./cmd/pdp
# Or build and run
go build -o pdp ./cmd/pdp && ./pdp
The service runs on port 8082 by default.
Configuration
Environment Variables
All configuration is done via environment variables. See .env.example for a complete list.
| Variable | Description | Default |
|---|---|---|
PORT |
Service port | 8082 |
ENVIRONMENT |
production or local |
local |
IDP_ORG_NAME |
IDP organization name | - |
IDP_ISSUER |
JWT issuer URL | - |
IDP_AUDIENCE |
JWT audience | - |
IDP_JWKS_URL |
JWKS endpoint URL | - |
DB_HOST |
Database host | localhost |
DB_PORT |
Database port | 5432 |
DB_USERNAME |
Database username | postgres |
DB_PASSWORD |
Database password | - |
DB_NAME |
Database name | pdp |
DB_SSLMODE |
SSL mode | require |
Optional:
RUN_MIGRATION=false # Set to "true" to run migrations on startup
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/v1/policy/decide |
POST | Authorization decision |
/api/v1/policy/metadata |
POST | Create policy metadata for fields |
/api/v1/policy/update-allowlist |
POST | Update allow list for applications |
/health |
GET | Health check |
/debug |
GET | Debug information |
/debug/db |
GET | Database connection status |
Authorization Request
Endpoint: POST /api/v1/policy/decide
Request:
{
"applicationId": "passport-app",
"requiredFields": [
{
"fieldName": "person.fullName",
"schemaId": "schema-123"
},
{
"fieldName": "person.photo",
"schemaId": "schema-123"
}
]
}
Response:
{
"appAuthorized": true,
"unauthorizedFields": [],
"appAccessExpired": false,
"expiredFields": [],
"appRequiresOwnerConsent": true,
"consentRequiredFields": [
{
"fieldName": "person.photo",
"schemaId": "schema-123",
"displayName": "Photo",
"description": "Person's photo"
}
]
}
Policy Metadata Management
Create Policy Metadata: POST /api/v1/policy/metadata
{
"schema_id": "schema-123",
"records": [
{
"field_name": "person.fullName",
"display_name": "Full Name",
"access_control_type": "public"
}
]
}
Update Allow List: POST /api/v1/policy/update-allowlist
{
"application_id": "passport-app",
"records": [
{
"field_name": "person.fullName",
"schema_id": "schema-123"
}
],
"grant_duration": "ONE_MONTH"
}
Access Control Logic
Field Types
-
Public Fields (
access_control_type: "public")- Any app can access
- Consent required only if
consent_required: true
-
Restricted Fields (
access_control_type: "restricted")- Only apps in
allow_listcan access - Consent required if
consent_required: true
- Only apps in
Decision Logic
- Allow: All requested fields are authorized for the app
- Deny: Any requested field is not authorized for the app
- Consent Required: Any requested field has
consent_required: true
Consent Logic
Consent requirement is calculated as: !is_owner && access_control_type != "public"
- Owner Fields (
is_owner: true): No consent required - Public Fields: No consent required for non-owners
- Restricted Fields: Consent required for non-owners
Testing
# From the repo root
go test ./cmd/pdp/... ./internal/pdp/... -count=1
# Run with coverage
go test ./cmd/pdp/... ./internal/pdp/... -cover
# Test authorization scenarios
curl -X POST http://localhost:8082/api/v1/policy/decide \
-H "Content-Type: application/json" \
-d '{
"applicationId": "passport-app",
"requiredFields": [
{
"fieldName": "person.fullName",
"schemaId": "schema-123"
}
]
}'
Architecture
Database Schema
policy_metadata Table:
id(UUID) - Primary keyschema_id(TEXT) - Schema identifierfield_name(TEXT) - Data field namedisplay_name(TEXT) - Human-readable nameaccess_control_type(ENUM) - public/restrictedis_owner(BOOLEAN) - Field ownership flagallow_list(JSONB) - Authorized applications with expirationcreated_at,updated_at(TIMESTAMP)
Policy Evaluation Flow
Request → Load Policy Metadata → OPA Evaluation → Consent Check → Decision
Health Check
curl http://localhost:8082/health
Response:
{
"service": "policy-decision-point",
"status": "healthy"
}
Documentation
¶
There is no documentation for this package.