Skip to Content
GuidesPolicy Design

Policy Design

This guide covers best practices for designing policies that balance security with agent productivity.

Rule ordering

Policy rules are evaluated top-to-bottom, and the first matching rule wins. Order matters:

[ { "action": "update_deal", "resource_pattern": "crm:deal:*", "decision": "require_approval", "risk_level": "high", "conditions": { "require_approval_if_stage": ["closed_won"] } }, { "action": "update_deal", "resource_pattern": "crm:deal:*", "decision": "allow", "risk_level": "low" }, { "action": "*", "resource_pattern": "*", "decision": "deny", "risk_level": "medium" } ]

In this example:

  1. Closing a deal as won requires approval (most specific rule first)
  2. Other deal updates are allowed
  3. Everything else is denied (catch-all at the bottom)

Always place more specific rules before more general ones. A catch-all deny at the bottom ensures that unrecognized actions are blocked by default.

Resource patterns

Use wildcards strategically:

PatternMatchesUse case
crm:deal:123Exact resourceLock down a specific high-value deal
crm:deal:*All dealsGeneral deal policy
crm:*All CRM resourcesBroad CRM policy
*EverythingCatch-all default

Using conditions

Amount thresholds

Use max_amount_change to escalate large changes:

{ "action": "update_deal", "resource_pattern": "crm:deal:*", "decision": "allow", "risk_level": "medium", "conditions": { "max_amount_change": 50000 } }

Deals under $50,000 are auto-approved. Larger changes require human review.

Stage gates

Use require_approval_if_stage for critical transitions:

{ "conditions": { "require_approval_if_stage": ["closed_won", "closed_lost"] } }

Field protection

Use deny_fields to prevent modification of sensitive fields:

{ "conditions": { "deny_fields": ["owner_id", "created_at", "organization_id"] } }

deny_fields results in a hard deny. If an agent’s payload contains any of the listed fields, the request is denied regardless of the base decision.

Common patterns

Permissive start

Begin with broad allow rules and tighten as you learn:

[ { "action": "*", "resource_pattern": "*", "decision": "allow", "risk_level": "low" } ]

Review receipts to identify risky actions, then add specific rules.

Deny by default

The safest approach — only allow explicitly listed actions:

[ { "action": "read_deal", "resource_pattern": "crm:deal:*", "decision": "allow", "risk_level": "low" }, { "action": "update_deal", "resource_pattern": "crm:deal:*", "decision": "require_approval", "risk_level": "high" }, { "action": "*", "resource_pattern": "*", "decision": "deny", "risk_level": "medium" } ]

Tiered risk

Assign risk levels to help approvers prioritize:

Risk levelUse for
lowRead operations, minor updates
mediumStandard write operations
highFinancial changes, deletions, stage transitions

Testing with the simulator

Before activating a new policy version, use the policy simulator to verify behavior:

curl -X POST https://your-relynt-instance/v1/policy-simulator \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "action": "update_deal", "resource": "crm:deal:123", "payload": { "amount": 100000, "stage": "closed_won" } }'

Test edge cases:

  • Requests that should be allowed
  • Requests that should be denied
  • Requests that should require approval
  • Requests with boundary values (e.g., amount exactly at the threshold)
Last updated on