Table of contents

Guide

Agentic Ops

Access Control

User roles and permissions: best practices for humans and AI agents

Guillaume Rigal

0 min read

Most permission models were designed for people. Then something arrives that is not a person but acts for one. Here is the vocabulary, the design rules, and what has to change.

Every team eventually writes its own permission system. It starts with an is_admin boolean, grows a roles table, then a permissions table, then a join table nobody remembers the shape of. Two years later somebody asks a question that should be simple. Can this person refund this customer, and where is that written down?

The question is harder than it looks, and it just got harder again. Whoever is asking to refund the customer is no longer always a person. It is increasingly an AI agent, working from a chat window or an agentic platform, calling your systems on someone's behalf.

This guide covers user roles and permissions as a working model: the vocabulary, the two axes most systems merge into one, the design rules that survive an audit, and what all of it has to do once something that is not a person starts making the calls.

To explain these concepts, throughout the article we'll follow a fictional team at a payments company.

  • Alice, support analyst. She works her own queue, sees customers in her region, and can refund up to a limit.

  • Bob, operations lead. He runs the team Alice works in. He approves the refunds above her limit and sees every region, and he changes nothing about how the tool works.

  • Claire, process owner. She designs the process Alice follows. She can change the workflow, and she has almost no reason to open a customer record.

  • Dave, developer. He builds the thing. He needs deep access to how the system works and really none to the data in it.

The rules and concepts below will refer back to them.

Permission, role, privilege, entitlement, scope: what is the difference?

A permission is one action on one kind of object. Some systems call the same thing a privilege, borrowed from database vocabulary, so user permissions and user privileges are two names for one idea. A role is a named bundle of permissions. An entitlement is what somebody actually holds once every role, group and exception has been applied. A scope is the subset of records any of it applies to.

Most permission arguments are vocabulary arguments in disguise. Two engineers use "role" to mean two different things and spend an hour in hot debate before realizing they agree.

Term

What it is

Example

Where teams get it wrong

Permission, also called a privilege

One action on one kind of object

Delete an invoice

Bundling read, create, update and delete into one "write" flag

Role

A named bundle of permissions

Compliance Reviewer

Naming them after job titles, which stop matching within a quarter

Entitlement

What somebody actually holds once every role, group and exception has been applied

Alice can, in fact, export

Assuming the grant and the entitlement match. They drift

Scope

The subset of records a permission applies to

Customers in the DACH region only

Having none, so Alice can open every account in the company

The one distinction worth holding on to is the last two. A role is what you granted. An entitlement is what is true today, after every exception anyone has added since. Access reviews exist because those two stop matching.

Platform capability and data access are two different permissions

What a person can change about your system and what a person can reach in your data are separate questions, and they need separate answers. Put them on one ladder and the only way to give somebody a setting is to give them the whole database.

There is what a person can do to your platform: change configuration, edit the layout, invite a colleague, deploy. And there is what a person can reach in your data: which collections, meaning which tables of customers or payments or disputes, then which records inside them, which fields on those records, and which actions they can run.

Dave, the developer, needs deep platform capability and really none of the customer data. Bob is the reverse. He has to see every account his team touches, and he should not be able to change how the tool is configured. One ladder cannot express either of them.

This leads to an impasse. Claire needs to change one setting. The only permission level that allows it is Admin, and Admin also sees every record in the company. To let her fix a checkbox you would have to hand her god mode, so nobody does it, and the setting stays wrong.


Which access control model should you use: ACL, RBAC, ABAC or ReBAC?

For almost every operational backoffice the answer is RBAC as the foundation, with a second model handling the exceptions. Traditionally there are four models to pick from, and they are not rivals: most real systems run one as the foundation and add a second for the cases the first one cannot express. Here is the short version of each.

Model

How access is decided

Best for

Breaks when

ACL (access control list)

Permissions attached to individual objects

Small systems, few objects, explicit sharing

Volume. A thousand users and ten thousand records is ten million grants

RBAC (role-based access control)

Permissions grouped into roles, roles assigned to people

Almost every operational backoffice

Exceptions multiply into Support EU Tier 2 Escalations

ABAC (attribute-based access control)

Decided at the moment of the request, from who is asking, what they are asking for and the context

Rules that genuinely depend on context, like time of day or amount

Nobody can answer "what can Marie see?" without running the engine

ReBAC (relationship-based access control)

Derived from who is connected to what

Ownership and assignment, where access follows the case

The relationships go stale and access follows them

RBAC gets a closer look, with the exception problem and the ways teams work around it, in our article on role-based access control.

What matters is knowing which of these decides what, so that when somebody sees the wrong thing you know where to look.

What are the best practices for user roles and permissions?

Six rules cover most of the work. We will go through them in order of importance.

Deny by default

A new permission, a new collection, a new tool: nobody has it until somebody grants it. The opposite policy fails silently, and it fails in the direction of exposure.

Least privilege, expressed as a mechanism

