← Back to list

Cerberus: A Secure Access Request Management System with Go, GraphQL, OPA, and AWS S3

Tushardhama · 2026-06-07 18:52 · 0 claps · 5.2 min read
#golang #system-design-interview #graphql #authorization #open-policy-agent
Open on Medium ↗
Wiki topics: AGT · AI Agents BIZ · Business Strategy LIT · Literature & Writing ☁️ · DevOps & Cloud

Building Cerberus: A Secure Access Request Management System with Go, GraphQL, OPA, and AWS S3

Why the Name “Cerberus”?

Cerberus is inspired by Greek mythology.

In Greek mythology, Cerberus was the multi-headed guardian dog that protected the gates of the underworld and controlled who could enter and leave.

I chose this name because the project is all about controlling access to protected resources.

Just as Cerberus guarded access in mythology, this application manages who can request access, who can approve it, and who is authorized to perform sensitive actions.

The name perfectly matches the purpose of the system: Access Management and Authorization.

The Problem I Wanted to Solve

In many organizations, employees need temporary access to internal systems, databases, dashboards, or production environments.

Without a proper system:

  • Requests are handled through emails or chat messages.
  • There is no approval workflow.
  • Access decisions are difficult to track.
  • Security audits become challenging.
  • No centralized authorization exists.

To solve this problem, I built Cerberus.

Cerberus provides:

  • User authentication
  • Access request creation
  • Screenshot uploads
  • Approval workflows
  • Audit logging
  • Centralized authorization through Open Policy Agent (OPA)

High-Level Architecture

The architecture follows a layered design where each layer has a specific responsibility.

  Frontend Client
       |
       v
   GraphQL API
       |
       v
    Resolvers
       |
       v
    Services
       |
       v
 OPA Authorization
       |
       v
   Repositories
       |
       v
    Ent ORM
       |
       v
     MySQL

This separation keeps the codebase clean, testable, and scalable.

Complete System Architecture

The actual request flow inside Cerberus looks like this:

Client / Frontend
        |
        | HTTP POST /query
        | Authorization: Bearer <JWT>
        v
+------------------------------------------------------------------+
|                           Gin HTTP Server                        |      |                                                                  |                                                                   |                                                                  |
|  CORS Middleware                                                 |     |                                                                  |
|  Recovery Middleware                                             |     |                                                                  |
|  JWT Authentication Middleware                                   |      |                                                                  |                                                                      |                                                                  |
|  Routes                                                          |     |                                                                  |
|  POST /query                                                     |     |                                                                  |
|  GET /playground                                                 |     |                                                                  |
|  GET /health                                                     |     |                                                                  |
|                                                                  |                                                                      
+------------------------------------------------------------------+
                                |
                                v
+------------------------------------------------------------------+
|                         GraphQL (gqlgen)                         |  |                                                                  |
|                                                                  |     |                                                                  |
| Queries                                                          |     |                                                                  |
| - me                                                             |     
| - users                                                          |
| - accessRequest                                                  |   
| - accessRequests                                                 |     
| - auditLogs                                                      |                                                                         |                                                                  |
| Mutations                                                        |     |                                                                  |
| - register                                                       |     
| - login                                                          |     
| - createAccessRequest                                            |     
| - uploadScreenshot                                               |     
| - approveRequest                                                 |     
| - rejectRequest                                                  |     
| - markUnderReview                                                |     
| - updateUserRole                                                 |     
+------------------------------------------------------------------+
                                |
                                v
+------------------------------------------------------------------+
|                         Resolver Layer                           |     |                                                                  |
+------------------------------------------------------------------+
                                |
                                v
+------------------------------------------------------------------+
|                         Service Layer                            |                                                                          |                                                                  |
| AuthService                                                      |     |                                                                  |
| AccessRequestService                                             |                                                                          |                                                                  |
| Business Rules                                                   |     |                                                                  |
| Workflow Management                                              |     |                                                                  |
| Audit Logging                                                    |     |                                                                  |
| Authorization Calls                                              |     |                                                                  |
+------------------------------------------------------------------+
                                |
                +---------------+----------------+
                |                                |
                v                                v
             OPA Client                        Repository Layer
                |                                |
                v                                v
          Open Policy Agent                    Ent ORM
                |                                |
                v                                v
            user.rego                        MySQL Database
            role.rego
           approval.rego
                |
                v
            Authorization
             Decision
                |
                v
           AWS S3 Bucket
         (Screenshot Storage)

Why I Chose This Architecture

When building backend applications, one common mistake is putting everything inside handlers or controllers.

As the project grows, the code becomes difficult to maintain.

I wanted a structure where:

  • GraphQL handles API communication.
  • Resolvers remain thin.
  • Services contain business logic.
  • Repositories handle database operations.
  • OPA handles authorization.
  • AWS S3 handles file storage.

Each component has a single responsibility.

This makes the project easier to test, debug, and scale.

Project Structure

To keep the codebase maintainable, I followed a layered architecture where each component has a single responsibility.

  • GraphQL handles API communication
  • Resolvers handle request mapping
  • Services contain business logic
  • OPA handles authorization
  • Repositories handle database operations
  • Ent ORM manages data access
  • AWS S3 stores screenshots

The screenshot below shows the actual project structure used in Cerberus.

The Most Important Decision: OPA Authorization

