ahmed omosanya

The permissions I never granted

I’m learning OpenFGA for work, and I started the way I start everything: by trying to click around in a UI. OpenFGA ships a Playground web UI, so I ran the container and opened localhost:3000. ERR_CONNECTION_RESET. The built-in Playground is deprecated and binds to the container’s own loopback, so the port mapping never reaches it. I fell back to the fga CLI against the HTTP API, which is how a real app talks to it anyway. (openfga-playground)

Then the part that got me.

I wrote a handful of relationship tuples. Alice is an editor of organization:hq. hq is the parent of branch. Then I started running Check calls, which are about as simple as an API gets: (user, relation, object) in, boolean out.

fga query check user:alice editor organization:branch   # true

I never wrote a tuple saying Alice can edit branch. She edits hq, and branch sits under hq. The model says editor from parent, so OpenFGA walks the relationship graph and the grant cascades down. Same story with documents: an owner resolves as a viewer with no viewer tuple anywhere, because the model folds owner into viewer with an or. The permissions resolved true. I’d never granted them.

The cascade is one-way, which is the bit I had to keep reminding myself of. Grants flow parent to child, never child to parent. Carol editing branch does not make her an editor of hq.

That one-way graph is the part I care about for work. The naive way to do authorization is a row per (user, resource) pair, and it drowns the moment your resources nest. Here I stored a small org tree and a few direct grants, and access to everything underneath answers itself by walking relationships. You grant at the top and let the graph answer for the whole subtree.

← all writing press c to copy email