Authorization infrastructure

App permissions
are a mess.
They don't have
to be.

You added if-statements early on. They multiplied. Now nobody's quite sure what the rules are, the logic is scattered across your codebase, and when a customer asks who has access to their data you have to guess.

No spam. We'll reach out personally when we're ready for design partners.

↳ You're on the list. We'll be in touch.

How it looks

-- Define your model once
type document
  relations
    define owner: [user]
    define viewer: [user] or owner

-- Ferri compiles it into your database
$ ferri migrate --db postgres://...

-- Check permissions anywhere, in any language
SELECT check_permission(
  'user', 'alice',
  'viewer',
  'document', 'quarterly-report'
);
-- Returns: true  (in ~400μs)

The problem

Permissions are still a mess at most companies

Almost every engineering team starts with if-statements and ends up with a tangle of logic nobody fully understands. When a compliance audit asks "show us who has access to what and prove it" — most teams panic.

The existing solutions require running a separate service alongside your application, syncing your data to it, managing another piece of infrastructure, and debugging failures across a network boundary. That overhead is why most teams still roll their own.

The insight

Your database already knows everything it needs

Your users, resources, and relationships already live in Postgres. Ferri compiles your permission model into SQL functions that run inside your existing database. No new service. No data sync. Permission checks in the same transaction as everything else.

We're looking for a small number of teams to work with closely before public launch.

Three steps.
Then it just works.

01

Define your model

Write your permission rules using the OpenFGA schema language. Editors can edit. Viewers can view. Permissions inherit through folders. Express it once, clearly.

02

Compile to Postgres

Run ferri migrate. The compiler analyses your model and generates specialised SQL functions — one per relation. The traversal logic is computed at compile time, not runtime.

03

Check from anywhere

Call check_permission() from any language that speaks SQL. Go, TypeScript, Python, Ruby — anything. No SDK required. Sub-millisecond checks. Transaction-aware by default.

The difference

Not another service
to run.

Everyone else

A separate service you have to operate

  • Deploy and maintain a dedicated authorization service
  • Sync your domain data to a separate tuple store
  • Network hop on every permission check
  • Can't see uncommitted transactions
  • Manual cleanup when data is deleted
  • Another thing to break at 2am
Ferri

SQL functions inside your existing database

  • Lives inside the Postgres you already run
  • Permissions are views over your real tables
  • 300–600μs checks with no network overhead
  • Fully transaction-aware out of the box
  • Cascade deletes handled automatically
  • Nothing new to monitor or operate

Early access

Built for teams who
already chose Postgres.

We're working with a small group of design partners before public launch. If your team runs Postgres and has been putting off fixing your permission model — we want to talk to you.

No spam. We'll reach out personally when we're ready for design partners.

↳ You're on the list. We'll be in touch.