This is a submission for the Permit.io Authorization Challenge: Permissions Redefined

What I Built

I've developed PermitGuard, a next-generation document management system with advanced permission controls powered by Permit.io. The platform addresses the critical challenge of securing sensitive documents while maintaining flexibility and ease of use.

In today's collaborative environments, organizations struggle with balancing security and accessibility. Traditional permission models fail to account for the complex, dynamic nature of modern document workflows.

PermitGuard solves this by implementing fine-grained, context-aware permissions that adapt to real-world business scenarios.

Key features include:

  • Document classification with automatic permission assignment
  • Section-level access controls within documents
  • Attribute-based permissions that consider user context and document metadata
  • Time-bounded access with automatic expiration
  • Complete audit trail of all permission decisions
  • Permission delegation with approval workflows

The system demonstrates how externalized authorization through Permit.io delivers superior security with significantly less code complexity compared to traditional approaches.

Demo

You can test the application using these credentials:

Admin credentials:

  • username: admin
  • password: 2025DEVChallenge

User credentials:

  • username: newuser
  • password: 2025DEVChallenge

The demo showcases:

  • Real-time permission changes without application redeployment
  • How the same document appears differently to users with different permissions
  • The delegation workflow for temporary access grants
  • Comprehensive audit logging of all access decisions

My Journey

Creating PermitGuard completely changed my understanding of authorization in modern applications.

The Authorization Problem

When I started this project, I initially implemented a simple role-based access control (RBAC) system directly in my application code. This quickly became problematic:

  • Permission checks were scattered throughout the codebase
  • Business rules became entangled with authorization logic
  • Changes to permission requirements required code changes
  • Testing permission scenarios was cumbersome
  • Scaling to handle complex real-world scenarios was difficult

I needed a better approach that would separate authorization from business logic while providing the flexibility for complex permission scenarios.

Discovering Permit.io

After researching various options, I discovered Permit.io and realized it offered exactly what I needed: externalized authorization with a robust policy engine. The key advantages that drew me to Permit.io were:

  1. Clear separation between authorization logic and application code
  2. Support for attribute-based access control (ABAC)
  3. Ability to update policies without code changes
  4. Comprehensive audit capabilities
  5. Developer-friendly tools including the CLI

Implementation Challenges

Challenge 1: Modeling Complex Document Permissions

The first major challenge was modeling our document permission system in a way that could handle real-world complexity. Documents in our system have multiple sections, versions, and states, each potentially requiring different permission rules.

I solved this by creating a richly attributed resource model in Permit.io:

// Document resource definition with attributes
const documentResource = {
  key: "document",
  name: "Document",
  description: "A document in the system",
  attributes: {
    owner: { type: "string" },
    department: { type: "string" },
    classification: { 
      type: "string", 
      enum: ["public", "internal", "confidential", "restricted"] 
    },
    status: { 
      type: "string", 
      enum: ["draft", "review", "approved", "archived"] 
    }
  }
};

This allowed me to create sophisticated policies based on document attributes.

Challenge 2: Section-Level Permissions

Another challenge was implementing section-level permissions within documents. Rather than treating each section as a separate resource (which would have been inefficient), I implemented a creative solution using resource hierarchies and context-based checks:

// Section-level permission check
async function checkSectionAccess(user, documentId, sectionId) {
  // Get document metadata
  const document = await getDocument(documentId);

  // Get section metadata
  const section = await getDocumentSection(documentId, sectionId);

  // Check permission with section context
  return await permit.check({
    user: user.email,
    action: "read",
    resource: `document:${documentId}`,
    context: {
      section: {
        id: sectionId,
        classification: section.classification
      },
      document: {
        owner: document.owner,
        department: document.department,
        classification: document.classification,
        status: document.status
      }
    }
  });
}

Challenge 3: Performance Optimization

With potentially thousands of permission checks per user session, performance became a concern. I addressed this through:

  1. Strategic caching of permission decisions
  2. Batch permission checks for document lists
  3. Minimizing permission check frequency through UI state management

Key Lessons

This project taught me several valuable lessons:

  1. Authorization as infrastructure - Moving permission logic outside of application code dramatically improves maintainability
  2. Policy as code - Treating permission rules as versioned code improves governance
  3. Context is critical - Rich contextual information enables much more sophisticated authorization decisions
  4. Separation of concerns - Decoupling authorization from business logic results in cleaner architecture

Using Permit.io for Authorization

The Permit.io CLI became an essential part of my development workflow, enabling me to manage authorization as code.

Initial Setup

I began by initializing my project and creating a development environment:

# Initialize Permit in the project
permit init

# Create development environment
permit create env dev

# Login to Permit cloud
permit login

Resource and Policy Modeling

I used the CLI to define my permission model:

# Create resource types
permit create resource document
permit create resource folder
permit create resource comment

# Create roles
permit create role admin
permit create role editor
permit create role viewer
permit create role owner

# Create relationships between roles and resources
permit create role-assignment --role admin --resource document --actions "create,read,update,delete"
permit create role-assignment --role editor --resource document --actions "read,update"
permit create role-assignment --role viewer --resource document --actions "read"

Advanced Policy Rules

For more complex scenarios, I defined custom policy rules:

# Create a custom rule for document access based on department
permit create rule "document_department_match" \
  --resource document \
  --action read \
  --rule "user.department == resource.department"

# Create rule for document owners
permit create rule "document_owner" \
  --resource document \
  --action "update,delete" \
  --rule "user.email == resource.owner"

# Create rule for document classification restrictions
permit create rule "restricted_documents" \
  --resource document \
  --action read \
  --rule "resource.classification == 'restricted' ? user.clearance_level >= 3 : true"

Policy Testing and Validation

The CLI enabled me to test policies before deploying them:

# Test if a user can access a specific document
permit check-access \
  --user [email protected] \
  --resource document:financial-report-2023 \
  --action read

# Test with specific context
permit check-access \
  --user [email protected] \
  --resource document:strategic-plan \
  --action update \
  --context '{"urgency": "high", "approval_status": "pending"}'

Policy Management Workflow

I integrated Permit.io into my CI/CD pipeline for consistent policy deployment:

# Export current policies to version control
permit export > policies/current-policies.json

# In CI/CD pipeline: apply policies from version control
permit apply -f policies/current-policies.json --auto-approve

By leveraging Permit.io's CLI throughout my development workflow, I created a sophisticated authorization system that adapts to complex business requirements while keeping my application code clean and focused on business logic.