# Policy Rules

A policy defines **when a tool is allowed to execute**.

Every request made through Swytchcode is evaluated against your configured policies before an API call is made. If a policy condition matches, Swytchcode applies the configured action immediately.

Policies allow you to enforce business rules, security requirements, and operational constraints without changing your application code.

---

## How Policy Evaluation Works

Whenever a tool is executed, Swytchcode performs the following checks:

```text
Tool Execution Requested
           │
           ▼
Find matching policies
           │
           ▼
Evaluate conditions
           │
           ▼
Condition matched?
      │             │
     No            Yes
      │             │
      ▼             ▼
 Continue      Execute action
                    │
                    ▼
            Allow or Block Request
```

A policy only applies to the methods or workflows listed in its `target`.

---

## Anatomy of a Policy

Every policy consists of four parts:

```text
Policy
│
├── Target
├── Condition
├── Action
└── Identifier
```

Each part serves a specific purpose.

| Component | Purpose | JSON field |
|-----------|---------|------------|
| **ID** | Uniquely identifies the policy. | `id` |
| **Target** | Specifies which methods or workflows the policy applies to. | `target` |
| **Condition** | Determines when the rule should trigger. | `when` |
| **Action** | Defines what happens when the condition is met. | `action` |

Put together, a policy in `.swytchcode/integrations/policies.json` looks like this:

```json
{
  "id": "block-large-payments",
  "target": ["stripe.create_payment"],
  "when": {
    "field": "amount",
    "operator": ">",
    "value": 100000
  },
  "action": {
    "type": "POLICY_BLOCKED",
    "message": "Payments above the allowed limit are blocked."
  }
}
```

If `amount` on the request exceeds `100000`, `swy exec` (and the equivalent `swytchcode_exec` MCP call) stops before any network request is made, returns exit code `4`, and surfaces the `message` string back to the caller. See [Policy action types](/reference/troubleshooting/#policy-action-types) for the two supported `action.type` values (`POLICY_BLOCKED` and `AUTH_FAILED`).

---

## Choosing a Target

Policies only evaluate requests that match one of their targets. `target` is always an array of canonical IDs.

```json
{ "target": ["github.repo.star"] }
```

only evaluates requests that star GitHub repositories.

Another policy might target:

```json
{ "target": ["stripe.payment.create"] }
```

to validate payment requests.

A single policy can protect multiple methods if they share the same business rule.

```json
{
  "target": [
    "stripe.payment.create",
    "stripe.payment.refund",
    "stripe.payment.capture"
  ]
}
```

---

## Writing Conditions

Conditions determine **when** a policy should apply.

A condition always evaluates information from the request being executed.

Examples include:

- Payment amount
- Currency
- Email address
- Branch name
- Environment
- Region
- Request metadata

A simple condition might read:

> Block any payment greater than 10,000.

which is written as:

```json
{ "field": "amount", "operator": ">", "value": 10000 }
```

Another might read:

> Block requests that aren't from a company email address.

```json
{ "field": "email", "operator": "not_contains", "value": "@yourcompany.com" }
```

Policies should describe business intent rather than implementation details. The full set of supported operators - equality/ordering (`==`, `!=`, `>`, `>=`, `<`, `<=`), membership (`in`, `not_in`), substring (`contains`, `not_contains`), string matching (`starts_with`, `ends_with`, `matches`), presence (`exists`, `not_exists`, `empty`, `not_empty`), and time comparisons (`before`, `after`, `between`, `outside`) - is documented in the [policies.json reference](/configuration/policy-json/).

---

## Combining Conditions

Many production rules require more than one condition.

Swytchcode lets you combine leaf conditions (`field`/`operator`/`value`) into a group condition using `operator: "all" | "any" | "not"` plus a `conditions` array.

**`all` (AND)** - every condition must match:

```json
{
  "operator": "all",
  "conditions": [
    { "field": "amount", "operator": ">", "value": 10000 },
    { "field": "currency", "operator": "==", "value": "usd" }
  ]
}
```

---

**`any` (OR)** - at least one condition must match:

```json
{
  "operator": "any",
  "conditions": [
    { "field": "role", "operator": "==", "value": "admin" },
    { "field": "role", "operator": "==", "value": "support" }
  ]
}
```

---

**`not`** - inverts the nested condition:

```json
{
  "operator": "not",
  "conditions": [
    { "field": "test_mode", "operator": "exists" }
  ]
}
```

Groups can nest inside groups, so you can build rules like "amount over 10,000 AND currency is USD or EUR AND NOT test mode" as a single `when` block. See [Nested Conditions](/configuration/policy-json/#nested-conditions) in the policies.json reference for a full worked example.

---

## Common Policy Patterns

The most effective policies are usually simple.

### Spending Limits

Prevent expensive operations.

Examples:

- Payments above a threshold
- Refund limits
- Credit issuance limits

---

### Production Protection

Prevent accidental changes to production systems.

Examples:

- Block delete operations
- Prevent destructive workflows
- Disable infrastructure changes

---

### Organization Rules

Restrict operations based on company policies.

Examples:

- Company email domains only
- Approved GitHub organizations
- Approved cloud projects

---

### Environment Restrictions

Different environments often require different rules.

For example:

Development:

- Relaxed limits
- Test data
- Sandbox providers

Production:

- Strict validation
- Protected resources
- Higher security

---

### Time-Based Rules

Restrict execution during specific time windows.

Examples:

- Business hours only
- Maintenance windows
- Scheduled deployments

---

## Designing Good Policies

When writing policies, follow these principles.

### Keep policies focused

Instead of one large policy:

❌

```text
Everything Policy
```

Prefer:

✅

```text
Payment Limit

Repository Protection

Production Restriction

Email Validation
```

Smaller policies are easier to review and maintain.

---

### Write descriptive IDs

Good:

```text
block-production-deletes
```

Better than:

```text
policy-4
```

Policy IDs should describe their purpose.

---

### Avoid deeply nested logic

If a policy becomes difficult to understand, consider splitting it into multiple policies.

Simple policies are easier to debug and less likely to introduce unexpected behavior.

---

### Prefer allowlists

Instead of trying to block every unsafe value:

```text
Block:
A
B
C
D
E
```

Prefer explicitly allowing trusted values.

```text
Allow:
Production
Staging
```

Allowlists are easier to reason about and generally more secure.

---

## Validating Policies

Before deploying policies, always validate them.

```bash
swy policy validate
```

Validation checks for:

- Invalid operators
- Missing required fields
- Duplicate IDs
- Empty targets
- Invalid value types
- Unknown action types
- Incorrect condition structures

Fix validation errors before running production workloads.

---

## Testing Policies

Policies should be tested before deployment.

A typical workflow looks like this:

```text
Write Policy
      │
      ▼
Validate Policy
      │
      ▼
Test in Sandbox
      │
      ▼
Review Behavior
      │
      ▼
Deploy to Production
```

Testing policies against sandbox environments helps ensure they behave as expected without affecting live systems.

```bash
swy policy validate
swy exec <canonical_id> --dry-run
```

`--dry-run` validates the request against the tool's input schema without making the live API call. Once a policy is live, `swy audit policy` shows you which requests it has actually blocked, so you can tell a too-strict rule from a working one.

---

## Best Practices

- Write one policy per business rule.
- Use descriptive policy IDs.
- Prefer allowlists whenever possible.
- Keep conditions simple and readable.
- Validate policies after every change.
- Test policies in sandbox environments before production.
- Review policies alongside application code during code review.
- Remove unused policies to keep configurations easy to maintain.

---

## Next steps

- [Production Guardrails](https://docs.swytchcode.com/policies/production-guardrails/) - Recommended safeguards for running AI agents against production systems.
- [Best Practices](https://docs.swytchcode.com/policies/best-practices/) - Recommendations for maintainable, predictable, secure policy configurations.
- [Policies overview](https://docs.swytchcode.com/policies/overview/) - The policy engine that decides what an agent can do, when, and how.
