Skip to content

zvectorlabs/pgauthz

Repository files navigation

pgauthz

Zanzibar-style authorization as a PostgreSQL extension.

Overview

pgauthz brings Google Zanzibar-style authorization directly into PostgreSQL, enabling fine-grained access control with relationship-based permissions. Built as a native PostgreSQL extension, it provides high-performance authorization checks with built-in caching, observability, and structured error handling.

Why pgauthz in an Agentic World

As AI agents autonomously browse, write, execute, and transact on behalf of users, authorization becomes the critical control plane. Traditional role-based access control wasn't designed for a world where thousands of agents act concurrently, each with different scopes, on behalf of different principals, across shared resources. pgauthz addresses this head-on:

  • Agent-to-resource permissions — Model exactly what each agent (or tool) can access. An agent acting on behalf of Alice should inherit Alice's permissions, not a blanket service account.
  • Dynamic, context-aware checks — Conditions like time windows, IP allowlists, or session metadata let you enforce runtime constraints on agent actions (e.g., "this agent can only write during business hours").
  • Composable delegation chains — Zanzibar's relationship model naturally represents delegation: User → Agent → Tool → Resource. Permission flows through the graph, and revocation propagates instantly.
  • Sub-millisecond decisions at the data layer — Agents move fast. Authorization checks that round-trip to an external service add latency and failure modes. pgauthz runs inside PostgreSQL, right next to your data, keeping authorization on the hot path without the network hop.
  • Audit-ready by design — Every relation and policy change is tracked. When an agent takes an action, you can answer why it was allowed — essential for compliance and debugging in autonomous systems.

If your stack already uses PostgreSQL, pgauthz gives you Zanzibar-grade authorization without bolting on another service — one fewer moving part for your agents to depend on.

Key Features

  • Zanzibar-Style Authorization - Relationship-based access control with computed permissions
  • PostgreSQL Native - Runs directly in your database as an extension
  • High Performance - Multi-level caching (L1 model, L2 result, L3 tuple)
  • Observability - OpenTelemetry metrics and tracing support
  • Structured Errors - PostgreSQL SQLSTATE error codes for all operations
  • Flexible Policies - Support for conditions, wildcards, and complex permission hierarchies

Quick Links

Documentation

Full documentation is available at docs.pgauthz.dev

Quick Example

-- Create the extension
CREATE EXTENSION pgauthz;

