Skip to main content

Agent configs · free template

Guardrail Configuration Template

The caps, ceilings, and kill-switch rules a team signs off before any agent touches spend.

Fill in your values.

Everything you enter below is substituted live into the template — copy or download it and the file is already yours. Skip anything you're not sure of; unfilled fields stay as {{PLACEHOLDER}} markers. Values save in your browser and carry across every template in the library.

Your values · 55 fields

Your copy, ready to run.

The preview below updates as you type. Copy it to your clipboard or download it as guardrail-config.md.

Guardrail Configuration Template · 218 lines
# Guardrail Configuration — {{ACCOUNT_OR_CLIENT_NAME}} (the account, client, or brand this config governs)

> **Rule zero: no automation runs until this document is signed.**
> This config is the agreement between the humans who own the budget and the
> automation that can touch it. The agent proposes; a human confirms; the log
> records. Enforcement lives in two places — platform-level caps set inside the
> ad accounts themselves (the backstop), and this policy file the agent checks
> on every run. Never in a prompt alone.

---

## How to use this template

1. Fill every `{{PLACEHOLDER}}`. Do not delete a section you "don't need yet" — mark it `not_in_scope` with a one-line reason instead, so the decision is on record.
2. Walk the completed config in one sitting with the automation owner, the second approver, and whoever runs the ad accounts day to day.
3. Set the budget caps and exclusion lists **inside each ad platform first** (account-level rules, campaign budget limits, exclusion lists). The platform is the backstop; this file is the policy the agent evaluates.
4. Complete the sign-off block. Store the file where the whole team can read it — the same shared home as your automation register.
5. Any later edit to this config follows the same approval path it defines. Log the edit in the config change log at the bottom.
6. If your agent reads a Campaign AGENTS.md at session start, mirror the caps below into its guardrail section — this document is the signed source of truth; the AGENTS.md carries the agent-facing copy. Brand voice and claim rules live in the companion Campaign CLAUDE.md, not here.

**Blank means restrictive.** Any field left unfilled resolves to the most restrictive option: no write access, no auto-apply, queue for human. An unset value is never permission.

---

## 1. Scope and ownership

| Field | Value |
|---|---|
| Config ID | GC-{{YYYY}}-{{NN}} (year + sequence number, e.g. GC-2026-01) |
| Automation owner | {{OWNER_NAME}} (the one named person with authority to approve or block changes) |
| Second approver | {{SECOND_APPROVER}} (required for changes above the escalation threshold in section 2) |
| Systems covered | {{SYSTEMS_LIST}} (every platform this config governs, e.g. Google Ads, Meta Ads, workflow tools) |
| Account IDs in scope | {{ACCOUNT_IDS}} (exact account/CID numbers — anything not listed is out of scope and read-only) |
| Agent / automation identity | {{AGENT_NAME}} (the named agent, script, or workflow this config binds) |
| Effective date | {{EFFECTIVE_DATE}} |
| Status | draft / approved / live (circle one — only "live" permits execution) |

---

## 2. Guardrail configuration