Everybody agrees with least privilege in the abstract. It only becomes real when your system can express it, which means permissions at the granularity the work actually has. In Forest, a role sets read on the list view separately from read on the record detail, and create, update, delete and export separately again. Six decisions, not one "write" flag. Alice processes refunds and never needs export, and export is how data leaves the building.

Scope to data, not to endpoints

Most systems attach their permissions to endpoints, so the only question they can answer is "are you allowed to open this screen". The question you need answered is "are you allowed to open this screen, for these customers". Forest handles it with scopes, applied to a collection and all its segments and resolved against whoever is logged in, so Alice and her counterpart in Milan open the same screen and see different customers. A permission that only knows which page you opened cannot tell you which records belong on it.

Scopes are also where the numbers turn against you, because roles and scopes multiply. Five roles and four scopes is twenty combinations to define, check and keep true, and five roles is a small company. Add a market, or split a team, and the number moves again. This is the point where a permission model stops being something you can hold in your head or keep in a spreadsheet, and has to become a system that works out the combination for you every time somebody asks.

Separate duties

Some operations should never be carried out end to end by one person, however senior. Alice requests the large refund. Bob approves it. Neither of them can do both halves. That is not a permission setting, it is a workflow, and it has its own section further down.

Control fields where it matters

Most collections have a few columns more sensitive than the rest. Alice needs the customer record and does not need the full bank details. Field-level control and masking are what let one screen serve two audiences. Check that whatever you use enforces this on the API and not only on the screen, because an agent calling your data is not looking at the screen.

Keep the grant reviewable

Permission management is not the act of granting. It is the act of being able to say, later, that the grant was right. Somebody has to be able to read the current state and check it. If your model can only be inspected by clicking through a settings screen one user at a time, it will not be reviewed, and what is not reviewed drifts. There is more on making a model readable, and on the review cycle itself, in our article on permission management in software development.

What should you look for in permission management software?

Six things to check, and most of them are a yes or a no. The third column is what to ask for in a demo. Vendors answer the first two columns the same way. They do not all survive the question.

What to check

Why it matters

How to test it in a demo

Two axes, not one ladder

Otherwise the only way to grant a setting is to grant the database

Ask for Claire's configuration rights without Bob's data access

Record and field level

Sensitive columns live inside otherwise ordinary records

Ask to hide one column from one team, on one collection

Scope resolved per user

A static filter is not a scope, it is a saved view

Ask what Alice and her counterpart in Milan see on the same screen

Approval as a step

Some operations need a second person, not a stronger role

Ask how a refund above a threshold gets a second approval

A readable grant

What cannot be reviewed drifts, and drift is what an auditor finds

Ask to export or compare the entire permission model

An identity for every caller

Work a person asked for and work that runs on its own need different identities, and both need to be traceable

Ask what the log says when an assistant does the work for Alice, then what it says for a nightly job

The last row is the one that separates tools right now. Most permission systems were designed when whoever called them was either a person at a screen or a script doing the same thing every time. Neither of those opens a chat window and asks for something in its own words.

How does Forest handle roles and permissions?

Forest sets the two axes in two different places, and neither one constrains the other.

Data access is set by a role. A role is attached to a team, and every user belongs to a team. It sets which collections that team can read or edit, which actions they can trigger, and under which conditions. Put Alice and Bob in different teams and the same screen shows them different customers.

Platform capability is set by a permission level. That one belongs to the user account itself, not to their team. There are six: User, Manager, Developer, Process Owner, Editor and Admin. Some are broader than the one below. Others cover one specific area of the product instead of sitting higher on a scale, which is why the six are not a straight line from less power to more.

Process Owner is the clearest case. In our fictional team it belongs to Claire, who designs the process Alice follows. It exists because defining a process and running it are two different jobs carrying two different risks.

  • Editor governs what a screen looks like: layouts, Workspaces, Summary Views.

  • Process Owner governs what a Workflow does, which is what happens to real customers the next time it runs.

  • Neither of them grants access to a single extra customer record. That is the role's job, on the other axis.

Defining and running are held apart for the same reason platform and data are: whoever may do one is not automatically the person who may do the other.

Whether or not you use Forest, build the same separation.

Should an AI agent act as a person, or as itself?

The test is one question: is there a human user who asked for this specific action? If yes, the agent should act as them. If no, it needs standing of its own.

Most of the time the situation answers that question for you.

A person is at the keyboard. Alice opens her assistant and asks it to pull every dispute older than five days. There is a human user, she is identifiable, and the only sensible thing is for the agent to log in as her. It sees her region because that is her scope, it cannot export because she cannot export, and the log says Alice. The work was hers. The agent did the typing. This is delegation: the agent holds no permissions of its own and borrows hers for the length of the request.

Nothing was triggered by a person. A job re-screens the sanctions list every night. An agent watches a queue and sorts what lands in it. Nobody launched the run, so there is no person whose permissions it could sensibly borrow. It needs an identity of its own and a grant of its own. In Forest that is a service account: an identity that belongs to the automation rather than to a person, carrying its own role and its own line in the log.

