CompanyOS members edit shared records and trigger Routines with scopes
October 23, 20261 min read
Agno's /company routes in AgentOS now authorize every write by the caller's scopes alone and leave the creator's user_id on the record for attribution. Every member already reads all of CompanyOS, yet with user_isolation=True a teammate holding every scope still hit "Cannot modify product owned by another user" when renaming a Product, archiving a Project, or pausing someone else's Routine.
We ran the same two-user session through the AgentOS routes on both releases with FastAPI's TestClient, with JWT auth set up the way the release's own tests do. Alice creates a Product, a Project and a Routine. Bob holds the Product, Project, Routine and schedule scopes plus agents:reader:run, and writes to each of them. The scheduler's background run is a stub taken from those tests, so the trigger records its run without calling a model.
AgentOS(
db=db,
agents=[Agent(id="reader")],
company=CompanyConfig(),
authorization=True,
authorization_config=AuthorizationConfig(
verification_keys=[SECRET], algorithm="HS256", user_isolation=True
),
)
A manual POST /company/routines/{id}/trigger needs routines:write, schedules:write and the executor's run scope. The run is saved under the caller's user_id and executes with the caller's authority, while scheduled runs keep the creator and the authorization stored on the Routine. A Routine with auto_accept stays locked to the user who authorized acceptance, because it runs on that person's saved grant.
Deployments that relied on user isolation to keep members off each other's Company records now control them through scopes only. A member with products:delete can archive any Product, and wiki:write covers every wiki page, company pages included.
See the cookbook, and learn more about per-user data isolation in the documentation.
Frequently asked questions
No. Company records are shared across the team. A write to a Product, Project, Task, Routine, Source or wiki page needs only the matching scope, and user_id keeps the name of whoever created the record.
The routines:write and schedules:write scopes, plus the run scope for the Routine's executor, such as agents:reader:run for an agent with the ID reader.
The caller. AgentOS records the run under the caller's user_id and runs it with the caller's authority. Scheduled runs keep using the creator and the authorization saved on the Routine.
Only the user who authorized automatic acceptance, as recorded on the saved grant, or an admin. Anyone else gets a 403 that says only that user may run the Routine.