One of the biggest improvements I made was introducing Open Policy Agent (OPA).

Initially, authorization checks looked like this:

if role != "ADMIN" {
    return forbidden
}

This works for small applications but becomes difficult to maintain as permissions grow. Instead, I moved authorization logic into OPA policies.

Now the backend asks OPA:

Can this user perform this action?

OPA evaluates policies and returns:

ALLOW

or

DENY

This keeps authorization centralized and independent of application code.

Enterprise Roles and Departments

Another important design decision was separating Roles and Departments.

Roles

  • EMPLOYEE
  • APPROVER
  • MANAGER
  • ADMIN
  • SUPER_ADMIN

Roles define permissions.

Departments

  • ENGINEERING
  • SUPPORT
  • FINANCE
  • HR
  • SALES

Departments define organizational ownership.

For example:

Role       = APPROVER
Department = ENGINEERING

This user can approve Engineering requests but cannot approve Finance requests.

This model is much more flexible than treating departments as roles.

Approval Workflow

The request approval process follows a structured workflow.

  1. Employee creates an access request.
  2. Request is stored with PENDING status.
  3. Audit log entry is created.
  4. Employee uploads supporting screenshots.
  5. Screenshot is stored in AWS S3.
  6. Manager or Approver reviews the request.
  7. OPA evaluates authorization policies.
  8. Request is approved, rejected, or marked under review.
  9. Another audit log entry is created.
           Employee
              |
              | Create Request
              v
    +----------------------+
    | Access Request       |
    | Status = PENDING     |
    +----------------------+
              |
              | Upload Screenshot
              v
    +----------------------+
    | AWS S3 Storage       |
    +----------------------+
              |
              | Review Request
              v
    +----------------------+
    | Manager / Approver   |
    +----------------------+
              |
              | Authorization
              v
    +----------------------+
    | Open Policy Agent    |
    | (OPA)                |
    +----------------------+
              |
    +----------+----------+
    |                     |
    v                     v
 APPROVED           REJECTED
    |                     |
    +----------+----------+
              |
              v
    +----------------------+
    | Audit Log Created    |
    +----------------------+
              |
              v
    +----------------------+
    | GraphQL Response     |
    +----------------------+

This workflow ensures every action is traceable and authorized.

AWS S3 for File Storage

Screenshots uploaded by users are not stored directly in the database.

Instead, files are uploaded to AWS S3 and only the generated URL is stored in MySQL.

Benefits:

  • Reduced database size
  • Better scalability
  • Easier file management
  • Secure cloud storage

This approach keeps the application lightweight while supporting large file uploads.

Audit Logging

One of the most important features of Cerberus is audit logging. Every security-sensitive action is recorded in the audit_logs table.

Examples include:

  • REQUEST_CREATED
  • REQUEST_APPROVED
  • REQUEST_REJECTED
  • REQUEST_UNDER_REVIEW
  • SCREENSHOT_UPLOADED
  • USER_ROLE_CHANGED

Each audit record stores:

  • Action
  • Actor Email
  • Actor Role
  • Metadata
  • Timestamp
  • Request ID

This provides complete visibility into request lifecycle events and helps during debugging, compliance reviews, and security investigations.

The screenshot below shows actual audit records generated during testing.

Security Measures

Security was a major focus while building Cerberus.

The application includes:

  • Password hashing using bcrypt
  • JWT-based authentication
  • OPA-based authorization
  • Role-Based Access Control (RBAC)
  • Department-Based Access Control (DBAC)
  • Audit logging
  • GraphQL query complexity limits
  • Production GraphQL hardening

These features help ensure that access is controlled, actions are auditable, and sensitive operations remain secure.

What I Learned

Building Cerberus taught me several important engineering concepts:

  • GraphQL API design with gqlgen
  • Clean layered architecture
  • JWT authentication
  • Open Policy Agent integration
  • AWS S3 file storage
  • Ent ORM modeling
  • Audit logging strategies
  • Enterprise IAM concepts
  • Role-Based Access Control (RBAC)
  • Department-Based Access Control (DBAC)

More importantly, I learned that good architecture matters more than adding features quickly.

A well-structured system becomes easier to maintain, extend, and secure as it grows.

Conclusion

Cerberus started as a simple access request application, but it evolved into a complete Identity and Access Management style backend.

The project combines:

  • Go
  • GraphQL
  • Ent ORM
  • MySQL
  • JWT Authentication
  • Open Policy Agent
  • AWS S3
  • Audit Logging

By separating responsibilities into dedicated layers and moving authorization into OPA, the system remains secure, maintainable, and scalable.

For anyone interested in backend engineering, IAM systems, or policy-driven authorization, building a project like Cerberus is an excellent learning experience.


메타데이터
post_id
abe4e2e0d6ed
slug
cerberus-a-secure-access-request-management-system-with-go-graphql-opa-and-aws-s3-abe4e2e0d6ed
url
https://medium.com/@tushardhama3/cerberus-a-secure-access-request-management-system-with-go-graphql-opa-and-aws-s3-abe4e2e0d6ed
canonical_url
https://medium.com/@tushardhama3/cerberus-a-secure-access-request-management-system-with-go-graphql-opa-and-aws-s3-abe4e2e0d6ed
author_url
https://medium.com/@tushardhama3
status
ok
fetched_at
2026-06-10 09:45:17