```yaml
guardrail_config:

  # ------------------------------------------------------------------
  # ACCESS — read-only is the default state, not a temporary phase.
  # Write access is granted per action type, through scoped, revocable
  # credentials. The boundary is enforced by the credentials, not the prompt.
  # ------------------------------------------------------------------
  access:
    default_mode: read_only
    write_access_granted_for: [{{WRITE_ACTION_TYPES}}]   # (only the action types listed here may write, e.g. pause_entity, adjust_bid, shift_budget — empty list = fully read-only)
    credential_scope: "{{CREDENTIAL_SCOPE}}"             # (which API scopes / MCP connections the agent holds, and who can revoke them)
    out_of_scope_systems: read_only_always

  # ------------------------------------------------------------------
  # BUDGET CAPS — hard ceilings. No action may exceed these, and the
  # same caps are mirrored inside each ad platform as the backstop.
  # All values are yours to set; nothing here is a recommendation.
  # ------------------------------------------------------------------
  budget_caps:
    account_daily_cap: {{ACCOUNT_DAILY_CAP}}             # (max total daily spend across the account)
    account_monthly_cap: {{ACCOUNT_MONTHLY_CAP}}         # (max total monthly spend across the account)
    per_campaign_daily_cap: {{CAMPAIGN_DAILY_CAP}}       # (max daily spend any single campaign may reach)
    max_spend_agent_can_move_per_day: {{DAILY_MOVE_CAP}} # (total budget the automation may reallocate in one day, across all runs)
    mirrored_in_platform: true                           # (confirm the caps above are also set natively in each ad platform)

  # ------------------------------------------------------------------
  # CHANGE CEILINGS — how big any single run is allowed to be.
  # Small, frequent, reversible changes beat large, rare ones.
  # ------------------------------------------------------------------
  change_ceilings:
    max_bid_change_per_run_pct: {{MAX_BID_SHIFT_PCT}}       # (max % any bid may move in a single run)
    max_budget_change_per_run_pct: {{MAX_BUDGET_SHIFT_PCT}} # (max % any campaign budget may move in a single run)
    max_entities_changed_per_run: {{MAX_ENTITIES_PER_RUN}}  # (max campaigns/ad groups/keywords one run may touch)
    max_runs_per_day: {{MAX_RUNS_PER_DAY}}                  # (how many times per day the automation may act at all)
    cooldown_after_change: {{COOLDOWN_PERIOD}}              # (minimum wait before the same entity may be changed again, e.g. 72h)
    min_data_before_acting: "{{MIN_DATA_THRESHOLD}}"        # (conversion/click floor before bid or budget logic may act — no decisions on thin data)

  # ------------------------------------------------------------------
  # APPROVAL THRESHOLDS — the line between "apply and log" and
  # "queue for a human". When in doubt, a change queues.
  # ------------------------------------------------------------------
  approval_thresholds:
    auto_apply_below: "{{AUTO_APPLY_THRESHOLD}}"       # (changes under this size apply automatically and are logged, e.g. budget moves under a set $ or %)
    queue_for_human_above: "{{HUMAN_QUEUE_THRESHOLD}}" # (changes at or above this size wait for the owner's explicit sign-off)
    second_approver_above: "{{ESCALATION_THRESHOLD}}"  # (changes at or above this size need the owner AND the second approver)
    always_require_human:                              # (never auto-applied regardless of size)
      - new_campaign_goes_live
      - new_audience_or_targeting_change
      - any_change_to_a_protected_entity
      - any_change_to_this_config
      - {{ADDITIONAL_ALWAYS_HUMAN}}                    # (add your own — e.g. landing page swaps, geo expansion)
    approval_channel: "{{APPROVAL_CHANNEL}}"           # (where requests land, e.g. Slack channel or email address)
    approval_request_includes: [diff, before_state, rollback_step]
    no_response_default: no_action                     # (an unanswered request expires as a rejection — silence is never a yes)
    approval_expiry: {{APPROVAL_EXPIRY}}               # (how long a queued request waits before expiring, e.g. 48h)

  # ------------------------------------------------------------------
  # EXCLUSIONS — protected entities the automation may read but
  # never change, no matter what any trigger says.
  # ------------------------------------------------------------------
  exclusions:
    protected_campaigns: [{{PROTECTED_CAMPAIGNS}}]     # (campaign names/IDs the agent must never modify, e.g. brand campaigns, launches in flight)
    protected_keywords: [{{PROTECTED_KEYWORDS}}]       # (keywords/negatives that may not be added, removed, or re-bid)
    protected_audiences: [{{PROTECTED_AUDIENCES}}]     # (audiences/lists that may not be edited or targeted anew)
    brand_exclusion_lists: [{{BRAND_EXCLUSION_FILES}}] # (placement/content exclusion lists applied in-platform, e.g. competitor_names.txt)
    rule: protected_entities_are_read_only_to_the_agent_without_exception

  # ------------------------------------------------------------------
  # PAUSE & KILL SWITCH — conditions that stop the automation,
  # and how a human turns it all off in one step.
  # ------------------------------------------------------------------
  pause_conditions:                                    # (automation halts itself and alerts the owner when any of these is true)
    - daily_spend_reaches: "{{PAUSE_SPEND_LEVEL}}"     # (e.g. a set % of the daily cap before the cap itself is hit)
    - conversion_tracking_outage_detected: true        # (no acting on broken data)
    - guardrail_check_fails_or_config_unreadable: true # (cannot verify policy = cannot act)
    - consecutive_failed_or_errored_runs: {{MAX_CONSECUTIVE_FAILURES}}  # (how many failed runs in a row force a halt)
    - {{CUSTOM_PAUSE_CONDITION}}                       # (yours — e.g. site outage, feed error, tracking template change)
  kill_switch:
    who_can_pull_it: [{{KILL_SWITCH_HOLDERS}}]         # (owner plus at least one other person — never a single point of absence)
    how: "{{KILL_SWITCH_MECHANISM}}"                   # (the one-step action: revoke the agent's credentials and disable its schedule)
    effect: all_write_access_revoked_and_schedules_disabled
    restart_requires: owner_signoff_plus_logged_reason # (restart is a decision, not a reflex — the log records why it stopped and why it resumed)

  # ------------------------------------------------------------------
  # ROLLBACK — every change reverses in one step, or it doesn't ship.
  # ------------------------------------------------------------------
  rollback:
    before_state_captured: always                      # (the prior value is logged before any change is applied)
    rollback_step_written_before_change: true          # (if the undo step cannot be written down, the change is not ready)
    who_executes_rollback: {{ROLLBACK_EXECUTOR}}       # (named person or role; the agent may propose a revert but a human applies it above threshold)
    rollback_target_time: {{ROLLBACK_SLA}}             # (how quickly a flagged change must be reverted once the owner calls it, e.g. same business day)

  # ------------------------------------------------------------------
  # AUDIT LOG — Trigger / Action / Impact, append-only.
  # If it isn't logged, it didn't happen — and it wasn't allowed.
  # ------------------------------------------------------------------
  audit_log:
    format: trigger_action_impact
    required_fields:
      - timestamp
      - action_id
      - trigger_that_fired                             # (the condition that initiated the run)
      - guardrails_result                              # (pass / fail / queued, with which threshold applied)
      - action_taken                                   # (or "no_action" — quiet runs are logged too)
      - before_value
      - after_value
      - approver                                       # ("auto" below threshold; a named human above it)
      - rollback_step
    append_only: true                                  # (entries are never edited or deleted; corrections are new entries)
    no_action_runs_logged: true
    location: "{{LOG_LOCATION}}"                       # (shared sheet, warehouse table, or file the whole team can read)
    export_formats: [csv, json]
    retention: {{LOG_RETENTION}}                       # (how long entries are kept, e.g. per client contract or internal audit policy)

  # ------------------------------------------------------------------
  # CONFLICTS & REVIEW — what happens when rules collide, and
  # how often humans re-check the whole system.
  # ------------------------------------------------------------------
  conflict_protocol: "{{CONFLICT_RULE}}"               # (when two triggers fire conflicting actions, which wins — the other is queued, never silently dropped)
  review:
    audit_cadence: {{AUDIT_CADENCE}}                   # (how often live rules are diffed against this config and the register, e.g. weekly)
    audit_owner: {{AUDIT_OWNER}}                       # (who runs the diff and logs that the check happened)
    unregistered_automation_found: investigate_then_log_or_switch_off
    config_review_cadence: {{CONFIG_REVIEW_CADENCE}}   # (how often this document itself is re-approved, e.g. quarterly or on team change)
    threshold_refinements: proposed_with_evidence_never_silently_applied
```

