Your First Custom Policy

This tutorial walks you through creating a policy from scratch, testing it in the sandbox, and seeing it enforce decisions on real agent actions.

Time: ~5 minutes

Prerequisites: A running TameFlare instance with at least one registered agent.


Step 1: Understand the goal

We'll create a policy that:

  • Denies any attempt to delete a GitHub repository
  • Requires approval for merging pull requests to the main branch
  • Allows everything else

This is a common starting point — protect destructive actions, gate risky ones, and let safe actions through.


Step 2: Write the YAML

Go to Policies in the dashboard sidebar and click Create policy. Paste this YAML:

name: github-branch-protection
description: Protect main branch and prevent repo deletion
scope:
  action_types:
    - "github.*"
rules:
  - name: block-repo-deletion
    conditions:
      all:
        - field: action_spec.type
          operator: equals
          value: "github.repo.delete"
    decision: deny
    reason: "Repository deletion is not allowed through agents"
    risk_score: 95
 
  - name: require-approval-for-main-merge
    conditions:
      all:
        - field: action_spec.type
          operator: equals
          value: "github.pr.merge"
        - field: action_spec.parameters.branch_name
          operator: equals
          value: "main"
    decision: requires_approval
    reason: "Merging to main requires human approval"
    risk_score: 70
    approval:
      timeout_seconds: 3600
      approver_roles:
        - admin
        - owner
 
  - name: allow-other-github-actions
    conditions:
      all:
        - field: action_spec.type
          operator: starts_with
          value: "github."
    decision: allow
    reason: "Other GitHub actions are permitted"
    risk_score: 20

Click Create. The live validator will confirm the YAML is valid before you save.


Step 3: Test with the sandbox

Go back to Overview and open the Sandbox. Switch to the Custom tab and paste this action spec:

{
  "type": "github.repo.delete",
  "resource": {
    "provider": "github",
    "organization": "my-org",
    "repository": "important-repo"
  },
  "parameters": {},
  "risk_hints": {
    "is_destructive": true
  }
}

Click Evaluate. You should see:

  • Decision: Denied
  • Reason: "Repository deletion is not allowed through agents"
  • Risk score: 95

Now test the merge scenario:

{
  "type": "github.pr.merge",
  "resource": {
    "provider": "github",
    "organization": "my-org",
    "repository": "important-repo"
  },
  "parameters": {
    "branch_name": "main",
    "pr_number": 42
  },
  "risk_hints": {
    "affects_production": true
  }
}

Expected result: Requires approval, risk score 70.

And a safe action:

{
  "type": "github.issue.create",
  "resource": {
    "provider": "github",
    "organization": "my-org",
    "repository": "important-repo"
  },
  "parameters": {
    "title": "Bug report"
  },
  "risk_hints": {}
}

Expected result: Allowed (no matching deny or approval rule, and the scope matches github.*).


Step 4: Understand rule evaluation

TameFlare evaluates rules in this order:

  1. Scope check — if the action type doesn't match the policy's scope.action_types, the entire policy is skipped
  2. Deny wins — if any rule returns deny, the action is denied regardless of other rules
  3. Approval next — if no deny but any rule returns requires_approval, the action is held for approval
  4. Allow last — if no deny or approval rules match, the action is allowed
  5. Priority — lower number = higher priority (priority 1 evaluates before priority 100), but deny always wins regardless of priority

This means you don't need to worry about rule ordering within a policy — the deny-wins logic handles conflicts automatically.


Step 5: Refine and iterate

Common next steps:

  • Add environment scoping: Only enforce in production by adding scope.environments: ["production"]
  • Add agent scoping: Only apply to specific agents by adding scope.agents: ["deploy-bot"]
  • Adjust risk scores: Higher scores (0-100) appear more prominently in the dashboard
  • Use the demo sandbox: The demo auto-seeds a "GitHub Safe Defaults" policy pack on first run to give you a working baseline

Full policy reference

For the complete schema including all 14 condition operators, nested any/all combinators, and more examples, see Writing Policies.