# Policies

Catalyst controls runtime behaviour declaratively through **policies**. A policy is a project-scoped resource that binds to one or more [Application Identities](https://docs.diagrid.io/concepts/identities) — the per-workload identity Catalyst issues to every application, agent, and MCP server. Catalyst fetches the policies that apply to each ID and enforces them inline on every relevant call. No application code changes are required, and policies can be tuned per environment without redeploying.

Catalyst exposes the following policy kinds.

## Access policies

**Access policies** control which apps can invoke a target — an application, an agent, or an MCP server. You attach access control rules to the target; the default action can be set to **deny**, so the target is unreachable until a calling app is explicitly allow-listed. Authorization is enforced inside Catalyst at the service-invocation boundary, so a denied call is rejected before it reaches the target.

Access policies apply to any workload that other workloads call: services, agents, and MCP servers alike. The default posture differs by resource type:

| Resource | Default posture | How it is applied |
|----------|----------------|-------------------|
| **Agent** | Allow all callers. | Catalyst creates a managed `Configuration` with `defaultAction: allow` when the agent is created. Lock down with `diagrid agent access grant <agent> --caller '*' --action deny`. |
| **MCP server** | Deny all callers and all tools. | Catalyst creates a managed `MCPServerAccessPolicy` with an empty rule set when the server is created. Grant access with `diagrid mcpserver access grant`. |
| **Application** | Allow all callers. | Apps use the project's default `Configuration`. Lock down with `diagrid app access grant <app> --caller '*' --action deny`. |

See [Secure service invocation with access control](https://docs.diagrid.io/operate/project-operations/policies/service-invocation) for the rules model and the CLI commands, and [IDs](https://docs.diagrid.io/operate/project-operations/ids) for day-2 operations.

## Workflow access policies

**Workflow access policies** govern which apps can schedule workflows and activities on other apps — the authorization layer for multi-application workflows. They apply only to **workflow applications** (applications that run workflows). A policy is a pure allow-list: without one, all cross-app workflow calls are allowed; once a policy covers an app, every cross-app call must match a rule or it is denied. An app can always run its own workflows, so a policy only gates calls from other apps.

See [Secure workflows with access policies](https://docs.diagrid.io/operate/project-operations/policies/workflows) for the rules model and the CLI commands.

## Resiliency policies

**Resiliency policies** describe how Catalyst should recover from transient failures on outbound calls. An outbound call is any call from an app out to another application, or to a component such as a state store, pub/sub broker, or binding. A resiliency policy can express retries (constant or exponential), timeouts on individual calls, and circuit breakers that trip after a configurable number of consecutive failures. The same policy can target multiple apps by listing them in its scope, or be scoped narrowly to a single one.

See [Resiliency](https://docs.diagrid.io/concepts/policies/resiliency) for the full concept, and [Apply resiliency policies](https://docs.diagrid.io/operate/project-operations/policies/resiliency) for the CLI commands.

## MCP access policies

**MCP access policies** govern which caller apps may use which tools on an [MCP server](https://docs.diagrid.io/concepts/mcp). Catalyst creates one (`MCPServerAccessPolicy`) automatically with every MCP server and locks its lifecycle to that server. The policy is a deny-by-default, per-tool, per-caller allow-list: a newly created server denies everything until you grant access, tool discovery is filtered to authorized tools, and unauthorized calls are rejected with `403`. You manage it with the `diagrid mcpserver access` commands rather than authoring it by hand.

See [Control tool access](https://docs.diagrid.io/develop/mcp/mcp-access-policies) to apply it, and [MCP](https://docs.diagrid.io/concepts/mcp) for the broader picture.

## Enforcement model

Policies are defined at the project level and bound to apps. When a workload makes a call through Catalyst, the relevant policies are evaluated before the call is dispatched. A retried request is retried inside Catalyst, so the application making the request sees a single logical call. A tripped circuit breaker fails fast without dispatching a request at all. A request that violates an access policy never reaches the destination app. Because enforcement happens in Catalyst rather than in application code, the same workload gets the same guarantees in every environment, and operators can change those guarantees without touching application code.

```mermaid
flowchart LR
  APP(Workload
  App / Agent)
  APPID(ID)
  POL{Policy
  decision}:::decision
  COMP(Target
  App / Component)
  DENY((Blocked))
  APP-->APPID
  APPID-->POL
  POL--"allow"-->COMP
  POL--"deny"-->DENY

  classDef decision stroke:#ed8936
```

## See also

- [Resiliency](https://docs.diagrid.io/concepts/policies/resiliency): retries, timeouts, and circuit breakers.
- [Workflow access policies](https://docs.diagrid.io/operate/project-operations/policies/workflows): who can schedule workflows and activities across apps.
- [Service invocation access control](https://docs.diagrid.io/operate/project-operations/policies/service-invocation): which apps can invoke a target app, and on which methods.
- [Application Identities](https://docs.diagrid.io/concepts/identities): the unit policies bind to.
- [MCP](https://docs.diagrid.io/concepts/mcp): where MCP access policies fit in the protocol story.
- [Policies reference](https://docs.diagrid.io/references/policies): declarative syntax for every policy kind.
