> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Policies

> Control which tools are made available to your agents and how they can use them.

<Warning>
  **Policies are in early access**. User interfaces may change and not every capability is live yet (see [Capabilities](#capabilities)). For feedback or suggestions, contact our support team.
</Warning>

**Policies** control which tools an agent may use, and how, on behalf of the member it acts for. StackOne checks the active policies that apply to that member before a tool call reaches the provider, and refuses the call when an enforced policy denies it.

<Frame>
  <img src="https://mintcdn.com/stackone-60/kri0MTCUjjX_lETu/images/secure/policies-overview.svg?fit=max&auto=format&n=kri0MTCUjjX_lETu&q=85&s=6edb3a9c1c030230a4ef172dfc58ee95" alt="Flow diagram with three lanes. An AI agent makes a tool call and policies are checked. Allowed: the provider is called and the response returns unchanged. Redact PII or Read a field: the provider is called and the response returns with PII redacted or fields masked. Denied, including Write a field denials: the provider is not called and a refusal is returned. All three responses come back to the AI agent. Write a field is marked as not applied in the current early access phase" width="1928" height="840" data-path="images/secure/policies-overview.svg" />
</Frame>

<Note>
  **Policies** are available on **Gateway** plans, and are enabled per organization. If the page reports that Policies are not enabled, contact StackOne support.
</Note>

## How a policy is evaluated

A policy carries a single **rule** that allows or denies capabilities. Rules are made up of 4 parts:

| Part | Options | What it means |
| - | - | - |
| **Who it applies to** | **Everyone**, **Users**, **Groups** | The members whose agents the rule governs. Groups come from [Manage Groups](/secure/identity-and-access/roles-and-groups/groups). |
| **What it does** | **Allow**, **Deny** | A deny rule refuses exactly what it covers for those users or groups. An allow rule restricts nothing and cannot undo a deny. |
| **Capabilities** | **Use a tool**, **Read a field**, **Write a field**, **Redact PII** | The operations the rule covers. One capability per kind of access, each narrowed on its own terms. See [Capabilities](#capabilities) below. |
| **Applies to** | **Everything**, **A connector category**, **A connector**, **An account**, **Specific tools** | Where the capability is covered. **Tools matching** narrows any target with a name pattern. |

Four guarantees hold across every policy:

<Card title="A deny always wins" icon="gavel" horizontal>
  When policies overlap, a matching deny refuses the call whatever any allow says.
</Card>

<Card title="Policies narrow access" icon="filter" horizontal>
  [Connector Profile scoping](/secure/scoping-connectors) and [account access](/secure/identity-and-access/roles-and-groups/connector-profile-access) apply restrictions before policies.
</Card>

<Card title="Policies follow the member" icon="user-check" horizontal>
  Policies apply when the member is known, which is the case for [AI platform](/connect/overview) sessions. A call made with a project API key is memberless — govern that traffic with [Connector Profile scoping](/secure/scoping-connectors) instead.
</Card>

<Card title="Policies stay in their project" icon="diagram-project" horizontal>
  A policy belongs to the project it is created in and governs calls made in that project only. To apply the same rule in several projects, create it in each.
</Card>

### Capabilities

A **capability** is the kind of access a rule governs: running a tool, reading or writing a field, or receiving PII in responses. Denying one removes that access for the users or groups the rule covers.

<Warning>
  **Write a field** rules do not currently apply in the current Early Access phase. The rules can be saved but this capability will not be taken into account when or how tools are called.
</Warning>

| Capability | What denying it does |
| - | - |
| **Use a tool** | Refuses the call. The agent may not run the tool at all. |
| **Read a field** | Masks the field in responses. |
| **Write a field** | Refuses calls that would change the field. |
| **Redact PII** | Redacts the chosen classes of PII (email addresses, phone numbers, SSNs, or credit card numbers) from responses. Ids and keys stay intact. |

Rules can carry more than one capability. Capabilities are alternatives rather than conditions: the rule applies where **any** one of them matches, so adding a second says "or also" rather than narrowing the first. Each is scoped on its own terms, so one rule can deny a tool outright on one connector and only mask a field on another.

## Create a policy

<Steps>
  <Step title="Open Policies">
    Select the project, open [**Project Settings > Policies**](https://app.stackone.com/settings/policies), and click **Create policy**. Give the policy a descriptive name.
  </Step>

  <Step title="Pick the mode and status">
    Two settings control whether the policy acts:

    * **Status**: **Active** policies are consulted from the project's next call. **Inactive** policies are stored and never consulted.
    * **Enforcement**: **Monitor only** records decisions without refusing anything. **Enforce** refuses the calls the policy denies.

    Start new deny rules in **Monitor only**, then monitor the logs for recorded decisions. Once you're happy, set it to **Enforce**.
  </Step>

  <Step title="Choose who it applies to">
    Select **Everyone**, **Users**, or **Groups**, then search for the users or groups the rule covers.
  </Step>

  <Step title="Choose what it does">
    Select **Deny** to refuse the capability for those users or groups, or **Allow** to state permitted use without restricting anything.
  </Step>

  <Step title="Set the capability and its targets">
    Add the [capabilities](#capabilities) the rule governs:

    <Tabs>
      <Tab title="Use a tool">
        Denying **Use a tool** refuses the call.

        Choose which targets it applies under **Applies to**:

        * **Everything** covers every tool in the project.
        * **A connector category** covers every tool on every connector in the category, including connectors added later.
        * **A connector** covers every tool on the connectors you pick.
        * **An account** covers the tools of specific [Linked Accounts](/gateway/concepts/linked-accounts). Search accounts by name or owner.
        * **Specific tools** lets you pick a connector, then the tools on it by name.

        To narrow the tools covered by the target selection, enter a name pattern under **Tools matching** (see the pattern syntax below). An empty pattern covers every tool the targets include, so a deny refuses every call to them. A capability takes either specific tools or a pattern, not both.
      </Tab>

      <Tab title="Read a field">
        Denying **Read a field** masks the field in responses.

        Choose which targets it applies under **Applies to**:

        * **Everything** covers every connector and account in the project.
        * **A connector category** covers every connector in the category, including ones added later.
        * **A connector** covers the connectors you pick.
        * **An account** covers specific [Linked Accounts](/gateway/concepts/linked-accounts). Search accounts by name or owner.

        To narrow the fields covered by the target selection, enter a pattern on the field's path in the response under **Fields matching** (see the pattern syntax below). An empty pattern covers every field the targets include, so a deny masks every field in scope.
      </Tab>

      <Tab title="Write a field">
        <Warning>
          **Write a field** rules do not currently apply in the current Early Access phase. The rules can be saved but this capability will not be taken into account when or how tools are called.
        </Warning>

        Denying **Write a field** refuses calls that would change the field.

        Choose which targets it applies under **Applies to**:

        * **Everything** covers every connector and account in the project.
        * **A connector category** covers every connector in the category, including ones added later.
        * **A connector** covers the connectors you pick.
        * **An account** covers specific [Linked Accounts](/gateway/concepts/linked-accounts). Search accounts by name or owner.

        To narrow the fields covered by the target selection, enter a pattern on the field's path under **Fields matching** (see the pattern syntax below). An empty pattern covers every field the targets include, so a deny refuses every call that would change one.
      </Tab>

      <Tab title="Redact PII">
        Denying **Redact PII** redacts the chosen classes of PII from responses. Ids and keys stay intact.

        Choose which targets it applies under **Applies to**:

        * **Everything** covers every connector and account in the project.
        * **An account** covers specific [Linked Accounts](/gateway/concepts/linked-accounts). Search accounts by name or owner.

        Under **Which PII to redact**, select one or more classes. There is no pattern to enter.

        **Redact PII** never blocks a call. A response that cannot be scanned (it is streamed, too large, or the scan fails) is returned unredacted.
      </Tab>
    </Tabs>

    <br />

    <Accordion title="Pattern syntax - wildcards">
      * `*` is the only wildcard, and it matches any run of characters.
      * A pattern has to cover the whole name: `salary` matches only something named exactly that, so use `*salary*` to match it anywhere.
      * Matching is case-sensitive.
      * `?`, `[a-z]`, and `{a,b}` are ordinary characters here, not wildcards. A pattern using one saves cleanly and then never matches anything.

      | Pattern | Matches | Does not match |
      | - | - | - |
      | `*delete*` | `workday_delete_worker` | `workday_remove_worker` |
      | `salary` | `salary` | `employee.compensation.salary` |
      | `*Delete*` | Nothing, since matching is case-sensitive. | `workday_delete_worker` |
    </Accordion>
  </Step>

  <Step title="Add exemptions">
    For a deny rule, use **Exempt from this rule** to name users or groups the rule does not apply to. Another matching deny can still refuse the call.
  </Step>

  <Step title="Review and create">
    Review the policy:

    * **Plain Text**: the panel footer restates the rule in plain words, for example:

      > Everyone in this project may not use a tool matching `*delete*` on Workday, except Finance (Group).

    * **Cedar**: the exact statement the engine will evaluate, in [Cedar syntax](https://docs.cedarpolicy.com/policies/syntax-policy.html). The view is read-only; change the form and the statement follows.

    * **JSON**: the same statement in Cedar's JSON encoding.

    Then click **Create policy**.

    <Note>
      If you used the assistant, the button reads **Accept changes and create**. See [Build a policy using chat](#build-a-policy-using-chat).
    </Note>
  </Step>
</Steps>

<Frame caption="A deny rule on the Create policy panel, with Monitor only and Active selected and Fields / Cedar / JSON above the form.">
  <img src="https://mintcdn.com/stackone-60/MRw_NcTkLCDG7kLr/images/secure/policies-create-tool-rule.png?fit=max&auto=format&n=MRw_NcTkLCDG7kLr&q=85&s=c2bae43edfe4363ae092aee47feee8fb" alt="Create policy panel with Policy chat on the left and the form on the right, showing a policy named Contractors cannot use tools that delete records, Enforcement set to Monitor only, Status set to Active, the audience set to the Contractors group, and a Deny rule on the Use a tool capability" width="1322" height="896" data-path="images/secure/policies-create-tool-rule.png" />
</Frame>

## Build a policy using chat

**Policy chat** is available on policy create and edit. Describe the rule you want in your own words and the form will be updated automatically, showing you the suggested changes:

* Suggestions are highlighted in the form, with the previous value shown underneath.
* Each suggestion can be applied or reverted individually.
* All changes can be applied using the buttons at the top of the form or simply by clicking **Accept changes and create**/**Accept changes and save**.

<Frame caption="Policy chat beside the form. The assistant looked up the Contractors group, proposed a deny rule, and left three changes marked for review.">
  <img src="https://mintcdn.com/stackone-60/MRw_NcTkLCDG7kLr/images/secure/policies-assistant-panel.png?fit=max&auto=format&n=MRw_NcTkLCDG7kLr&q=85&s=66c258bf38192cf9f68dbcec81021ffb" alt="Create policy panel split in two, with Policy chat on the left showing completed search_principals and update_policy_draft tool calls and an explanation of the proposed rule, and the policy form on the right with a bar reading 3 changes from the assistant need review" width="1322" height="896" data-path="images/secure/policies-assistant-panel.png" />
</Frame>

### What policy chat can access

Policy chat can look things up in the project as it drafts, and the transcript shows each lookup as it runs:

| It can find | So you can say |
| - | - |
| Users and groups | *Exempt payroll*, (where you have a group defined as "payroll") |
| Connectors and categories | *Block writes to any HRIS connector* |
| The tools on a connector | *Stop the delete ones on Workday* |
| Linked accounts | *Only the Acme production account* |
| Related tool call logs | *Stop this tool returning some of the fields it returned* |

<Note>
  By default, only a tool call's tool, connector and caller are exposed.

  With [advanced logging](/secure/observability#advanced-logs) enabled, the assistant can read the request/response payloads to help define field related capabilities.
</Note>

For example, using a prompt like:

> Stop contractors deleting records

1. The assistant searches existing groups, sets **Who it applies to** to `Groups` and populates with `Contractors`.
2. Writes a deny on **Use a tool** with a `*delete*` pattern, with **applies to** set to `Everything`.

The chat will also flag to you what a rule may miss. E.g. A pattern matching `delete` does not catch a connector that uses tool names using `remove` or `archive`. So you can confirm and ask it to also apply these patterns.

### Starting from logs

Policy creation can be initiated from a specific log instead of the policies page.

<Steps>
  <Step>
    Go to [StackOne Logs](https://app.stackone.com/logs).
  </Step>

  <Step>
    Select the log of a call you want to create a policy from.
  </Step>

  <Step>
    Click **Use in policy** at the top of the panel.

    This takes you to the **Policies** page with the context of the log selected.
  </Step>

  <Step>
    Either select an existing policy **OR** create a new policy by clicking **Create policy**.
  </Step>

  <Step>
    The **Policy chat** now has the context of the log selected.

    Continue by using the policy chat to craft the policy. For example:

    > *This call should not have been allowed to return salary*

    > *This person should not have been allowed to make it*

    See [Build a policy using chat](#build-a-policy-using-chat).
  </Step>
</Steps>

## Testing a policy before enforcing it

Two checks come before enforcing:

1. **Test against personas**: in the create and edit panel, **Test this policy against personas** shows what the rule would decide for the members you choose, without making a call.
2. **Monitor only**: set the policy's **Enforcement** to **Monitor only** and applicable tool calls are flagged as calls the policy would have applied to, while continuing unaffected.

Only once **Enforcement** is set to **Enforce** are tool calls blocked or modified as defined by the policy.

## Duplicating policies

Instead of starting with a blank new policy, an existing policy can be used as a template.

<Steps>
  <Step>
    On an existing policy's row in the Policies table, click the **...** button. Then click **Duplicate**.
  </Step>

  <Step>
    A new policy is drafted with the original policy's details except:

    * **Name**: original name is appended with `(copy)`.
    * **Enforcement**: set to **Monitor only**.
    * **Status**: set to **Inactive**.
  </Step>

  <Step>
    Edit as needed then click **Create policy** when done.
  </Step>
</Steps>

<Warning>
  A policy whose rule the builder cannot read, or that holds more than one statement, cannot be duplicated.
</Warning>

## What a denied call returns

When an enforced policy refuses a tool call, the request fails with HTTP `403` before anything reaches the underlying provider. The refusal returns to the agent as the tool result.

```json theme={null}
{
  "message": "Action 'workday_delete_worker' is not permitted by project policy",
  "errorType": "POLICY_DENIED_ERROR",
  "level": "project"
}
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Why is a pattern matching the wrong tools, or none at all?">
    * **It matches nothing.** The pattern has to cover the whole name: `salary` only matches a tool named exactly that, so use `*salary*`.
      `?`, `[a-z]`, and `{a,b}` do not perform any special matching.
    * **It misses tools you expected.** Matching is case-sensitive: `*Delete*` misses `workday_delete_worker`. A pattern matches exactly rather than describing a behaviour: `*delete*` does not catch a tool named `workday_remove_worker`.
    * **It matches more than you expected.** `*` matches any run of characters, underscores included, so `*create*` could cover `list_created_employees`.
  </Accordion>

  <Accordion title="Why is a policy not taking effect?">
    Check the following in order:

    1. The policy is **Active**.
    2. Its mode is **Enforce**.
    3. The acting member is in its audience (and not exempt).
    4. The call is made in the project the policy was created in.
    5. The tool name or pattern matches exactly, including case.
    6. The caller is a member connected through an [AI platform](/connect/overview), so the call carries their identity. A call made with a project API key alone names no member, so no policy governs it.
  </Accordion>

  <Accordion title="Can I see policy decisions in request logs?">
    Yes, on an action log. Open the record and select the **Policy** tab.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Scoping Connectors" icon="sliders" href="/secure/scoping-connectors">
    Set which actions each Connector Profile exposes.
  </Card>

  <Card title="Groups" icon="users" href="/secure/identity-and-access/roles-and-groups/groups">
    Maintain the groups your policies apply to.
  </Card>

  <Card title="Connector Profile Access" icon="share-nodes" href="/secure/identity-and-access/roles-and-groups/connector-profile-access">
    Control who can link accounts on a profile.
  </Card>

  <Card title="Observability" icon="chart-line" href="/secure/observability">
    Configure request logging and retention.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.