ProductsProducts
Chio-Wall
Record signed evidence for a defined cross-domain tool-access denial using Chio receipts and checkpoints.
Chio-Wall is a separate product from Mercury. Mercury concerns trading-workflow evidence; Chio-Wall records a defined information-domain tool-access denial. Both use Chio guards, receipts, and evidence exports. Chio-Wall does not cover model memorization, prompt injection, or broader information-barrier operations.
The bounded lane
This implementation records one scenario: a research actor is denied a execution-domain tool before the call crosses the boundary. The chio-wallbinary fixes the parameters below so exports use the same structure.
| Field | Value |
|---|---|
| Buyer motion | control_room_barrier_review |
| Control surface | tool_access_domain_boundary |
| Source domain | research |
| Protected domain | execution |
| Policy reference | chio.wall.research_execution_barrier.v1 |
| Control owner | barrier-control-room |
| Support owner | chio-wall-ops |
The lane does not approve a generic barrier platform, additional buyer motions, more domain-boundary combinations, folding Chio-Wall into Mercury, or multi-product hardening. Those are deferred, and the export records that limit explicitly.
The denied cross-domain request
The scenario is one request. The actor research-agent-alpha, scoped to the research domain, requests execution_oms.submit_order, a tool in the protected execution domain. Chio-Wall evaluates the request through the same tool guard Chio uses everywhere else, configured fail-closed.
The evaluation is an McpToolGuard built from an McpToolConfig whose default_action is McpDefaultAction::Block and whose allow list is the research-domain allowlist: research_news.read, research_model.run, research_review.export. The requested tool is not on that list, so the guard denies it fail-closed before research can reach execution.
{
"schema": "chio.wall.guard_outcome.v1",
"requestId": "chio-wall-request-2026-07-15-01",
"workflowId": "workflow-information-domain-barrier",
"decision": "deny",
"guardName": "mcp-tool",
"pipelineName": "guard-pipeline",
"matchedPolicy": "chio.wall.research_execution_barrier.v1",
"evaluatedTool": "execution_oms.submit_order",
"allowedTools": ["research_news.read", "research_model.run", "research_review.export"],
"reason": "tool `execution_oms.submit_order` is outside the allowlist for the `research` domain and is denied fail-closed before `research` access can cross into `execution`",
"failClosed": true
}The deny is recorded as a signed Chio receipt on tool_server chio-wall, carrying a Decision::Deny with guard: "mcp-tool". Its metadata rides under the chio.wall.receipt_metadata.v1 envelope, embedding the authorization context, guard outcome, denied-access record, and policy snapshot together, with a content_hash over the canonical metadata and a policy_hash over the policy snapshot. The receipt is appended to a receipt store and checkpointed exactly as any other Chio decision, then folded into the evidence bundle.
Record denied access
Exporting the control-path package
control-path export builds the bounded package and the Chio evidence bundle into an empty output directory:
$ chio-wall control-path export --output ./chio-wall-export
workflow_id: workflow-information-domain-barrier
buyer_motion: control_room_barrier_review
control_surface: tool_access_domain_boundary
control_profile: ./chio-wall-export/control-profile.json
policy_snapshot: ./chio-wall-export/policy-snapshot.json
authorization_context: ./chio-wall-export/authorization-context.json
guard_outcome: ./chio-wall-export/guard-outcome.json
denied_access_record: ./chio-wall-export/denied-access-record.json
buyer_review_package: ./chio-wall-export/buyer-review-package.json
control_package: ./chio-wall-export/control-package.json
chio_evidence: ./chio-wall-export/chio-evidenceThe output directory must exist empty or not at all; a non-empty target, a symlink, or a plain file is rejected before anything is written. The global --json flag prints the same summary as a machine-readable object. The resulting layout:
chio-wall-export/
├── control-profile.json
├── policy-snapshot.json
├── authorization-context.json
├── guard-outcome.json
├── denied-access-record.json
├── buyer-review-package.json
├── control-package.json
├── control-path-summary.json
└── chio-evidence/Evidence contracts
Each JSON file is a typed contract with a pinned schema string. Fields serialize as camelCase; enum values as snake_case. A file whose schema does not match its contract is rejected on read.
| Artifact | Schema | Carries |
|---|---|---|
control-profile.json | chio.wall.control_profile.v1 | Lane identity: buyer motion, control surface, source and protected domain, retained-artifact policy, fail-closed flag |
policy-snapshot.json | chio.wall.policy_snapshot.v1 | The research-domain allowlist and fail-closed flag under one policy id |
authorization-context.json | chio.wall.authorization_context.v1 | The domain-scoped request: actor label, requested tool, requested domain, policy reference |
guard-outcome.json | chio.wall.guard_outcome.v1 | The decision, matched policy, evaluated tool, allowed tools, and reason |
denied-access-record.json | chio.wall.denied_access_record.v1 | The denied cross-domain event with its escalation and support owners |
buyer-review-package.json | chio.wall.buyer_review_package.v1 | The buyer-facing index tying the control package back to each artifact file |
control-package.json | chio.wall.control_package.v1 | The manifest: profile, buyer-review package, evidence dir, and the seven required artifacts |
chio-evidence/ | Chio evidence export | The signed receipt, checkpoint, and verification bundle for the denied decision |
The control-path-summary.json file is not a contract; it is the reconciliation summary the exporter writes and then reads back to confirm the package matches what it emitted.
The contracts enforce their own invariants on validation:
- Fail-closed is not optional:
failClosedmust betrueon the profile, policy snapshot, guard outcome, buyer-review package, and control package. Afalsevalue fails validation. - Domains must cross: the profile's source and protected domains must differ, and the authorization context and denied-access record both require the requested domain to differ from the source domain.
- Allowlists are clean sets:
allowedToolsmust be non-empty and free of duplicate, empty, whitespace-padded, or control-character entries. - A deny cannot contradict its allowlist: a guard outcome may not deny a tool that appears in its own
allowedTools. - The manifest is complete:
control-package.jsonmust list all seven artifact kinds exactly once. A missing or duplicated kind fails validation.
Fail-closed reconciliation
control-path export does not trust its own write. Before returning, it re-reads every artifact, re-runs each contract's validation, and cross-checks the references: the summary, buyer-review package, and control package must agree on the workflow id, buyer motion, control surface, owners, and every file path. The policy snapshot's allowlist must equal the guard outcome's. The authorization context, guard outcome, and denied-access record must agree on request id, tool, and domains.
The chio-evidence directory must exist and be non-empty, and the output directory is rejected if it holds any entry outside the expected set. The temporary receipt database used to build the evidence bundle is staged outside the package and removed, so an undeclared file in the output directory fails reconciliation rather than shipping silently.
Validating and closing out
control-path validate is the validation command. It runs the export under a control-path/ subdirectory, writes a validation report and emits an explicit expansion decision.
$ chio-wall control-path validate --output ./chio-wall-validation
workflow_id: workflow-information-domain-barrier
decision: proceed_chio_wall_only
buyer_motion: control_room_barrier_review
control_surface: tool_access_domain_boundary
control_path_dir: ./chio-wall-validation/control-path
validation_report: ./chio-wall-validation/validation-report.json
expansion_decision: ./chio-wall-validation/expansion-decision.jsonchio-wall-validation/
├── control-path/ # a complete control-path export
│ ├── control-profile.json
│ ├── policy-snapshot.json
│ ├── authorization-context.json
│ ├── guard-outcome.json
│ ├── denied-access-record.json
│ ├── buyer-review-package.json
│ ├── control-package.json
│ ├── control-path-summary.json
│ └── chio-evidence/
├── validation-report.json
└── expansion-decision.jsonThe expansion decision is proceed_chio_wall_only: proceed with the one bounded lane, and defer additional buyer motions, generic barrier-platform breadth, folding Chio-Wall into Mercury, and multi-product hardening. The report and decision name that boundary in the report so a reviewer can inspect it directly.
The supported claim
control_room_barrier_review buyer motion using one fail-closed tool_access_domain_boundary control surface on Chio. It does not claim multiple buyer motions, complete information-barrier coverage, generic barrier-platform breadth, or Mercury workflow-evidence readiness.Fail-closed operations
A Chio-Wall bundle is complete when each required component resolves: one control profile, one policy snapshot, one authorization context, one guard outcome, one denied-access record, one buyer-review package, one control package, and one non-empty Chio evidence export. Any missing, inconsistent, or unresolved file makes the surface incomplete.
The lane must fail closed when the bundle contradicts itself:
- the policy snapshot and guard outcome disagree about the allowed tool set;
- the authorization context and denied-access record disagree about the requested domain or tool;
- the buyer-review package cannot be matched back to the same control package;
- the Chio evidence export is missing or cannot be reconciled to the denied control-path record.
Recovery is ordered and owner-gated:
- Stop using the bundle immediately.
- Regenerate it from
control-path export. - Require the control owner (
barrier-control-room) to re-review the denied-access artifact before the bundle is treated as current.
The control owner owns the buyer motion, the domain boundary, and the escalation path. The support owner, chio-wall-ops, owns re-export, fail-closed recovery, and artifact integrity when the profile, authorization context, guard outcome, denied-access, buyer-review, or Chio evidence files go missing or inconsistent.
Streaming evidence to a SIEM
Chio-Wall receipts are ordinary Chio receipts, so they flow to a SOC through the same exporter as the rest of the platform. The siem-export subcommand runs the cursor-pull loop against a read-only receipt database, with the per-exporter high-water mark persisted to a separate RW cursor store for at-least-once delivery:
$ chio-wall siem-export \
--receipt-db /var/lib/chio/receipts.sqlite \
--cursor-db /var/lib/chio-wall/siem-cursor.sqliteThe serve loop fails closed unless a real SOC export sink is configured. A webhook sink is wired from CHIO_SIEM_WEBHOOK_URL (with an optional CHIO_SIEM_WEBHOOK_BEARER_TOKEN) and forwards every audit row. Alerting to PagerDuty or OpsGenie is an operator-configured notification overlay that only delivers high-severity denials, set through CHIO_SIEM_ALERT_PAGERDUTY_ROUTING_KEY or CHIO_SIEM_ALERT_OPSGENIE_API_KEY. It runs alongside a SOC sink and never satisfies the gate on its own.
A SOC sink is mandatory
The serve process also runs a receipt-log gap and lag watchdog and exposes a Prometheus scrape endpoint for the SOC-export, dead-letter, and alert-dispatch families it records. For exporter configuration, batching, retry, and the dead-letter queue, see SIEM Export.
Related
- Guards: the fail-closed evaluation model Chio-Wall reuses for the tool boundary
- Receipts: the signed, append-only records the denied decision is written to
- Verify Receipts Offline: re-check the Chio evidence bundle without trusting its source
- Mercury: the sibling companion product for trading-workflow evidence