-- Define an authorization policy
SELECT pgauthz_define_policy('
  type user {}
  type document {
    relations
      define viewer: [user]
      define editor: [user]
  }
');

-- Add a relation
SELECT pgauthz_add_relation('document', 'doc1', 'viewer', 'user', 'alice');

-- Check permission
SELECT pgauthz_check('document', 'doc1', 'viewer', 'user', 'alice');
-- Returns: true

Examples

Nested Groups with Exclusions

Control access through group hierarchies with deny-list style exclusions — e.g. interns in a group can be blocked from accessing documents while regular members retain access.

SELECT pgauthz_define_policy('
  type user {}
  type group {
    relations
      define member: [user | group#member]
      define intern: [user]
      define allowed: [user]
    permissions
      define intern_but_not_allowed = intern - allowed
      define non_intern_member = member - intern_but_not_allowed
  }
  type document {
    relations
      define viewer: [user | group#non_intern_member]
    permissions
      define view = viewer
  }
');

-- alice is a regular member
SELECT pgauthz_add_relation('group', 'engineering', 'member', 'user', 'alice');
-- bob is an intern (not in allowed list)
SELECT pgauthz_add_relation('group', 'engineering', 'intern', 'user', 'bob');
-- grant the group access to a document
SELECT pgauthz_add_relation('document', 'doc1', 'viewer', 'group', 'engineering#non_intern_member');

SELECT pgauthz_check('document', 'doc1', 'view', 'user', 'alice'); -- true
SELECT pgauthz_check('document', 'doc1', 'view', 'user', 'bob');   -- false (intern, excluded)

Conditional Access (Business Hours & IP Allowlist)

Attach runtime conditions to relations — permissions only resolve when context satisfies the condition expression.

SELECT pgauthz_define_policy('
  type user {}
  condition business_hours(hour: int, day: string) {
    hour >= 9 && hour <= 17 && day != "saturday" && day != "sunday"
  }
  condition ip_whitelist(allowed_ips: list<string>, current_ip: string) {
    current_ip in allowed_ips
  }
  type document {
    relations
      define viewer: [user with business_hours]
      define editor: [user with ip_whitelist]
    permissions
      define view = viewer + editor
  }
');

SELECT pgauthz_add_relation('document', 'doc1', 'viewer', 'user', 'alice', 'business_hours');
SELECT pgauthz_add_relation('document', 'doc1', 'editor', 'user', 'bob',   'ip_whitelist');

-- alice can view during business hours
SELECT pgauthz_check_with_context('document', 'doc1', 'view', 'user', 'alice',
  '{"hour": 10, "day": "monday"}');   -- true

-- alice cannot view outside business hours
SELECT pgauthz_check_with_context('document', 'doc1', 'view', 'user', 'alice',
  '{"hour": 22, "day": "monday"}');   -- false

-- bob can view from a whitelisted IP
SELECT pgauthz_check_with_context('document', 'doc1', 'view', 'user', 'bob',
  '{"allowed_ips": ["10.0.0.1"], "current_ip": "10.0.0.1"}');  -- true

Public Access with Wildcards

Use user:* to grant access to all users — useful for public resources while keeping ownership restricted.

SELECT pgauthz_define_policy('
  type user {}
  type document {
    relations
      define viewer: [user | user:*]
      define owner:  [user]
    permissions
      define view   = viewer
      define delete = owner
  }
');

-- make doc1 publicly readable
SELECT pgauthz_add_relation('document', 'doc1', 'viewer', 'user', '*');
-- only alice can delete
SELECT pgauthz_add_relation('document', 'doc1', 'owner', 'user', 'alice');

SELECT pgauthz_check('document', 'doc1', 'view',   'user', 'anyone'); -- true
SELECT pgauthz_check('document', 'doc1', 'delete', 'user', 'anyone'); -- false
SELECT pgauthz_check('document', 'doc1', 'delete', 'user', 'alice');  -- true

Permission Set Operations (Union, Intersection, Exclusion)

Compose permissions using + (union), & (intersection), and - (exclusion).

SELECT pgauthz_define_policy('
  type user {}
  type project {
    relations
      define member:   [user]
      define reviewer: [user]
      define lead:     [user]
      define blocked:  [user]
    permissions
      define can_review = reviewer + lead          -- union: reviewer OR lead
      define can_edit   = member & reviewer        -- intersection: must be both
      define can_merge  = lead - blocked           -- exclusion: lead but not blocked
  }
');

SELECT pgauthz_add_relation('project', 'proj1', 'member',   'user', 'alice');
SELECT pgauthz_add_relation('project', 'proj1', 'reviewer', 'user', 'alice');
SELECT pgauthz_add_relation('project', 'proj1', 'lead',     'user', 'bob');
SELECT pgauthz_add_relation('project', 'proj1', 'lead',     'user', 'charlie');
SELECT pgauthz_add_relation('project', 'proj1', 'blocked',  'user', 'charlie');

SELECT pgauthz_check('project', 'proj1', 'can_edit',   'user', 'alice');   -- true (member & reviewer)
SELECT pgauthz_check('project', 'proj1', 'can_edit',   'user', 'bob');     -- false (lead but not member)
SELECT pgauthz_check('project', 'proj1', 'can_merge',  'user', 'bob');     -- true (lead, not blocked)
SELECT pgauthz_check('project', 'proj1', 'can_merge',  'user', 'charlie'); -- false (lead but blocked)

List All Objects a User Can Access

-- list all documents alice can view
SELECT * FROM pgauthz_list_objects('user', 'alice', 'view', 'document');

-- list all users who can edit doc1
SELECT * FROM pgauthz_list_subjects('document', 'doc1', 'edit', 'user');

Core SQL Functions

  • Authorization Checks: pgauthz_check(), pgauthz_check_with_context(), pgauthz_expand()
  • List Operations: pgauthz_list_objects(), pgauthz_list_subjects()
  • Relation Management: pgauthz_add_relation(), pgauthz_write_relationships(), pgauthz_read_relationships()
  • Policy Management: pgauthz_define_policy(), pgauthz_read_latest_policy(), pgauthz_list_policies()
  • Change Tracking: pgauthz_read_changes()

Requirements

  • PostgreSQL 16/17/18
  • Linux or macOS

License

This project is licensed under the Apache License 2.0. See LICENSE for details.

Contributing

[Contributing guidelines to be added]

Support

About

pgauthz brings Google Zanzibar-style authorization directly into PostgreSQL for Agents

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors