Skip to content

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:

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:

Policy
├── Target
├── Condition
├── Action
└── Identifier

Each part serves a specific purpose.

ComponentPurposeJSON field
IDUniquely identifies the policy.id
TargetSpecifies which methods or workflows the policy applies to.target
ConditionDetermines when the rule should trigger.when
ActionDefines what happens when the condition is met.action

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

{
"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 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.

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

only evaluates requests that star GitHub repositories.

Another policy might target:

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

to validate payment requests.

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

{
"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:

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

Another might read:

Block requests that aren’t from a company email address.

{ "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.


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:

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

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

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

not - inverts the nested condition:

{
"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 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:

Everything Policy

Prefer:

Payment Limit
Repository Protection
Production Restriction
Email Validation

Smaller policies are easier to review and maintain.


Write descriptive IDs

Good:

block-production-deletes

Better than:

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:

Block:
A
B
C
D
E

Prefer explicitly allowing trusted values.

Allow:
Production
Staging

Allowlists are easier to reason about and generally more secure.


Validating Policies

Before deploying policies, always validate them.

Terminal window
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:

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.

Terminal window
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.