Governance Flags
Declare what your agent should and shouldn’t do. in one HTTP header.
Governance Flags let developers express security and compliance intent at the call site, without editing pipeline policies, Rego rules, or YAML files. Add a header, your agent is governed.
X-TapPass-Flags: mode=observe, email=internal:cogniqor.be, pii=maskTable of contents
Section titled “Table of contents”- Why flags?
- Quick start
- Flag reference
- SDK integration
- Resolution order
- Org policies and locks
- Audit trail
- Recommended progression
- Examples
Why flags?
Section titled “Why flags?”Without flags, governing an AI agent requires:
- Deploy TapPass proxy (one-time)
- Write pipeline policy in YAML/Rego (complex, separate system)
- Switch to TapPass dashboard to tweak settings
- Go back to code, test, switch to dashboard, repeat
With flags, governance is a property of your API call:
from tappass import Agent
agent = Agent("http://localhost:9620")
# Governance lives in your code, not a separate systemresponse = agent.chat( "Draft an email to the client about the Q4 results", flags={"email": "mirror:jens@cogniqor.be", "pii": "mask"},)No context switching. No YAML. No dashboard visits. Test, iterate, ship.
Quick start
Section titled “Quick start”Option 1: HTTP header (any language, any framework)
Section titled “Option 1: HTTP header (any language, any framework)”curl https://tappass.internal/v1/chat/completions \ -H "X-TapPass-Flags: mode=observe, email=internal:cogniqor.be" \ -d '{"model": "gpt-4o-mini", "messages": [...]}'Option 2: Python SDK
Section titled “Option 2: Python SDK”from tappass import Agent
agent = Agent("http://localhost:9620", flags={ "email": "internal:cogniqor.be", "pii": "mask",})
response = agent.chat("Summarize the HR report")Option 3: OpenAI SDK (drop-in)
Section titled “Option 3: OpenAI SDK (drop-in)”from openai import OpenAI
client = OpenAI(base_url="http://localhost:9620/v1")response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "Hello"}], extra_headers={ "X-TapPass-Flags": "mode=observe, email=block, pii=mask" },)Flag reference
Section titled “Flag reference”Overall governance posture. Controls how the pipeline handles detections.
| Mode | Behaviour | Use case |
|---|---|---|
observe | Full pipeline runs, everything logged, nothing blocked. Response includes detection details. | Week 1: “show me what you’d catch” |
warn | Detections logged and flagged, but traffic flows through. | Staging: see violations without breaking anything |
enforce | Normal operation. Detections trigger configured actions (block, redact, notify). | Production (default) |
lockdown | Any detection triggers a block. Most aggressive posture. | Incident response, high-risk scenarios |
X-TapPass-Flags: mode=observeDefault:
enforce
Email tool call restrictions. Governs what happens when the LLM instructs the agent to send an email.
| Mode | Behaviour | Use case |
|---|---|---|
mirror:<address> | All emails redirect to <address>. Subject gets [AI TEST] prefix. Original recipient logged. | Development: see exactly what the agent would send |
internal:<domain> | Only recipients at @<domain> allowed. External recipients blocked. | Staging/production: agent can’t email outside your org |
reviewqueue | Email is held for human approval. (Coming soon) | Early production: human in the loop |
block | All email tool calls blocked entirely. | Agents that should never email |
allow | No email restrictions. | Production: you trust the agent |
X-TapPass-Flags: email=mirror:jens@cogniqor.beX-TapPass-Flags: email=internal:cogniqor.beX-TapPass-Flags: email=blockDefault:
allow
How mirror works:
The agent calls send_email(to="ceo@bigcorp.com", subject="Q4 Report", body="..."). TapPass rewrites the call before it executes:
to→jens@cogniqor.besubject→[AI TEST] Q4 Report
You get the email in your inbox. The original recipient (ceo@bigcorp.com) is logged in the audit trail. The agent doesn’t know the difference.
Detected email tools: send_email, send_mail, gmail_send, outlook_send, smtp_send, sendgrid_send, compose_email, send_message. Also auto-detects by arguments (any tool with to + subject + body parameters).
PII handling in responses.
| Mode | Behaviour |
|---|---|
mask | PII detected → replaced with [MASKED_SSN], [MASKED_EMAIL], etc. Response still flows. |
block | Response contains PII → entire response blocked. |
flag | PII detected → logged and tagged in audit trail, but passed through. |
off | No PII scanning. |
X-TapPass-Flags: pii=maskDefault:
off
budget
Section titled “budget”Cost and token caps.
| Mode | Behaviour |
|---|---|
dev | $1/session, $5/day: hard stop. |
standard | $10/session, $50/day. |
custom:<per_call>:<per_session> | Set your own limits. |
unlimited | No caps. |
X-TapPass-Flags: budget=devX-TapPass-Flags: budget=custom:0.50:20Default:
unlimited
Tool call restrictions.
| Mode | Behaviour |
|---|---|
allowlist:<tool1>:<tool2> | Only listed tools can execute. Everything else blocked. |
denylist:<tool1>:<tool2> | Listed tools blocked. Everything else allowed. |
confirm | Every tool call pauses for approval. (Coming soon) |
log | All tool calls execute but are logged with full arguments. |
block | No tool calls at all: chat only. |
X-TapPass-Flags: tools=denylist:send_email:delete_user:drop_tableX-TapPass-Flags: tools=allowlist:search:read_file:get_userDefault:
log
File operation restrictions.
| Mode | Behaviour |
|---|---|
read_only | Can read any file, all writes blocked. |
project | Writes only within the project/workspace directory. |
sandbox | Writes redirected to a sandboxed path. You review before promoting. |
block | No file operations at all. |
allow | Unrestricted. |
X-TapPass-Flags: files=read_onlyDefault:
allow
Database operation restrictions.
| Mode | Behaviour |
|---|---|
read_only | SELECT only. INSERT/UPDATE/DELETE/DROP blocked. |
safe_write | SELECT + INSERT + UPDATE allowed. DELETE/DROP/TRUNCATE/ALTER blocked. |
block | No database tool calls at all. |
X-TapPass-Flags: db=read_onlyDefault:
safe_write
secrets
Section titled “secrets”Secret handling in responses.
| Mode | Behaviour |
|---|---|
redact | API keys, tokens, passwords → replaced with [REDACTED]. Response flows. |
block | Secrets detected → response blocked entirely. |
flag | Secrets detected → logged, but passed through. |
X-TapPass-Flags: secrets=redactDefault:
redact
SDK integration
Section titled “SDK integration”Python SDK: constructor flags (apply to all calls)
Section titled “Python SDK: constructor flags (apply to all calls)”from tappass import Agent
# These flags apply to every call this agent makesagent = Agent("http://localhost:9620", flags={ "mode": "observe", "email": "mirror:jens@cogniqor.be", "pii": "mask", "budget": "dev",})
response = agent.chat("Summarize the HR report")print(response.pipeline.flags) # {'mode': 'observe', 'email': 'mirror:...', ...}Python SDK. per-call flags (override constructor)
Section titled “Python SDK. per-call flags (override constructor)”agent = Agent("http://localhost:9620", flags={"pii": "mask"})
# This specific call uses stricter settingsresponse = agent.chat( "Send the salary report to the board", flags={"email": "block", "mode": "lockdown"},)OpenAI SDK. extra headers
Section titled “OpenAI SDK. extra headers”from openai import OpenAI
client = OpenAI(base_url="http://localhost:9620/v1")response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": "Hello"}], extra_headers={ "X-TapPass-Flags": "email=internal:cogniqor.be, pii=mask" },)Environment variable (zero-code)
Section titled “Environment variable (zero-code)”export TAPPASS_FLAGS="mode=observe, pii=mask, email=internal:cogniqor.be"The SDK reads TAPPASS_FLAGS as the default when no flags are provided.
CrewAI / LangChain
Section titled “CrewAI / LangChain”from tappass import Agent
agent = Agent("http://localhost:9620", flags={ "email": "internal:cogniqor.be", "pii": "mask",})agent.configure_environment()# CrewAI / LangChain now routes through TapPass with these flagsResolution order
Section titled “Resolution order”Flags are resolved from multiple sources. Most restrictive wins.
1. Per-call flags (SDK flags= argument or X-TapPass-Flags header) ↓ overrides2. Agent-level defaults (set on agent registration) ↓ overrides3. Org-level policy (admin sets in dashboard) ↓ overrides4. Catalog defaults (built-in)Example
Section titled “Example”Developer sends: mode=observe, pii=offAgent default: pii=maskOrg policy: pii=mask (locked), mode minimum=enforce
Resolved: mode = enforce (org minimum overrides observe) pii = mask (org lock overrides developer's "off")Org policies and locks
Section titled “Org policies and locks”Org admins can lock flags so developers can’t override them, and set minimums for the mode flag.
# Set via Admin API or dashboardflag_policy: pii: mode: mask locked: true # developers CANNOT turn PII masking off
email: mode: internal params: ["cogniqor.be"] locked: true # external email always blocked
mode: minimum: enforce # developers can't go below enforce # (lockdown is allowed. it's more restrictive)
secrets: mode: redact locked: false # developers can override this oneWhy this matters: The platform team sets the security floor. Developers can add restrictions (more secure) but can’t remove them (less secure). A developer can escalate from enforce to lockdown, but can’t downgrade from enforce to observe if the org minimum is enforce.
Audit trail
Section titled “Audit trail”Active flags are recorded in every audit event:
{ "event_type": "llm_call", "agent_id": "hr-bot", "flags": { "mode": "enforce", "email": "internal:cogniqor.be", "pii": "mask" }, "pipeline": { "classification": "INTERNAL", "steps_run": 12, "blocked": false }}The audit trail shows exactly which flags were active for every call, including whether they were set by the developer, the agent default, or an org lock. This creates a complete governance evidence chain.
Recommended progression
Section titled “Recommended progression”Every team follows a similar path from “just exploring” to “production-ready”:
| Week | Flags | What you’re doing |
|---|---|---|
| 1 | mode=observe | See what TapPass would catch. Zero risk. |
| 2 | mode=enforce, budget=dev | Start enforcing, cap spend while testing. |
| 3 | + email=mirror:you@company.com, pii=mask | Handle obvious risks. See email output. |
| 4 | email=internal:company.com, tools=denylist:... | Tighten for staging. |
| 5 | mode=enforce, email=internal:company.com | Production with domain restrictions. |
| 8 | Full pipeline config, org locks | Enterprise governance. Flags are the onramp. |
Each step is one line change. No dashboard visit. No YAML editing.
Examples
Section titled “Examples””I want to test my agent safely"
Section titled “”I want to test my agent safely"”agent = Agent("http://localhost:9620", flags={ "mode": "observe", # log everything, block nothing "email": "mirror:me@company.com", # emails come to me "budget": "dev", # $1 cap})"Production: never email externally, mask PII"
Section titled “"Production: never email externally, mask PII"”agent = Agent("http://localhost:9620", flags={ "email": "internal:cogniqor.be", "pii": "mask", "secrets": "redact",})"Lockdown: incident response mode"
Section titled “"Lockdown: incident response mode"”agent = Agent("http://localhost:9620", flags={ "mode": "lockdown", # block on any detection "email": "block", # no emails at all "tools": "block", # chat only "files": "read_only", # no writes})"CI/CD pipeline agent"
Section titled “"CI/CD pipeline agent"”agent = Agent("http://localhost:9620", flags={ "email": "block", "db": "read_only", "files": "project", "budget": "standard",})"Customer-facing chatbot”
Section titled “"Customer-facing chatbot””agent = Agent("http://localhost:9620", flags={ "tools": "block", # chat only, no tool use "pii": "mask", # mask any PII in responses "secrets": "redact", # never leak API keys "budget": "custom:0.10:5", # tight budget per session})Header format
Section titled “Header format”X-TapPass-Flags: flag1=mode1, flag2=mode2:param1, flag3=mode3:param1:param2- Comma-separated key=value pairs
- Values can include colon-separated parameters
- Whitespace is trimmed
- Unknown flags are silently ignored
- Invalid modes are silently ignored
Examples:
X-TapPass-Flags: mode=observeX-TapPass-Flags: mode=enforce, email=mirror:jens@cogniqor.be, pii=maskX-TapPass-Flags: tools=denylist:send_email:delete_user:drop_table, budget=devX-TapPass-Flags: email=internal:cogniqor.be, files=read_only, db=read_only