Skip to content

Policy packs

A pack (now a policy template in the product) is a named, opinionated set of rules applied in one step. It answers “what should I turn on?” with a tested default instead of an empty policy screen. Packs are plain rules underneath — what lands is ordinary policy you can edit, version, and publish.

Terminal window
# Browse the catalog (dashboard: Policies → Templates)
tappass template list
tappass template get claude-code-safety
# Apply from the dashboard, or start from the set with policy create.

Packs declare params that resolve at apply time, so a rule never ships with someone else’s domain in it:

  1. Explicit --param key=value (repeatable)
  2. Workspace context — e.g. org_domain from your org’s settings (--org-domain overrides)
  3. The pack’s declared default

A param that can’t be resolved and is referenced by a rule is an error at apply time — never a silently empty domain list.

Credential-theft and runaway protection for coding agents (Claude Code, Cursor, Aider). Uses the first-class risk behavior types: a secret read taints the session.

Rule What it does
BlockToolSequence ×3 After any CREDENTIAL_ACCESS: no CODE_EXEC, no Gmail send, no Slack send for the rest of the session
BlockForbiddenPaths Blocks ~/.ssh/**, *.pem, *.key reads
BlockExfilDomains Blocks pastebin, webhook.site, requestbin, ngrok, transfer.sh
MaxSpend Per-session spend cap (param max_spend_usd, default 5)
SessionRateLimit 200 events per session — runaway loop breaker

Org-wide floor against the OWASP agentic risk classes.

Rule Covers
BlockPromptInjection (threshold param, default 0.7) LLM01 prompt injection
BlockSecrets / BlockResponseSecrets Credential leakage, both directions
BlockPII (on_pii: redact) PII stripped, task continues
BlockUnicodeTricks Hidden-character smuggling
AllowedModels (param allowed_models, required) Unapproved models
MaxTokensPerDay Daily token budget

Email/Slack sending inside a capability envelope — the showcase for capability governance.

Rule What it does
AllowCapabilities Envelope: external_messaging only; composes by intersection, can never widen
ConstrainCapabilityArgs Recipients must end in @{{org_domain}} — one rule across every tool that can send (gmail to, Slack channel)
BlockToolSequence ×2 Nothing sent after a credential read this session
RequireApproval (tier signed) External recipients require passkey-signed human approval — one approval authorizes exactly one send

Govern an agent that proposes and applies SAP plan adjustments — the vertical pack for ERP planning. Every write stays inside numeric and temporal guardrails, with human sign-off. The showcase for the numeric/temporal constraint operators.

Rule What it does
AllowCapabilities Envelope: sor_read + plan_adjust only — read the plan, adjust the plan, nothing else
ConstrainCapabilityArgs (max_deviation_pct) A new quantity may deviate at most max_qty_deviation_pct% (default 10) from the current planned value the call reports — fail-closed if that baseline is absent
ConstrainCapabilityArgs (within_days) A delivery date may be at most planning_horizon_days (default 30) in the future — no far-future edits nobody reviews
RequireApproval (tier signed) Four-eyes on plan writes — every adjustment signed off, bound one-to-one to the change

Both ceilings are tunable at apply time — set max_qty_deviation_pct and planning_horizon_days in the dashboard’s template-apply dialog (Policies → Templates → sap-supply-chain).

The pattern generalizes: the same max_deviation_pct / within_days operators drive finance (amount ceilings), devops (change windows), and data-pipeline packs.

Every shipped pack carries an eval corpus in the test suite: attack transcripts that must block, benign transcripts that must allow, evaluated through the same policy engine that runs production. A pack only ships if every rule in it fires. Params you can’t resolve fail at apply time, and rules that can’t fire fail composition — packs can’t contain dead controls.

Endpoint Purpose
GET /api/v2/packs List packs (names, descriptions, rule counts)
GET /api/v2/packs/{name} Full pack: params + rules (dashboard “apply pack” form)

Applying goes through the normal changes:stage / changes:apply flow — packs are content, not a side channel.