---

## 3. Approval matrix — quick reference

Fill this from section 2 so anyone can answer "does this need sign-off?" without parsing YAML.

| Change type | Below {{AUTO_APPLY_THRESHOLD}} | {{HUMAN_QUEUE_THRESHOLD}} and above | Never automated |
|---|---|---|---|
| Bid adjustment (within ceiling) | Auto-apply + log | Queue for {{OWNER_NAME}} | — |
| Budget shift (within ceiling) | Auto-apply + log | Queue for {{OWNER_NAME}} | — |
| Pause underperforming entity | Auto-apply + log | Queue for {{OWNER_NAME}} | — |
| Add negative keywords | Auto-apply + log | Queue for {{OWNER_NAME}} | — |
| New campaign live | — | — | Human only |
| Audience / targeting change | — | — | Human only |
| Anything on a protected list | — | — | Human only |
| Edit to this config | — | — | Owner + {{SECOND_APPROVER}} |

---

## 4. Log line format

Every run writes at least one Trigger / Action / Impact line in this shape — including runs where nothing happened. The fields below are slots, not placeholders to pre-fill:

```
{{TIMESTAMP}} | {{ACTION_ID}} | trigger:{{TRIGGER_NAME}} | guardrails:{{PASS_FAIL_QUEUED}} | action:{{ACTION_OR_NO_ACTION}} | before:{{BEFORE_VALUE}} | after:{{AFTER_VALUE}} | approver:{{AUTO_OR_NAME}} | rollback:{{ROLLBACK_STEP_REF}}
```

