Skip to content

VikkramVigneswaranJai/policy-as-code-platform

Repository files navigation

Policy-as-Code Platform

A comprehensive Flask-based authorization system using Open Policy Agent (OPA) for implementing Policy-as-Code principles with Attribute-Based Access Control (ABAC).

🎯 Project Overview

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.

Key Features

β€’ πŸ” 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

πŸ“‹ Table of Contents

πŸš€ Installation

Prerequisites

  • Python 3.8 or higher
  • pip (Python package manager)
  • OPA (Open Policy Agent) - Optional but recommended

Step 1: Clone the Repository

git clone <repository-url>
cd PolicyAsCodePlatform

Step 2: Create Virtual Environment

# Windows
python -m venv venv
venv\Scripts\activate

# Linux/Mac
python3 -m venv venv
source venv/bin/activate

Step 3: Install Dependencies

pip install -r requirements.txt

Step 4: Install OPA (Optional)

Windows

  1. Download OPA from: https://www.openpolicyagent.org/docs/latest/#running-opa
  2. Or use direct link: https://openpolicyagent.org/downloads/latest/opa_windows_amd64.exe
  3. Rename to opa.exe and add to PATH

Linux

curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64
chmod +x opa
sudo mv opa /usr/local/bin/

Mac

brew install opa

Step 5: Initialize Database

python init_db.py

This creates the SQLite database and populates it with sample users and policies.

⚑ Quick Start

Option 1: Integrated Startup (Recommended)

Starts both OPA server and Flask application together:

python start_app.py

Option 2: Manual Startup

Terminal 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

Access the Application

Default Test Credentials

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

πŸ—οΈ Architecture

System Components

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     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          β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Technology Stack

  • 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

Directory Structure

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

πŸ“š API Documentation

Authentication Endpoints

POST /auth/register

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": { ... }
  }
}

POST /auth/login

Authenticate and receive JWT token.

Request Body:

{
  "username": "string",
  "password": "string"
}

Response (200):

{
  "status": "success",
  "data": {
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
    "token_type": "Bearer",
    "user": { ... }
  }
}

GET /auth/profile

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"
    }
  }
}

Policy Endpoints

POST /policy/evaluate

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"
  }
}

Audit Endpoints

GET /audit/logs

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)

πŸ”’ Policy Examples

Example 1: Admin Full Access

allow if {
    input.user.role == "admin"
}

Example 2: Manager Office Hours

allow if {
    input.user.role == "manager"
    input.environment.hour >= 9
    input.environment.hour < 18
    input.action in ["read", "write"]
}

Example 3: Employee Department Access

allow if {
    input.user.role == "employee"
    input.action == "read"
    input.user.department == input.resource.department
}

πŸ§ͺ Testing

Run All Tests

python -m pytest test_app.py -v

Run Specific Test Class

python -m pytest test_app.py::TestAuthEndpoints -v

Test Coverage

The 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

🌐 Deployment

Production Considerations

  1. Environment Variables: Set production secrets

    export SECRET_KEY="your-secret-key"
    export JWT_SECRET_KEY="your-jwt-secret"
    export FLASK_ENV="production"
  2. Database: Use PostgreSQL or MySQL instead of SQLite

    SQLALCHEMY_DATABASE_URI = "postgresql://user:pass@localhost/dbname"
  3. OPA Server: Deploy OPA as a separate service

    opa run --server --addr 0.0.0.0:8181 /path/to/policies
  4. WSGI Server: Use Gunicorn or uWSGI

    gunicorn -w 4 -b 0.0.0.0:5000 run:app

πŸ”§ Troubleshooting

OPA Server Not Starting

Problem: OPA executable not found

Solution:

  • Ensure OPA is installed and in PATH
  • Or use local fallback mode (application works without OPA)

Database Errors

Problem: Database locked or permission errors

Solution:

# Delete and recreate database
rm pac_platform.db
python init_db.py

Port Already in Use

Problem: 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 -9

Login Not Working

Problem: Token not being stored

Solution:

  • Check browser console for errors
  • Ensure JavaScript is enabled
  • Clear browser localStorage
  • Try incognito/private mode

πŸ“ Configuration

Environment Variables

  • 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 key
  • JWT_SECRET_KEY: JWT signing key
  • OPA_SERVER_URL: OPA server URL (default: http://localhost:8181)
  • DATABASE_URL: Database connection string

Configuration Files

  • config.py: Main configuration
  • .env: Environment variables (create from .env.example)

🀝 Contributing

This is an academic project. For improvements:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

πŸ“„ License

This project is created for academic purposes.

πŸ‘₯ Authors

  • Academic Project - Policy-as-Code Platform
  • Vikkram Vigneswaran KJ
  • Velmurugan A
  • Velsabarinaath B
  • Sri haran R

πŸ™ Acknowledgments

  • Open Policy Agent (OPA) team
  • Flask framework contributors
  • Tailwind CSS team

πŸ“ž Support

For issues or questions:

  • Check the troubleshooting section
  • Review the API documentation
  • Run the test suite to verify setup

Mail To-


Built with ❀️ using Flask, OPA, and modern web technologies

About

"A secure Policy-as-Code platform leveraging Flask and Open Policy Agent (OPA) to enforce scalable, real-time authorization decisions using externalized policies."

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors