Prerequisites
-
A graph backend enabled:
ACCESS_CONTROL_BACKEND=openfga. The setting defaults todisabled, and with it disabled every write here returns HTTP 503 and the permission service allows everything. Which stack you started decides whether it is on:If you are onmake up, switch tomake up-devor set the variable and run OpenFGA yourself before continuing. -
You are a workspace admin. Every
/v1/access-controlendpoint requires it. - The subject is already a member of your workspace, and the object already exists in it. Both are checked before the tuple is written.
- Read the AgentArea model — in particular that the three permission bits are independent.
API=http://localhost:8000 and a bearer token in $TOKEN.Steps
Confirm the graph is on
enabled: false means no graph backend is configured — stop here and set
ACCESS_CONTROL_BACKEND before continuing.Choose the relation
The relation you send is mapped onto one of three grant relations on the
resource. Pick by what the subject needs to do:
Four legacy names still resolve, so older scripts keep working:
viewers and
connectors map to reader, editors to writer, and owners and operators
to manager.The bits do not imply each other. A subject with only manager cannot read
the resource. To give somebody full access, write all three.Write the grant
namespace is one of Agent, MCPServer, Skill or SkillCollection. It
selects the repository used to confirm the object belongs to your workspace; the
tuple itself is always written against resource:<object>, because all four
kinds are one generic type in the graph.subject_id takes two shapes. Use User:<user_id> for a person. Use
Agent:<agent_uuid> to let one agent reach a resource in its own right — that
agent must also be in your workspace.A successful write returns HTTP 201 and {"ok": true}. Writes are idempotent, so
repeating one is safe.Verify
Ask the graph directly.relation accepts the same verbs the application uses,
and they are mapped onto the underlying bit:
allowed, effective_relation, verb and a paths array.
resource_kind is one of skill, collection, mcp or agent.
You can also list what has been written:
Troubleshooting
403 Agent:<id> not found in your workspace
403 Agent:<id> not found in your workspace
The object id is wrong, belongs to another workspace, or you are sending
it with the wrong
namespace. The lookup uses the namespace to pick the
repository, so an MCP server id sent with "namespace": "Agent" fails
this way.403 Subject user is not in your workspace
403 Subject user is not in your workspace
Add the person to the workspace first through
POST /v1/workspaces/{workspace_id}/invitations . Membership is resolved
from the workspace owner plus the membership table, so a user who has been
invited but has not accepted is not yet grantable.422 Unsupported relation for a resource grant
422 Unsupported relation for a resource grant
You sent something outside the accepted set. Use
reader , writer or
manager .422 Group (subject_set) grants are managed via project/role, not the explorer
422 Group (subject_set) grants are managed via project/role, not the explorer
This endpoint writes direct grants only. Bundled or group-scoped access goes
through
role and role_assignment objects — see
model a custom relation .The grant exists and the user still cannot read
The grant exists and the user still cannot read
Almost always the independent-bits rule. Check all three separately —
read
, edit and manage each need their own tuple, and a manager grant
confers neither of the others.The grant exists and nothing changed in the product
The grant exists and nothing changed in the product
Only a handful of API call sites consult the graph today: agent, skill and
MCP server edit and delete, model instance delete, and registered- client
use. List and read endpoints are scoped by workspace in the database and are
not graph-filtered, so a grant will not make a resource appear or disappear
from a list.
Related
The AgentArea model
The types and inheritance behind these tuples
Model a custom relation
When direct grants are not enough
Review the audit trail
Note that grant changes are not recorded there