One clarification on the test, because it settles a lot of cases. A customer filling in a form on your website can set an automation running, and that customer is not a human user in the sense meant here. They hold no permissions in your system, so there is nothing for the automation to inherit. That run needs a service account.

The cases where you genuinely get to choose are narrower than they sound, and they usually look like a scheduled job that one person owns personally. Either answer works. Pick the one that will still be true after that person changes teams.

Getting it backwards fails quietly in both directions. Run a nightly job on Alice's credentials and it breaks the week she leaves, and until then your audit trail says Alice was issuing refunds at three in the morning. Run Alice's interactive request under a machine identity and the log names a robot, so six months later nobody can say who wanted the thing done.

When an agent does act as a person, it can do what that person is permitted to do, no more and no less. It cannot reach a collection Alice cannot reach or run an action her role does not allow, and it does not need a separate list of approved operations that falls behind every schema change.

If you want the agent to reach less than Alice does, do that on the same two axes: a narrower role, or a lower permission level, on the account the agent logs in with. Plenty of teams want exactly that for backoffice access through a chat client. Delegation sets the ceiling, and nothing obliges you to sit at it.

There is a third lever if you connect the agent through the Forest MCP Server, which is the component that exposes your backoffice operations to an AI client. You choose which of those operations the server exposes at all, and that choice applies to every caller behind it. It is the platform capability axis again, this time pointed at the agent. How to set it, and what changes for a Ruby back-end, is covered in our article on permissions beyond your own team.

Approval workflows are the permission boundary that scales

Some operations should not come down to one person's permission at all. A refund above a threshold, closing an account, anything with a regulator on the other end of it. What these need is an escalation path: a limit, a level above that limit, and somebody who approves.

This goes beyond setting permissions. It requires approval levels. Alice can raise a refund above her limit, Bob approves it, and neither of them holds the whole operation on their own. Alice is not blocked, and Bob is not doing her job for her.

The same structure covers the agent, because the requirement belongs to the operation rather than to whoever asked for it. Alice's assistant, acting as Alice, can raise the refund and cannot release it, exactly as Alice cannot. The action does not execute. It creates an approval request, somebody with the approval permission reviews it, and the outcome lands in the history either way.

This is what makes agent autonomy workable in a regulated business. You are not deciding once and forever whether an agent may issue refunds. You are deciding which refunds need a second person, and that requirement is already written into the operation.

What should a permission audit trail record?

For teams in regulated industries, and for anybody who has been through an audit, this is the part that gets checked. An audit trail has to record who acted, on which record, when, and what the values were before and after. For an action, it also has to record what was submitted and what came back. Anything less and you cannot reconstruct a decision.

The test is simple. Six months from now, somebody asks why this customer's postal code changed on a Tuesday in September. You should be able to answer without opening a database.

In Forest, every data operation and every action lands in the activity log against the record, field by field. What is deliberately not stored is the sensitive content of the records themselves, beyond the identifier. The log tells you what happened. It does not become a second copy of your customer data.

Because an agent acting for a person logs in as that person, its calls land in that same log, under that name, in the same format. There is no separate agent audit to reconcile, which is the whole point of delegation. One model, one log.

Frequently asked questions about user roles and permissions

How do you design permissions around intent instead of roles?

Start from the operations your business performs, not from your org chart. List the verbs: refund, close, escalate, re-screen, export. For each one, decide who may do it, on which records, and whether it needs a second person. Then group the results into roles. Roles built this way describe what the business does. Roles built from job titles describe what HR does.

How do you balance security and developer velocity with permissions?

The tension is usually a symptom of a model too coarse to express what you mean. When the only options are Admin or blocked, every request becomes a negotiation. Give the model enough granularity to say yes narrowly and the negotiations stop. Declaring permissions as code rather than clicking them in a settings screen helps for the usual reason: the change gets reviewed and leaves a trace.

Can an AI agent be given fewer permissions than the person it acts for?

Yes, and it is often the right call. Delegation sets the ceiling, not the floor. You can point the agent at an account with a narrower role, and you can restrict which operations it is offered in the first place, which lowers the ceiling for every caller behind it. A read-only agent for a user who can write is a reasonable place to start.

Fix your permission model before you write an agent policy

An AI agent inherits whatever model you already have, including its gaps. If a support analyst can currently export the full customer table because nobody separated export from read, an assistant acting for that person can export the full customer table, faster, and without pausing to wonder whether it should.

So something that acts for a person, without being one, is not a reason to build a second permission system. It is a reason to make sure the first one was built properly.

Start with the granularity of your user roles and permissions. Everything else, including whatever your agents end up doing, follows from it.

LEVEL UP YOUR OPS GAME

Every action traced, for every human, AI agent, BPO, LLM, and workflow.

LEVEL UP YOUR OPS GAME

Every action traced, for every human, AI agent, BPO, LLM, and workflow.

LEVEL UP YOUR OPS GAME

Every action traced, for every human, AI agent, BPO, LLM, and workflow.

The operational infrastructure regulated companies grow on

Copyright © 2026 Forest

Design by Alasta & Built by Reiya Studio