Skip to main content

Tutorial 17: Keep PDF brief — zero CONNECT

Stage the one-click Keep demo: drop a PDF, get brief.md, prove 0 CONNECT from Keep’s own audit (and FluxVM host eBPF when the dataplane is attached). No browser. No PacketWolf required.

Level: Beginner
Time: 20 minutes
Repos: Fabric agent-runtime, FluxVM with template node22-agent (+ pdftotext), curl, optional Fabric console JWT.

Honesty. Evidence class stays software-test. Zero CONNECT means the guest never brokered egress — not “the operator cannot read the VM.”

Related: Tutorial 16 · pdf-brief demo · host confinement


What you will learn​

  1. Run the PDF → brief demo from script or /app/keep.
  2. Read egress_connects on the cockpit (and optional FluxVM drop_reasons).
  3. Fail closed when CONNECT > 0 (session freeze / ebpf_deny).

Step 0 — Preflight​

cd fabric
export KEEP_API="${KEEP_API:-http://127.0.0.1:9096}"
export KEEP_TOKEN="${KEEP_TOKEN:-}" # if runtime auth is on

curl -fsS ${KEEP_TOKEN:+-H "Authorization: Bearer $KEEP_TOKEN"} "$KEEP_API/healthz"
# FluxVM must be ready (agent-runtime /readyz path); template node22-agent baked
# with poppler-utils so guest `pdftotext` works.

Console path (fabricd proxies demos): sign in → Keep → /app/keep.


Step 1 — One click (console)​

  1. Open /app/keep.
  2. Pick a PDF or leave empty for the lab sample.
  3. Click Brief this PDF.
  4. Watch chips: cell up → extract → brief.md.
  5. Open cockpit — CONNECT: 0.

If the button shows an error (missing template, no pdftotext, FluxVM down), fix that — do not fall through to a browser pack.


Step 2 — Same path from the script​

./scripts/keep-demo-pdf.sh
# or
./scripts/keep-demo-pdf.sh /tmp/vendor.pdf

Expect JSON with egress_connects: 0, artifact_title: brief.md, and a cockpit_url like /app/keep/<session-id>. Exit code 2 if CONNECT ≠ 0.

Direct API (multipart optional — omit pdf for the lab sample):

curl -fsS ${KEEP_TOKEN:+-H "Authorization: Bearer $KEEP_TOKEN"} \
-X POST -F "pdf=@examples/keep-agents/pdf-brief/sample.pdf;type=application/pdf" \
"$KEEP_API/v1/demos/pdf-brief" | jq '{session_id, egress_connects, artifact_title}'

Via fabricd (JWT): POST /api/demos/pdf-brief.


Step 3 — Read the proof​

SID=… # from the demo response
curl -fsS ${KEEP_TOKEN:+-H "Authorization: Bearer $KEEP_TOKEN"} \
"$KEEP_API/v1/sessions/$SID/cockpit" | jq '{egress_connects, drop_reasons, honesty: .attestation.honesty}'
SignalMeaning
egress_connects: 0No egress.connect / ebpf.* rows in Keep audit for this session
drop_reasonsFluxVM TC histogram when dataplane attached (e.g. udp-deny)
Policyegress_mode: deny, empty allowlist, FluxVM deny_udp + gateway-only ports

Stage line without PacketWolf:

Zero CONNECT is from Keep’s journal and FluxVM’s deny-by-default pin — the guest never got a path that could light an external observer.


Step 4 — What runs under the hood​

StepWhoVisible
0script / console/healthz, FluxVM ready, template
1POST /v1/demos/pdf-briefcell create + strict confine
2hostput PDF → /home/agent/work/input.pdf
3guestpdftotext extract (no model required for stage brief)
4hostartifact brief.md + goal done
5hostcount CONNECT; freeze + ebpf_deny if > 0

Pack: examples/keep-agents/pdf-brief/.


What not to do​

  • Claim PacketWolf or Hubble when they are not in the lab
  • Open Chromium “just to finish the demo” if extract fails
  • Market software-test as unread-by-operator

Next​