# Segregation of duties on approvals

Segregation of duties — who may approve. A person who approves an agent's held write must hold that right themselves; each decision records whether they did, and enforce mode refuses one who did not.

Letting an agent's held write go ahead lends the agent the decider's authority for that one call. So the person deciding should hold that authority: someone who could not post to the ERP should not be able to make an agent do it with one click.

## What is checked

When a person decides a held MCP call, Liyagent asks whether that person could make the same call themselves, the way the console decides a person's own tool call:

1. Cedar `read` on the MCP server, as that person, with their role;
2. Cedar `call_tool` on the tool (`Tool::"server/tool"`), as that person;
3. for a tool that can write, the permissions the agent requires of a person it acts for (`require_invoker_permissions` in the agent's runtime, `tickets.write` by default).

The check runs in `approvals.approve`, so it applies to every door a decision comes through: the console, batch decisions, the mobile app, the `liya` CLI and Teams cards. Pipeline proposals and framework releases are not MCP calls and keep their own checks.

## Modes

`TICKETIQ_APPROVAL_ENTITLEMENT` (default `audit`):

| Mode | What happens |
| --- | --- |
| `audit` (default) | The answer is recorded on the decision (`entitlement` on the approval record) and on its [trust-ledger](/docs/govern/trust-ledger) receipt. A missing entitlement writes `agent.approval.entitlement.missing`. The decision still goes ahead, so no flow that works today gains a new blocker. |
| `enforce` | A decider without the entitlement is refused with 403. The request stays pending for someone who holds the right, the refusal is audited, and a `decision` receipt with status `refused_approver` is written. |
| `off` | No check. |

Start with `audit`, read the `agent.approval.entitlement.missing` rows to see who would be refused, give them the permissions or move those decisions to people who hold them, then switch to `enforce`.
