Chio/Docs
LOGIN · JOIN

Receipt Dashboard

Serve the operator dashboard from the trust control plane and trace any call to its signed receipt and capability chain.

Deployment chio@5f63e6e

On this page

The receipt dashboard runs inside the trust control plane, on the same address as its API: an operator summary across the top, a filterable receipt list, and a detail panel that follows each call to its signed receipt and the capability chain behind it.

Every panel calls a documented trust-control route, the query contract the chio CLI uses, and each route admits only the principals its class allows. Two requests made a minute apart can return different rows as receipts arrive.

Start
Dashboard routesChoose a view.
operator’s browsertrust control plane · one addressprincipal checkoperator’s browsertrust control planeprincipal check

The summary is the operator report

The summary panels come from GET /v1/reports/operator, composed on the server from the receipt and budget stores. Budget utilization is current state, so the receipt time window leaves it unchanged. Operator reports.

One trust control plane serving the dashboard and its API on one address, with each store drawn where a view reads it. The issuance panel, the authority-tree and pool views, analytics, and reputation comparison are left out.

1. Start the trust control plane with the dashboard

Point the service at its receipt, authority, and revocation stores, with the admin service token in CHIO_TRUST_SERVICE_TOKEN. The three store flags are global flags on chio.

Terminalbash
$ export CHIO_TRUST_SERVICE_TOKEN="$(cat secrets/service-token.txt)"
$ chio trust serve \
    --listen 127.0.0.1:8940 \
    --receipt-db ./state/receipts.sqlite \
    --authority-db ./state/authority.sqlite \
    --revocation-db ./state/revocations.sqlite
Output
Chio trust control service listening on http://127.0.0.1:8940

You should see the listening line. The dashboard is a static catch-all mounted after every API route on the same router, so one address serves both and there is no second port. chio trust serve is flag-driven, with no separate config file: --service-token sets the admin principal and each --tenant-read-token adds a tenant principal, as Trust Control Plane covers.

Run it with Docker Compose
docker-compose.ymlyaml
services:
  chio-trust:
    # The release container image: the chio binary with the dashboard embedded.
    image: ghcr.io/backbay-labs/chio:0.2.0
    command:
      - chio
      - trust
      - serve
      - --listen
      - 0.0.0.0:8940
      - --receipt-db
      - /var/lib/chio/receipts.sqlite
      - --authority-db
      - /var/lib/chio/authority.sqlite
      - --revocation-db
      - /var/lib/chio/revocations.sqlite
    environment:
      # The admin service token, read from the host environment.
      CHIO_TRUST_SERVICE_TOKEN: ${CHIO_TRUST_SERVICE_TOKEN:?set the admin service token}
    ports:
      - "8940:8940"
    volumes:
      - chio-state:/var/lib/chio

volumes:
  chio-state:

chio trust serve is a subcommand of the single chio binary, so the dashboard ships in the release container image with no separate trust-control image. Mount a volume for the stores so they survive a container restart.

2. Check that the API and the dashboard answer

Terminalbash
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8940/health
$ curl -sI http://127.0.0.1:8940/ | grep -i '^content-security-policy'
Output
200
content-security-policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:

You should see 200 from the health route, then the dashboard's content security policy: scripts, styles, and API calls load only from the service's own origin.

3. Sign in with the admin principal

Open http://127.0.0.1:8940/ and sign in with the admin service token. Dashboard data requests carry it in the Authorization header, and the service rejects a token placed in the URL query string.

You should see the operator summary. Without a credential the dashboard shows an operator guidance state and sends no unauthenticated requests, so a misconfigured deployment shows an empty dashboard and exposes no receipt metadata. The full operator view needs the admin principal; a tenant read token reaches only its own tenant's receipts, never the summary, analytics, lineage, or approval routes.

4. Trace a call to its receipt and its authority

The dashboard has three panes: filters on the left, the operator summary across the top, and a receipt table that opens a detail panel on the right. Narrow the table with the filters, then select the row for the call.

  1. Filter. Set the agent subject, tool server, tool name, outcome, or time window. Each filter is a parameter on GET /v1/receipts/query, so the view matches chio receipt list with the same filters and ordering. Changing a filter returns to page 1; results arrive 50 to a page with cursor-based previous and next controls.
  2. Open. The detail panel shows the decision (allow, deny, canceled, or incomplete), tool server and name, timestamp, capability ID, financial metadata, the raw parameters, and the full receipt JSON for a ticket.
  3. Follow the authority. The delegation chain lists every capability from the root to the leaf the agent held, with issuer, subject, window, depth, and grants.

You should see the signed receipt and, beneath it, how the capability it names was delegated and attenuated before it reached the agent. The panel renders the receipt struct field for field; Receipt format defines each field, and the detail reference lists the panel's routes.

The summary is the operator report, composed on the server

The summary above the table comes from GET /v1/reports/operator, built by the service from its stores, so it covers every matching receipt beyond the page the table has loaded. It answers whether an agent or tool slice is active, within budget, and ready to export.

