# Best Practices

Well-designed policies help AI agents operate safely without slowing down development.

## Start with sandbox mode

Develop and test workflows in sandbox mode before enabling production execution:

```bash
swy init --mode=sandbox
```

Sandbox mode lets you exercise the full pipeline - trusted tools, policy evaluation, execution - against non-production resources, so a policy mistake never touches real data.

---

## Block destructive operations

Prevent accidental changes by blocking operations such as `DELETE`-style calls, database resets, and infrastructure removal. In practice this means a policy that always fires for the target method:

```json
{
  "id": "block-repo-delete",
  "target": ["github.repo.delete"],
  "when": { "field": "name", "operator": "exists" },
  "action": {
    "type": "POLICY_BLOCKED",
    "message": "Repository deletion is disabled in this environment."
  }
}
```

`name` is a field every `github.repo.delete` request has, so this condition always matches and the method is effectively disabled - the request never reaches the GitHub API.

---

## Block sensitive actions by default

Swytchcode's policy engine can only allow or block a request - there's no built-in human-approval step. To get "requires approval" behavior in practice, write a policy that blocks the action outright, then treat loosening or removing that policy as a reviewed code change (PR + merge) rather than a runtime approval click.

Good candidates for a default-block policy:

- Payments and refunds above a threshold
- Billing and subscription changes
- Production deployments
- User and permission management

```json
{
  "id": "block-refunds",
  "target": ["stripe.payment.refund"],
  "when": { "field": "id", "operator": "exists" },
  "action": {
    "type": "POLICY_BLOCKED",
    "message": "Refunds are disabled - remove this policy in a reviewed change to enable them."
  }
}
```

---

## Keep policies simple

Create small, focused rules instead of a few large, complex ones - one `id` per business rule, not one rule with a dozen nested `all`/`any`/`not` groups.

Simple policies are easier to review and maintain, and easier to identify from `swy audit policy` output when they fire.

---

## Test changes before deployment

Whenever you modify `policies.json`, run `swy policy validate` to catch structural errors (unknown operators, duplicate IDs, missing fields), then verify the specific behavior with a dry run:

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

`--dry-run` validates the request against the tool's input schema without calling the live API. Deploy the change, then confirm it behaves as expected by checking `swy audit policy` for the requests it actually blocks.

---

## Review policies regularly

As your project grows, review policy rules with `swy policy list` to ensure they still reflect your application's security requirements, and check `swy audit policy` periodically for violations that suggest a rule is too strict (or too loose).

## Next Steps

- [Policy Rules](https://docs.swytchcode.com/policies/policy-rules/) - Learn how to define custom policy rules using conditions, operators, and actions to control tool execution.
- [Production Guardrails](https://docs.swytchcode.com/policies/production-guardrails/) - Discover best practices for safely deploying AI agents and protecting production systems.
- [CLI Overview](https://docs.swytchcode.com/cli/overview/) - Understand how the Swytchcode CLI manages projects, integrations, authentication, and policy enforcement.
