# IMentorActionPolicy interface

> The IMentorActionPolicy interface of Novior.MentorAgent.Abstractions.Interfaces: Decides, in the application's own code, whether a user may use one of its…

- URL: https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy
- Verified with: MentorAgent 1.2.0
- Last updated: 2026-10-27
- Packages: Novior.MentorAgent.Abstractions

Decides, in the application's own code, whether a user may use one of its actions at all, and whether one call may run: a permission per company or per record, a rule on the arguments, a check against the application's data. For the application's actions only, on every surface: the coordinator's, a specialist's, a team member's, an agent source's, the tools of the MCP servers the application consumes, and the MCP server it serves. Never for MentorAgent's own tools (`navigate_to`, `remember`, `forget_all`, `load_skill`, `read_skill_resource`, `route_to_specialist`, a team's tool, `invoke_ui_action`).

Register it with `AddMentorActionPolicy<T>()`, or as a singleton [`IMentorActionPolicy`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy) of your own; every policy registered is asked, in the order of registration. It is a singleton: what it needs from the conversation's scope it resolves from [`MentorActionRequest.Services`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionrequest#services).

A call is decided in this order: the roles of the action, [`IMentorActionPolicy.IsAllowedAsync`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy#isallowedasync), [`IMentorActionPolicy.BeforeActionAsync`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy#beforeactionasync), the confirmation, then the action. A policy that does not answer within `MentorOptions.ActionPolicyTimeout`, or throws, stops the call; when MentorAgent decides what to offer, it leaves the action out. Its exception's message is never logged, only its type.

Both methods have a default body, so a policy writes only the one it needs. A member added to this interface in a later version comes with a default implementation.

## Definition

Namespace: `Novior.MentorAgent.Abstractions.Interfaces`. Package: `Novior.MentorAgent.Abstractions`.

`public interface IMentorActionPolicy`

```shell
dotnet add package Novior.MentorAgent.Abstractions
```

## Methods

### `BeforeActionAsync`

`ValueTask<MentorActionVerdict> BeforeActionAsync(MentorActionRequest request, CancellationToken cancellationToken)`

Before every call, once the roles and [`IMentorActionPolicy.IsAllowedAsync`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy#isallowedasync) have let it through, and before the confirmation: [`MentorActionVerdict.Proceed`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionverdict#proceed) has no objection, [`MentorActionVerdict.Confirm`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionverdict#confirm) asks the user first, [`MentorActionVerdict.Stop`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionverdict#stop) stops the call with a reason the model reads. Every policy is asked, and the strictest answer wins: Stop, then Confirm, then Proceed. Proceed never removes a confirmation the action asks for. Where nobody can confirm — the MCP server, a task from another agent — Confirm refuses the call.

**Parameters**

- `request`: The call: the action, its arguments, the user, and where it comes from.
- `cancellationToken`: Cancelled when the policy takes longer than `ActionPolicyTimeout`, and with the turn.

### `IsAllowedAsync`

`ValueTask<bool> IsAllowedAsync(MentorActionRequest request, CancellationToken cancellationToken)`

Whether this user may use this action at all. Asked when MentorAgent decides what to offer — the coordinator's tools for a turn, the MCP server's `tools/list` — with [`MentorActionRequest.Stage`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionrequest#stage)[`MentorActionStage.Offer`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionstage) and no arguments; and before every call, with [`MentorActionStage.Call`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-models/mentoractionstage) and the arguments, again after the user confirmed. `false`: the action is not offered, and a call to it does not run. Asked for every action offered on every turn: keep it fast, for example with a cache per user.

**Parameters**

- `request`: The action, the user, and where the call comes from.
- `cancellationToken`: Cancelled when the policy takes longer than `ActionPolicyTimeout`, and with the turn.

---

- Previous: [IMentorActionObserver interface](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionobserver.md)
- Next: [IMentorAgent interface](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoragent.md)
