Skip to content

Siddhant-K-code/agentic-authz

Repository files navigation

Agentic AuthZ Demo

Fine-grained authorization for AI agents using OpenFGA.

AI agents are getting access to production systems - databases, APIs, file systems. But who decides what they can do? Traditional RBAC wasn't designed for autonomous agents that make decisions without human approval.

This demo shows how to implement Relationship-Based Access Control (ReBAC) for AI agents using OpenFGA, with three levels of authorization:

  1. Team Level - Which teams can use which tool categories
  2. Project Level - Which projects have access to which resources
  3. Operation Level - Fine-grained control over destructive operations

Quick Start

# Start services and seed data
make setup

# Run the demo
make demo

# Or use the interactive script
./scripts/demo.sh

Why This Matters

Problem Solution
Agent has same permissions as user Fine-grained, context-aware permissions
Prompt injection → data exfiltration Blast radius contained by project scope
No audit trail for agent actions Every authorization decision logged
"All or nothing" tool access Operation-level restrictions

Architecture

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   AI Agent      │────▶│   Gateway       │────▶│   OpenFGA       │
│   (Claude/GPT)  │     │   (Go)          │     │   (AuthZ)       │
└─────────────────┘     └─────────────────┘     └─────────────────┘
                               │
                               ▼
                        ┌─────────────────┐
                        │   MCP Tools     │
                        │   (Mock/Real)   │
                        └─────────────────┘

Authorization Model

Three levels of access control:

1. Team Level

Teams are assigned to tool categories.

Team Code Tools Communication Data Tools Infrastructure
Engineering
Marketing
DevOps

2. Project Level

Projects have specific tool access.

Project GitHub Slack Postgres Filesystem
auth-service
landing-page
infrastructure

3. Operation Level

Specific operations are restricted to certain roles.

Operation Allowed Roles
github:delete_repo Team Leads only
postgres:delete Team Leads only

Demo Scenarios

# Scenario User Tool Expected
1 Engineering → GitHub Alice (lead) github:create_pr ✅ Allowed
2 Marketing → GitHub Bob (lead) github:create_pr ❌ Denied
3 auth-service → Postgres Alice postgres:query ✅ Allowed
4 landing-page → Postgres Bob postgres:query ❌ Denied
5 Member → delete_repo Charlie github:delete_repo ❌ Denied
6 Lead → delete_repo Alice github:delete_repo ✅ Allowed

Services

Service Port Description
Demo UI 3002 Interactive demo interface
Admin UI 3001 Permission management dashboard
OpenFGA Playground 3000 OpenFGA visual explorer
Gateway API 9000 Authorization gateway
OpenFGA API 8080 OpenFGA HTTP API

Development

# Install dependencies
make install-deps

# Start OpenFGA
make setup-openfga

# Run gateway in mock mode
make dev-gateway

# Run Demo UI
make dev-demo

# Run Admin UI
make dev-admin

API Endpoints

Check Authorization

curl -X POST http://localhost:9000/v1/tools/call \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "github",
    "operation": "create_pr",
    "params": {"title": "My PR"},
    "context": {
      "user": "alice",
      "project": "auth-service",
      "team": "engineering"
    }
  }'

List Tools

curl http://localhost:9000/v1/tools

View Audit Log

curl http://localhost:9000/v1/audit

List Demo Scenarios

curl http://localhost:9000/v1/demo/scenarios

Project Structure

agentic-authz/
├── gateway/              # Go authorization gateway
│   ├── cmd/gateway/      # Main entry point
│   └── internal/         # Internal packages
│       ├── authz/        # OpenFGA client
│       ├── config/       # Configuration
│       ├── handler/      # HTTP handlers
│       └── mcp/          # MCP proxy
├── demo-ui/              # Next.js demo interface
├── admin-ui/             # Next.js admin dashboard
├── openfga/              # Authorization model
│   ├── model.fga         # FGA DSL model
│   ├── model.json        # JSON model for API
│   └── tuples.json       # Seed data
├── scripts/              # Demo scripts
├── docker-compose.yml    # Service orchestration
└── Makefile              # Build commands

OpenFGA Model

The authorization model uses OpenFGA's DSL:

type tool
  relations
    define category: [tool_category]
    define allowed_team: [team]
    define can_use: member from allowed_team or can_use from category

type tool_operation
  relations
    define tool: [tool]
    define allowed_role: [user]
    define can_execute: allowed_role or can_use from tool

Make Commands

make help           # Show all commands
make setup          # Full setup
make demo           # Run all demo scenarios
make audit          # View audit log
make tools          # List available tools
make users          # List demo users
make projects       # List demo projects
make clean          # Stop and clean up

The Security Case for Agent Authorization

The Problem

User: "Summarize our Q4 sales data"
Agent: *has database access*
Agent: SELECT * FROM users; DROP TABLE users;--

Without fine-grained authorization, a compromised or manipulated agent can:

  • Access data outside its task scope
  • Perform destructive operations
  • Pivot between systems
  • Exfiltrate sensitive information

The Solution

User: "Summarize our Q4 sales data"
Agent: *requests database access*
Gateway: Check(user:alice, can_execute, tool_operation:postgres:query)
OpenFGA: ✅ ALLOWED (project:sales-dashboard has postgres access)
Agent: SELECT SUM(revenue) FROM sales WHERE quarter='Q4'

With this architecture:

  • Every tool call is authorized
  • Permissions are scoped to project context
  • Destructive operations require elevated privileges
  • All decisions are audited

Real-World Use Case: Confidential AI Platforms

When AI coding agents work on security-critical codebases, the blast radius of a compromised or misdirected agent is much larger than in a typical project. This pattern applies directly to confidential computing stacks where certain components must never be touched by an agent.

Example: Confidential AI inference platform (Intel TDX)

A typical confidential AI stack has components where agent write access would be catastrophic:

Component Why it matters
cvm/attestation-service/ TDX quote generation and EKM validation logic
cvm/auth-service/ Bearer token auth and HMAC comparison
cvm/cert-manager/ TLS cert and EKM shared secret

A developer running a frontend review agent should have no access to these components. With agentic-authz, this is expressed as the absence of tuples — no tuple written means no access, full stop.

# Grant the frontend review agent access to the frontend only
fga tuple write \
  '{"object":"repo:my-project/frontend","relation":"reader","user":"agent:frontend-review-agent"}'

# No tuples written for attestation-service, auth-service, cert-manager.
# The agent cannot read or write those components regardless of what it "decides."

# Verify
fga query check --user agent:frontend-review-agent \
  --relation reader --object repo:my-project/attestation-service
# { "allowed": false }

Connecting attestation identity to authorization

For platforms using attested TLS, the TEE's measurement (e.g. app_compose_hash from a TDX attestation report) can serve as the identity anchor in OpenFGA tuples:

# After verifying the TEE attestation, extract the identity
tee_identity = report.tdx.app_compose_hash  # deterministic per deployment

allowed = await fga.check(
    user=f"tee:{tee_identity}",
    relation="can_invoke",
    object="service:inference-endpoint"
)

This gives confidential AI platforms a full authorization layer on top of their existing attestation stack: the aTLS layer handles authentication (who is connecting), OpenFGA handles authorization (what they can do).


Resources

Author

Built by Siddhant Khare - OpenFGA Core Maintainer

Helping teams implement secure AI agent architectures.

License

MIT