PanelShowsUse it for
ActivityReceipt totals, allow and deny ratioWhether the slice is doing anything
SpendSpend totals, top root budget holderWho drives cost in the window
Budget pressurematchingGrants, nearLimitCount, exhaustedCountGrants near or at their limit
Compliance statecheckpointCoverageRate, lineageCoverageRate, uncheckpointedReceiptsCoverage indicators
Settlement readinesspendingSettlementReceipts, failedSettlementReceipts, proof completenessSettlement work before an invoice export
Shared evidenceReference counts, latest partner and shareFederated evidence context

Budget utilization is current state, so the receipt time window leaves it unchanged. The settlement card names pending settlements, failed settlements, and incomplete proofs before you attempt an invoice export. Coverage figures are report counts; an evidence export carries the inclusion proofs, as Operator Reports explains.

Approvals reach a person through the dashboard

The dashboard is the operator web client for the trust control plane. Its approvals panel lists pending requests for a person to decide, the same queue chio approvals pending reads and chio approve <id> decides. Approval routes admit only the admin principal.

The same client carries the issuance panel, an authority-tree view, and pool views, each calling its own trust-control route under the same principal check. Require human approval covers the approval flow end to end.

A passport compares against local history beside its subject

With the agent subject filter set, a comparison panel appears above the table. Upload a passport JSON document and the dashboard calls POST /v1/reputation/compare/{subject_key}, the contract chio reputation compare --control-url ... uses, with no second scoring path in the browser.

  • Whether the live local subject key matches the passport's subject DID.
  • The current local effective score and resolved tier.
  • A relying-party acceptance state, when the passport carries a verifier-evaluation result.
  • Per-credential drift for composite score, reliability, delegation hygiene, and resource stewardship.
  • Shared-evidence provenance: partner and share IDs, remote capability IDs, local anchor capability IDs, and local receipt counts.

Reputation is an optional module, off in default builds of the control plane and CLI; the panel answers when the deployment enables it. Reputation covers scoring.

Imported evidence stays beside local history

GET /v1/federation/evidence-shares returns the shared-evidence report shape that operator reports and reputation comparison use, and the summary's shared-evidence card reads it. Imported remote references appear as references, kept apart from the native local receipt history.

Terminalbash
$ chio trust evidence-share list \
    --agent-subject <subject-hex> \
    --json

A dashboard problem shows at sign-in or in an empty panel

The dashboard shows the operator guidance state

No credential reached the service. Sign in again with the admin service token or a tenant read token; a token pasted into the URL is rejected.

The summary and lineage panels stay empty

The credential is a tenant read token. Tenants read their own receipts through Tenancy & Read Scoping; the operator summary, analytics, and lineage need the admin principal.

Approve is refused

The signed-in credential is a tenant read token, and approval routes admit only the admin principal. Sign in with the admin service token, or decide from the CLI with chio approve <id>.

Dashboard reference

Receipt filters

FilterTypeSelects
Agent subject
Hex Ed25519 public key
Receipts produced against that agent's capability tokens
Tool server
Exact-match string
One tool server identifier
Tool name
Exact-match string
One tool name within a server
Outcome
Enum
allow, deny, cancelled, incomplete
Since
Unix seconds (u64)
Lower bound on receipt timestamp
Until
Unix seconds (u64)
Upper bound on receipt timestamp

The outcome values are the four Decision variants. The time window applies to receipt queries; current budget utilization is a state view outside it.

Detail panel contents

  • Decision badge: Allow, Deny, Canceled, or Incomplete.
  • Tool server and tool name, with a formatted timestamp, and the full capability ID.
  • Financial metadata when present: cost charged, budget remaining, total budget, delegation depth, and settlement status, formatted from minor units in the receipt's own currency.
  • The agent subject key when attribution metadata is present.
  • A per-day cost sparkline, the raw tool-call parameters, and the full receipt JSON.

Delegation chain

The DelegationChain component fetches GET /v1/lineage/{capability_id}/chain and renders every CapabilitySnapshot from root to leaf. Each snapshot shows subject_key, issuer_key, issued_at, expires_at, delegation_depth, and the raw grants JSON.

Budget sparkline

When the selected receipt has financial metadata, the panel renders a BudgetSparkline from GET /v1/receipts/analytics?agentSubject=...&timeBucket=day. It uses the receipt's attribution subject key and falls back to capability lineage when attribution metadata is absent. The chart is inline SVG, with no charting library in the bundle.

Routes the panels call

PanelRoute
Operator summary
GET /v1/reports/operator
Receipt table
GET /v1/receipts/query
Delegation chain
GET /v1/lineage/{capability_id}/chain
Budget sparkline
GET /v1/receipts/analytics
Reputation comparison
POST /v1/reputation/compare/{subject_key}
Shared evidence
GET /v1/federation/evidence-shares

Service flags

FlagDefaultNotes
--listen
127.0.0.1:8940
Bind address for the API and the dashboard
--receipt-db
none
Global flag; receipt SQLite database path
--authority-db
none
Global flag; authority store path
--revocation-db
none
Global flag; revocation store path

Next: read the report behind the summary