---

## 5. Sign-off

This configuration takes effect only when every line below is complete. Signing confirms: the caps are mirrored in-platform, the credentials match the access section, and the log location exists and is readable by the team.

| Role | Name | Date | Signature / recorded approval |
|---|---|---|---|
| Automation owner | {{OWNER_NAME}} | | |
| Second approver | {{SECOND_APPROVER}} | | |
| Account lead (day-to-day) | {{ACCOUNT_LEAD}} (whoever operates the accounts daily and will see the automation's effects first) | | |

---

## 6. Config change log

Changes to this document follow its own approval path (owner + second approver, always human). Append only.

| Date | Section changed | Old value → new value | Reason | Approved by |
|---|---|---|---|---|
| {{EFFECTIVE_DATE}} | Initial version | — | Config created | {{OWNER_NAME}}, {{SECOND_APPROVER}} |
| | | | | |

A single config file that defines what your marketing automation is allowed to do before it runs: budget caps, per-run change ceilings, approval thresholds, protected lists, pause and kill-switch conditions, a rollback rule, and an audit-log standard. It exists because the limits that would have prevented most automation incidents are usually the ones nobody wrote down. Fill the placeholders, get the named owner's sign-off, and every agent, script, and rule you add afterward inherits the same boundaries.

Before an AI agent or automated rule gets write access to any ad account, CRM, or budget
When an agency needs a per-client guardrail agreement the client can read and sign
After an automation incident, to replace verbal limits with written, checkable policy
When scaling from one automation to many and each new rule needs gates it can inherit
Set every cap and threshold to your own numbers — the fields are deliberately blank because limits belong to the budget owner, not a template.
Agencies: duplicate the file per client, keep field names identical so audits compare cleanly across accounts.
Running spreadsheet-based governance? Keep the YAML as the signed policy and mirror sections 2-3 as tabs in your register sheet.
Running an MCP-connected agent? Store this file where the agent reads it every run, mirror its caps into your Campaign AGENTS.md, and keep the signed copy under version control.
Trim the approval matrix rows to the action types you actually granted in access.write_access_granted_for — unused rows invite scope creep.
Used in practice by the Automation Governance build guide — the step-by-step build this template plugs into.