Skip to content
Free, open source

Zanzibar-Style Authorization 
for PostgreSQL

Implement fine-grained, relationship-based access control without external services. 
Melange compiles OpenFGA schemas into SQL functions that run inside your existing database.

How It Works

Melange is an authorization compiler. Like Protocol Buffers or GraphQL Code Generator, you define a schema and Melange generates optimized code tailored to your exact model. Instead of a generic runtime that interprets your model at query time, Melange generates purpose-built SQL functions for each relation in your schema. Role hierarchies are resolved at compile time and inlined into SQL, so runtime checks avoid recursive graph traversal entirely.

    flowchart LR
    schema["schema.fga"] --> melange["melange compile"]
    melange --> funcs["PostgreSQL Functions"]
    funcs --> check["check_permission()"]
    funcs --> list["list_accessible_objects()"]
    funcs --> subjects["list_accessible_subjects()"]
  

Define Your Schema

Write your authorization model using the OpenFGA DSL. The same .fga files work with both Melange and OpenFGA, so there’s no vendor lock-in.

Melange supports direct assignments, computed usersets, unions, intersections, exclusions, tuple-to-userset, wildcards, userset references, and contextual tuples.

model
  schema 1.1

type user

type organization
  relations
    define owner: [user]
    define admin: [user] or owner
    define member: [user] or admin

type repository
  relations
    define org: [organization]
    define owner: [user]
    define admin: [user] or owner
    define can_read: member from org or admin
    define can_write: admin
    define can_delete: owner

Query Your Existing Tables

Unlike traditional FGA systems, Melange doesn’t need a separate tuple store. Create a SQL view that maps your existing domain tables into tuples, and Melange queries them directly.

No data duplication. No sync jobs. Permissions are always consistent with your domain data, down to the current transaction.

CREATE VIEW melange_tuples AS
-- Organization memberships
SELECT
    'user' AS subject_type,
    user_id::text AS subject_id,
    role AS relation,
    'organization' AS object_type,
    organization_id::text AS object_id
FROM organization_members

UNION ALL

-- Repository ownership
SELECT
    'organization' AS subject_type,
    organization_id::text AS subject_id,
    'org' AS relation,
    'repository' AS object_type,
    id::text AS object_id
FROM repositories;

Check Permissions From Any Language

Once compiled, permission checks are simple SQL function calls. Use the Go or TypeScript client libraries for convenience, or call the generated functions directly from any language that can talk to PostgreSQL.

checker := melange.NewChecker(db)

allowed, err := checker.Check(ctx,
    authz.User("alice"),
    authz.RelCanRead,
    authz.Repository("123"),
)

Get Started in Minutes

# Install
brew install pthm/tap/melange

# Initialize your project
melange init

# Apply schema and generate SQL functions
melange migrate

# Generate type-safe client code
melange generate client