A comprehensive Flask-based authorization system using Open Policy Agent (OPA) for implementing Policy-as-Code principles with Attribute-Based Access Control (ABAC).
This platform demonstrates modern authorization patterns using declarative policies written in Rego. It provides a complete web application with user management, policy evaluation, and comprehensive audit logging.
β’ π Authentication & Authorization**: JWT-based authentication with OPA policy evaluation β’ π₯ User Management**: Complete user registration, login, and profile management β’ π Policy Management**: Create, update, and manage Rego policies through web interface β’ π Audit Logging**: Comprehensive logging of all authorization decisions β’ β° Time-Based Access Control**: Policies that consider time of day and day of week β’ π’ Department-Based Access**: ABAC policies based on user and resource departments β’ π¨ Modern UI**: Beautiful, responsive interface built with Tailwind CSS β’ π§ͺ Comprehensive Testing**: Full test suite covering all endpoints and edge cases
- Installation
- Quick Start
- Architecture
- API Documentation
- Policy Examples
- Testing
- Deployment
- Troubleshooting
- Python 3.8 or higher
- pip (Python package manager)
- OPA (Open Policy Agent) - Optional but recommended
git clone <repository-url>
cd PolicyAsCodePlatform# Windows
python -m venv venv
venv\Scripts\activate
# Linux/Mac
python3 -m venv venv
source venv/bin/activatepip install -r requirements.txt- Download OPA from: https://www.openpolicyagent.org/docs/latest/#running-opa
- Or use direct link: https://openpolicyagent.org/downloads/latest/opa_windows_amd64.exe
- Rename to
opa.exeand add to PATH
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
chmod +x opa
sudo mv opa /usr/local/bin/brew install opapython init_db.pyThis creates the SQLite database and populates it with sample users and policies.
Starts both OPA server and Flask application together:
python start_app.pyTerminal 1 - Start OPA Server:
python start_opa.py
# Or manually:
opa run --server --addr localhost:8181 opa_policies/Terminal 2 - Start Flask Application:
python run.py- Web Interface: http://localhost:5000
- Dashboard: http://localhost:5000/dashboard
- Login: http://localhost:5000/login
- Register: http://localhost:5000/register
- API Docs: http://localhost:5000/api-docs
- OPA Server: http://localhost:8181 (if running)
| Username | Password | Role | Department |
|---|---|---|---|
| admin | admin123 | admin | management |
| manager | manager123 | manager | engineering |
| employee | employee123 | employee | engineering |
| hr_manager | hr123 | manager | hr |
| finance_employee | finance123 | employee | finance |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web Browser (Client) β
βββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β HTTP/HTTPS
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Flask Application β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Auth Routes β βPolicy Routes β β Audit Routes β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β OPA Client Module β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββ βββββββββββββββββββββββββ
β SQLite Database β β OPA Server β
β - Users β β - Policy Engine β
β - Policies β β - Rego Policies β
β - Audit Logs β β - REST API β
βββββββββββββββββββββ βββββββββββββββββββββββββ
- Backend: Flask 2.3.3
- Database: SQLite with SQLAlchemy ORM
- Authentication: JWT (Flask-JWT-Extended)
- Policy Engine: Open Policy Agent (OPA)
- Policy Language: Rego
- Frontend: HTML5, Tailwind CSS, Vanilla JavaScript
- Testing: pytest
PolicyAsCodePlatform/
βββ app/
β βββ __init__.py # Application factory
β βββ models.py # Database models
β βββ opa_client.py # OPA integration
β βββ routes.py # Main routes
β βββ auth/
β β βββ routes.py # Authentication endpoints
β βββ policy/
β β βββ routes.py # Policy management endpoints
β βββ resources/
β β βββ routes.py # Resource access endpoints
β βββ audit/
β β βββ routes.py # Audit log endpoints
β βββ templates/ # HTML templates
β βββ base.html
β βββ login.html
β βββ register.html
β βββ dashboard.html
β βββ ...
βββ opa_policies/
β βββ authz.rego # Main authorization policy
β βββ rbac.rego # Role-based access control
β βββ time_based.rego # Time-based policies
β βββ department.rego # Department-based policies
βββ config.py # Configuration settings
βββ run.py # Application entry point
βββ start_app.py # Integrated startup script
βββ start_opa.py # OPA startup script
βββ init_db.py # Database initialization
βββ test_app.py # Comprehensive test suite
βββ requirements.txt # Python dependencies
βββ README.md # This file
Register a new user account.
Request Body:
{
"username": "string",
"email": "string",
"password": "string",
"role": "admin|manager|employee",
"department": "string",
"designation": "string (optional)"
}Response (201):
{
"status": "success",
"message": "User registered successfully",
"data": {
"user": { ... }
}
}Authenticate and receive JWT token.
Request Body:
{
"username": "string",
"password": "string"
}Response (200):
{
"status": "success",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "Bearer",
"user": { ... }
}
}Get current user profile (requires authentication).
Headers:
Authorization: Bearer <token>
Response (200):
{
"status": "success",
"data": {
"user": {
"id": 1,
"username": "admin",
"email": "[email protected]",
"role": "admin",
"department": "management"
}
}
}Evaluate a policy decision.
Headers:
Authorization: Bearer <token>
Request Body:
{
"action": "read|write|delete",
"resource": {
"type": "document|report|settings",
"department": "string",
"id": "string (optional)"
},
"environment": {
"hour": 14,
"day": "Monday"
}
}Response (200):
{
"status": "success",
"data": {
"allow": true,
"reason": "Admin has full access to all resources"
}
}Retrieve audit logs (admin only).
Query Parameters:
page: Page number (default: 1)per_page: Items per page (default: 20)decision: Filter by decision (allow/deny)action: Filter by action (read/write/delete)
allow if {
input.user.role == "admin"
}allow if {
input.user.role == "manager"
input.environment.hour >= 9
input.environment.hour < 18
input.action in ["read", "write"]
}allow if {
input.user.role == "employee"
input.action == "read"
input.user.department == input.resource.department
}python -m pytest test_app.py -vpython -m pytest test_app.py::TestAuthEndpoints -vThe test suite covers:
- β User registration (success, duplicates, validation)
- β User login (success, invalid credentials)
- β JWT token handling
- β Policy evaluation (all roles and scenarios)
- β Time-based access control
- β Department-based access control
- β Audit logging
- β Edge cases (SQL injection, XSS, malformed input)
- β Error handling
-
Environment Variables: Set production secrets
export SECRET_KEY="your-secret-key" export JWT_SECRET_KEY="your-jwt-secret" export FLASK_ENV="production"
-
Database: Use PostgreSQL or MySQL instead of SQLite
SQLALCHEMY_DATABASE_URI = "postgresql://user:pass@localhost/dbname"
-
OPA Server: Deploy OPA as a separate service
opa run --server --addr 0.0.0.0:8181 /path/to/policies
-
WSGI Server: Use Gunicorn or uWSGI
gunicorn -w 4 -b 0.0.0.0:5000 run:app
Problem: OPA executable not found
Solution:
- Ensure OPA is installed and in PATH
- Or use local fallback mode (application works without OPA)
Problem: Database locked or permission errors
Solution:
# Delete and recreate database
rm pac_platform.db
python init_db.pyProblem: Port 5000 or 8181 already in use
Solution:
# Change Flask port
export FLASK_PORT=8000
python run.py
# Or kill existing process
# Windows
netstat -ano | findstr :5000
taskkill /PID <PID> /F
# Linux/Mac
lsof -ti:5000 | xargs kill -9Problem: Token not being stored
Solution:
- Check browser console for errors
- Ensure JavaScript is enabled
- Clear browser localStorage
- Try incognito/private mode
FLASK_ENV: Environment (development/production/testing)FLASK_DEBUG: Enable debug mode (True/False)FLASK_HOST: Host address (default: 0.0.0.0)FLASK_PORT: Port number (default: 5000)SECRET_KEY: Flask secret keyJWT_SECRET_KEY: JWT signing keyOPA_SERVER_URL: OPA server URL (default: http://localhost:8181)DATABASE_URL: Database connection string
config.py: Main configuration.env: Environment variables (create from.env.example)
This is an academic project. For improvements:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
This project is created for academic purposes.
- Academic Project - Policy-as-Code Platform
- Vikkram Vigneswaran KJ
- Velmurugan A
- Velsabarinaath B
- Sri haran R
- Open Policy Agent (OPA) team
- Flask framework contributors
- Tailwind CSS team
For issues or questions:
- Check the troubleshooting section
- Review the API documentation
- Run the test suite to verify setup
- Vikkram Vigneswaran - [email protected]
Built with β€οΈ using Flask, OPA, and modern web technologies