Minimal Python platform for DPDP Act 2023 compliance with consent management, audit trails, and API key authentication.
- ✅ Consent Collection - Record user consent with purpose specification
- ✅ Consent Withdrawal - Easy withdrawal mechanism with audit logging
- ✅ Audit Trail - Immutable logs for compliance verification
- ✅ API Key Authentication - Secure endpoints with configurable API keys
- ✅ Input Validation - Prevents empty/malicious data
- ✅ Pagination - Efficient data retrieval with limits
- ✅ Transaction Safety - Automatic rollback on errors
- ✅ Timezone-aware Timestamps - UTC timestamps for all records
- ✅ Configurable Database - SQLite default, supports PostgreSQL/MySQL
- ✅ Prevents Double-withdrawal - Validates consent state before withdrawal
- FastAPI - Modern async web framework
- SQLAlchemy 2.0 - ORM with modern patterns
- Pydantic 2.x - Data validation
- SQLite - Default database (configurable)
# Install dependencies
pip install -r requirements.txt
# Set environment variables
export API_KEY="your-secret-api-key"
export DATABASE_URL="sqlite:///dpdp_consent.db" # optionaluvicorn main:app --reload- API: http://localhost:8000
- Interactive Docs: http://localhost:8000/docs
- OpenAPI Schema: http://localhost:8000/openapi.json
All endpoints require API key in header:
X-API-Key: your-secret-api-keyPOST /consentRecords user consent for a specific purpose.
Request:
{
"user_id": "user123",
"purpose": "marketing",
"metadata": "optional additional info"
}Response:
{
"id": "consent-uuid",
"user_id": "user123",
"purpose": "marketing",
"granted": true,
"granted_at": "2026-03-08T10:30:00Z",
"withdrawn_at": null
}GET /consent/{user_id}?limit=100&offset=0Retrieves all consents for a user (paginated, ordered by newest first).
Query Parameters:
limit- Max records (default: 100, max: 1000)offset- Skip records (default: 0)
POST /consent/withdrawWithdraws a specific consent.
Request:
{
"user_id": "user123",
"consent_id": "consent-uuid"
}Response:
{
"message": "Consent withdrawn successfully"
}GET /audit/{user_id}?limit=100&offset=0Retrieves audit trail for a user (paginated, ordered by newest first).
Query Parameters:
limit- Max records (default: 100, max: 1000)offset- Skip records (default: 0)
# Grant consent
curl -X POST "http://localhost:8000/consent" \
-H "X-API-Key: your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "purpose": "marketing"}'
# Get user consents
curl -X GET "http://localhost:8000/consent/user123" \
-H "X-API-Key: your-secret-api-key"
# Withdraw consent
curl -X POST "http://localhost:8000/consent/withdraw" \
-H "X-API-Key: your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "consent_id": "consent-uuid"}'
# Get audit logs
curl -X GET "http://localhost:8000/audit/user123" \
-H "X-API-Key: your-secret-api-key"id- Unique consent identifier (UUID)user_id- User identifier (indexed)purpose- Purpose of data processinggranted- Consent status (boolean)granted_at- Timestamp when consent was grantedwithdrawn_at- Timestamp when consent was withdrawn (nullable)metadata- Additional information (optional)
id- Unique log identifier (UUID)user_id- User identifier (indexed)action- Action performed (CONSENT_GRANTED, CONSENT_WITHDRAWN)timestamp- When action occurreddetails- Additional details about the action
API_KEY- API key for authentication (required in production)DATABASE_URL- Database connection string (default:sqlite:///dpdp_consent.db)
SQLite (default):
export DATABASE_URL="sqlite:///dpdp_consent.db"PostgreSQL:
export DATABASE_URL="postgresql://user:password@localhost/dpdp_db"MySQL:
export DATABASE_URL="mysql+pymysql://user:password@localhost/dpdp_db"This platform implements core requirements of India's Digital Personal Data Protection Act:
- ✅ Section 6 - Consent collection with clear purpose specification
- ✅ Section 7 - Easy withdrawal mechanism
- ✅ Section 8 - Audit trail for compliance verification
⚠️ Partial - Data retention policies (implement as needed)⚠️ Partial - Right to data portability (add export endpoint)
-
Set strong API key:
export API_KEY="$(openssl rand -hex 32)"
-
Use production database:
export DATABASE_URL="postgresql://user:password@db-host/dpdp_db"
-
Run with production server:
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
-
Add HTTPS - Use reverse proxy (nginx/traefik) with TLS
-
Optional enhancements:
- Rate limiting (slowapi, fastapi-limiter)
- Logging/monitoring (structlog, prometheus)
- Consent expiry dates
- Data export endpoint
- Change default API key in production
- Use HTTPS in production
- Rotate API keys regularly
- Monitor audit logs for suspicious activity
- Consider adding rate limiting for public APIs
MIT