Skip to content

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=mask


Without flags, governing an AI agent requires:

  1. Deploy TapPass proxy (one-time)
  2. Write pipeline policy in YAML/Rego (complex, separate system)
  3. Switch to TapPass dashboard to tweak settings
  4. 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 system
response = 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.


Option 1: HTTP header (any language, any framework)

Section titled “Option 1: HTTP header (any language, any framework)”
Terminal window
curl https://tappass.internal/v1/chat/completions \
-H "X-TapPass-Flags: mode=observe, email=internal:cogniqor.be" \
-d '{"model": "gpt-4o-mini", "messages": [...]}'
from tappass import Agent
agent = Agent("http://localhost:9620", flags={
"email": "internal:cogniqor.be",
"pii": "mask",
})
response = agent.chat("Summarize the HR report")
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"
},
)

Overall governance posture. Controls how the pipeline handles detections.

ModeBehaviourUse case
observeFull pipeline runs, everything logged, nothing blocked. Response includes detection details.Week 1: “show me what you’d catch”
warnDetections logged and flagged, but traffic flows through.Staging: see violations without breaking anything
enforceNormal operation. Detections trigger configured actions (block, redact, notify).Production (default)
lockdownAny detection triggers a block. Most aggressive posture.Incident response, high-risk scenarios
X-TapPass-Flags: mode=observe

Default: enforce


Email tool call restrictions. Governs what happens when the LLM instructs the agent to send an email.

ModeBehaviourUse 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
reviewqueueEmail is held for human approval. (Coming soon)Early production: human in the loop
blockAll email tool calls blocked entirely.Agents that should never email
allowNo email restrictions.Production: you trust the agent
X-TapPass-Flags: email=mirror:jens@cogniqor.be
X-TapPass-Flags: email=internal:cogniqor.be
X-TapPass-Flags: email=block

Default: allow

How mirror works:

The agent calls send_email(to="ceo@bigcorp.com", subject="Q4 Report", body="..."). TapPass rewrites the call before it executes:

  • tojens@cogniqor.be
  • subject[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.

ModeBehaviour
maskPII detected → replaced with [MASKED_SSN], [MASKED_EMAIL], etc. Response still flows.
blockResponse contains PII → entire response blocked.
flagPII detected → logged and tagged in audit trail, but passed through.
offNo PII scanning.
X-TapPass-Flags: pii=mask

Default: off


Cost and token caps.

ModeBehaviour
dev$1/session, $5/day: hard stop.
standard$10/session, $50/day.
custom:<per_call>:<per_session>Set your own limits.
unlimitedNo caps.
X-TapPass-Flags: budget=dev
X-TapPass-Flags: budget=custom:0.50:20

Default: unlimited


Tool call restrictions.

ModeBehaviour
allowlist:<tool1>:<tool2>Only listed tools can execute. Everything else blocked.
denylist:<tool1>:<tool2>Listed tools blocked. Everything else allowed.
confirmEvery tool call pauses for approval. (Coming soon)
logAll tool calls execute but are logged with full arguments.
blockNo tool calls at all: chat only.
X-TapPass-Flags: tools=denylist:send_email:delete_user:drop_table
X-TapPass-Flags: tools=allowlist:search:read_file:get_user

Default: log


File operation restrictions.

ModeBehaviour
read_onlyCan read any file, all writes blocked.
projectWrites only within the project/workspace directory.
sandboxWrites redirected to a sandboxed path. You review before promoting.
blockNo file operations at all.
allowUnrestricted.
X-TapPass-Flags: files=read_only

Default: allow


Database operation restrictions.

ModeBehaviour
read_onlySELECT only. INSERT/UPDATE/DELETE/DROP blocked.
safe_writeSELECT + INSERT + UPDATE allowed. DELETE/DROP/TRUNCATE/ALTER blocked.
blockNo database tool calls at all.
X-TapPass-Flags: db=read_only

Default: safe_write


Secret handling in responses.

ModeBehaviour
redactAPI keys, tokens, passwords → replaced with [REDACTED]. Response flows.
blockSecrets detected → response blocked entirely.
flagSecrets detected → logged, but passed through.
X-TapPass-Flags: secrets=redact

Default: redact


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 makes
agent = 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 settings
response = agent.chat(
"Send the salary report to the board",
flags={"email": "block", "mode": "lockdown"},
)
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"
},
)
Terminal window
export TAPPASS_FLAGS="mode=observe, pii=mask, email=internal:cogniqor.be"

The SDK reads TAPPASS_FLAGS as the default when no flags are provided.

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 flags

Flags are resolved from multiple sources. Most restrictive wins.

1. Per-call flags (SDK flags= argument or X-TapPass-Flags header)
↓ overrides
2. Agent-level defaults (set on agent registration)
↓ overrides
3. Org-level policy (admin sets in dashboard)
↓ overrides
4. Catalog defaults (built-in)
Developer sends: mode=observe, pii=off
Agent default: pii=mask
Org policy: pii=mask (locked), mode minimum=enforce
Resolved:
mode = enforce (org minimum overrides observe)
pii = mask (org lock overrides developer's "off")

Org admins can lock flags so developers can’t override them, and set minimums for the mode flag.

# Set via Admin API or dashboard
flag_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 one

Why 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.


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.


Every team follows a similar path from “just exploring” to “production-ready”:

WeekFlagsWhat you’re doing
1mode=observeSee what TapPass would catch. Zero risk.
2mode=enforce, budget=devStart enforcing, cap spend while testing.
3+ email=mirror:you@company.com, pii=maskHandle obvious risks. See email output.
4email=internal:company.com, tools=denylist:...Tighten for staging.
5mode=enforce, email=internal:company.comProduction with domain restrictions.
8Full pipeline config, org locksEnterprise governance. Flags are the onramp.

Each step is one line change. No dashboard visit. No YAML editing.


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",
})
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
})
agent = Agent("http://localhost:9620", flags={
"email": "block",
"db": "read_only",
"files": "project",
"budget": "standard",
})
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
})

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=observe
X-TapPass-Flags: mode=enforce, email=mirror:jens@cogniqor.be, pii=mask
X-TapPass-Flags: tools=denylist:send_email:delete_user:drop_table, budget=dev
X-TapPass-Flags: email=internal:cogniqor.be, files=read_only, db=read_only

Part of TapPass by TapPass.