IN SCOPE
4 servers · 4 principals
postgres-prod · github · slack · filesystem
- svc-analytics — declared, not verified
- svc-release-bot — declared, not verified
- svc-oncall-agent — declared, not verified
- m.okafor — declared, not verified
AGENT FLIGHT CHECK · SAMPLE READOUT
The readout below is the full Flight Check format, produced by the real recorder — Witness v0.3 — against a synthetic estate of four MCP servers and four principals, because one studio does not have four of each to show you. The estate is invented; the records, the report and the verification are not. At the end, the same instrument on our own estate, with the finding it caught here. Download either export and run witness verify on it yourself.
COVER PAGE
A real readout opens with what was in scope, what was recorded, and whether the record is intact. Numbers here are read from the export at build time, not typed.
IN SCOPE
postgres-prod · github · slack · filesystem
RECORDED
4 refused by the target system · 1 never answered · 22 completed.
FINDINGS
A finding is a sentence a CISO can repeat, the records that support it, and the fix. Nothing here is inferred from a screenshot.
A developer's coding agent read /srv/app/.env, attempted /home/deploy/.ssh/id_ed25519, and was denied on /etc/shadow. The filesystem server is mounted at / for an agent whose job is one application directory.
Fix. Scope the filesystem server to /srv/app; move secrets out of files the agent can reach.
Five queries from an analytics principal, one refused by the database as permission-denied. Query text is hashed, not stored; the refused statement is identified from the database's own log in the interview. Either way, an analytics credential is being used beyond a read-only grant.
Fix. Issue a read-only role for svc-analytics; alert on any denied statement from an agent principal.
The release bot merged a pull request in acme/platform and attempted a merge in acme/infra, which was refused. The token is repo-wide when the approved scope was one repository.
Fix. Fine-grained token limited to acme/platform; merge only via a protected-branch rule that requires a human review.
The on-call agent posted to #general (approved scope: #incidents), looked up an executive by email, and attempted to read #exec-private, which was refused.
Fix. Restrict the bot's channel allow-list to #incidents; remove users:read.email.
One call never received an answer: the server exited after 370 ms. Witness recorded the call as unknown, not as success. A retry loop on the agent side would have masked this.
Fix. Timeout and retry policy on the harness; alert on unknown outcomes.
Every principal is declared by the harness config (--as) and none is cryptographically verified. The record says so on every line (verified: false). Identity proof is a follow-on build, not part of the two-week check.
Fix. Decide whether declared identity is acceptable for your audit posture before the next review.
REMEDIATION PLAN
Ordered by risk removed per day of work. Estimates are what engineering can act on the same week; you can take the plan to your own team or to us.
| # | Action | Owner | Effort | Closes |
|---|---|---|---|---|
| 1 | Scope filesystem and GitHub tokens to the approved paths and repos | Platform | 2 days | F1 F3 |
| 2 | Read-only database role for agent principals; deny-alerting | Data | 1 day | F2 |
| 3 | Slack app scopes and channel allow-list | IT | half a day | F4 |
| 4 | Harness timeout/retry policy; keep the recorder running | Platform | 1 day | F5 |
| 5 | Decision: declared vs verified principals | Security lead | readout | F6 |
EVIDENCE EXPORT
Three files, all yours. The report is generated by witness report; the sessions file is the raw hash-chained record; the checkpoints file is the chain heads, chained again.
DOWNLOAD
Verify: git clone https://github.com/dark-vector-cognition/witness && node witness/bin/witness.mjs verify sessions.jsonl
ONE RECORD, VERBATIM
Note what is present (tool, path summary, principal, client, hash chain) and what is absent (file contents, the full argument object).
{
"v": "0.1",
"seq": 12,
"ts": "2026-09-12T23:37:44.772Z",
"session": "s_ac5761f3",
"event": "tool_call",
"rpc_id": 15,
"tool": "read_file",
"args_sha256": "8cbae1d71d242fe96189b44ab7a97a23a3a94f68dfde52e9625d19d5a904b4ea",
"args_bytes": 39,
"args_summary": {
"path": "/home/deploy/.ssh/id_ed25519"
},
"actor": {
"client": "cursor",
"version": "1.4.2",
"protocol": "2025-06-18"
},
"principal": {
"as": "m.okafor",
"source": "flag",
"verified": false
},
"server": {
"name": "filesystem",
"cmd_sha256": "02a751c263674851df7fab225085d4241ce610bc049b22b5ac5809c9deaba85e"
},
"prev": "8099faf071d4e216ffd1f182af317b662b21f8930e2d528e5dc4fd6c1160ef57",
"hash": "fd9086914301b6b3c42363db1a2643a4a6f5f87e03c86930e98e162931c458d5"
}REPORT.MD, VERBATIM
# Witness report — last 1d
Generated 2026-09-12T23:37:47.076Z · log /sessions/rcw-013spsibfthc6kbi23qcnnp4/wh-sample/log
| Sessions | Servers | Principals | Tool calls | Errors | Unanswered | Broken chains |
|---|---|---|---|---|---|---|
| 4 | 4 | 4 | 27 | 4 (15%) | 1 | 0 |
## Calls by tool
| Tool | Calls | Errors | Open | p50 ms | p95 ms |
|---|---|---|---|---|---|
| read_file | 5 | 1 | 0 | 1 | 15 |
| query | 5 | 1 | 0 | 0 | 13 |
| conversations_history | 3 | 1 | 0 | 0 | 0 |
| merge_pull_request | 2 | 1 | 0 | 1 | 1 |
| write_file | 2 | 0 | 0 | 1 | 1 |
| list_directory | 2 | 0 | 1 | 370 | 370 |
| chat_postMessage | 2 | 0 | 0 | 14 | 14 |
| search_issues | 1 | 0 | 0 | 14 | 14 |
| get_pull_request | 1 | 0 | 0 | 3 | 3 |
| create_pull_request | 1 | 0 | 0 | 0 | 0 |
| list_commits | 1 | 0 | 0 | 0 | 0 |
| create_issue | 1 | 0 | 0 | 1 | 1 |
| users_lookupByEmail | 1 | 0 | 0 | 0 | 0 |
## Calls by server
- **filesystem** — 9
- **github** — 7
- **slack** — 6
- **postgres-prod** — 5
## Calls by declared principal
- m.okafor — 9 _(declared, not verified)_
- svc-release-bot — 7 _(declared, not verified)_
- svc-oncall-agent — 6 _(declared, not verified)_
- svc-analytics — 5 _(declared, not verified)_
## Integrity
- ✓ 4 chain(s) verified, no broken links
Peak hour (UTC): 23:00 with 27 calls.
_Arguments and results are hashed, never stored. See SPEC.md._
FINDING F6, ON OUR OWN ESTATE · NOT A SAMPLE
The readout above uses a synthetic estate, because one studio does not have four servers and four principals to show you. This section does not. It is finding F6 — config drift — found on DVC's own machine by DVC's own recorder, with every number read from the export at build time.
RECORDED
1 session · 1 server (desktop-commander) · 1 declared principal.
THE FINDING
The wrapped config on this machine pointed at a Node binary that a Homebrew upgrade had broken. The server never started, so nothing was recorded — and an empty log looks exactly like a quiet estate. The config on the machine had drifted from the config in the repository, and nothing noticed until someone asked the record a question. It is fixed; the recorder is running.
Read the write-up →PER TOOL · READ FROM THE EXPORT
Aggregate error rate was 12% — unremarkable. Every failure was one tool. This is why a Flight Check reports per tool, not per session.
| Tool | Calls | Errors | Error rate | p50 ms | p95 ms |
|---|---|---|---|---|---|
| read_file | 12 | 3 | 25% | 62 | 529 |
| list_directory | 6 | 0 | 0% | 2 | 2 |
| get_file_info | 3 | 0 | 0% | 2 | 2 |
| get_config | 1 | 0 | 0% | 18 | 18 |
| get_usage_stats | 1 | 0 | 0% | 1 | 1 |
| list_processes | 1 | 0 | 0% | 169 | 169 |
| list_sessions | 1 | 0 | 0% | 3 | 3 |
Verify it yourself: git clone https://github.com/dark-vector-cognition/witness && node witness/bin/witness.mjs verify sessions.jsonl
TWO WEEKS · $7,500 · NOTHING LEAVES YOUR NETWORK
Thirty minutes to confirm scope and dates. If the Flight Check isn't the right instrument for your estate, we'll say so on the call.
Book the readout call →