Skip to main content

Tutorial 18: Keep use cases — drop a file, get an artifact

Tutorial 17 briefs one PDF. This one runs the whole family of one-click demos the same way: contract clauses, a security questionnaire, meeting actions, log triage, an SBOM summary and a CSV cleanup. Each takes an untrusted file, works inside a sealed cell with no browser, and must finish with 0 CONNECT.

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

Honesty. The summaries are extractive: no model is called and nothing found in the file is run, opened or sent. Evidence class stays software-test. Zero CONNECT means the guest never brokered egress, not "the operator cannot read the VM".

Related: Tutorial 17 · demos index · host confinement


What you will learn​

  1. List the demos a runtime offers and run any of them from the script or /app/keep.
  2. Read each artifact and see what was, and was not, extracted.
  3. Confirm the fail-closed rule (egress_connects > 0 freezes the session, 409).

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

./scripts/keep-demo.sh list

You should see seven demos. If the list is empty or the call fails, the runtime is older than this tutorial; run Tutorial 17 first.


Step 1: Run each demo on its sample​

Every demo ships a small sample under examples/keep-agents/<id>/:

./scripts/keep-demo.sh contract-clauses
./scripts/keep-demo.sh security-questionnaire
./scripts/keep-demo.sh meeting-actions
./scripts/keep-demo.sh log-triage
./scripts/keep-demo.sh sbom-summary
./scripts/keep-demo.sh csv-clean

Each run prints the JSON result and ends with OK — <artifacts> ready, 0 CONNECT. The script exits 2 if egress_connects is not 0.

Console path: sign in → Keep → /app/keep, pick a use case, choose a file (or leave it empty for the sample), and click Run.


Step 2: Read the artifacts​

Open the session cockpit (/app/keep/<session>) and read each artifact:

DemoWhat to look for
contract-clausesA section per topic found, and a Not found list
security-questionnaireA table of questions with the answer as written; (no answer found) where the next line is another question
meeting-actionsOwners from Name: prefixes; WebVTT timestamps are gone
log-triageLevel counts, errors grouped after numbers collapse (timeout after #s), the busiest minutes
sbom-summaryComponent and license counts; severity table for CycloneDX vulnerabilities or SARIF levels
csv-cleanclean.csv with formula-like cells prefixed by ', and a report.md listing them

Step 3: Try a hostile file​

The point of the cell is what happens when the input misbehaves. Try:

printf 'name,note\nAnn,=HYPERLINK("http://example.com","click")\n' > /tmp/evil.csv
./scripts/keep-demo.sh csv-clean /tmp/evil.csv

The formula cell comes back as '=HYPERLINK(...) in clean.csv and is listed in report.md. It never ran, and the cockpit still shows 0 CONNECT.

Wrong file type is refused before any cell is created:

./scripts/keep-demo.sh csv-clean README.md # 400: the csv-clean demo accepts .csv files

Step 4: Fail closed​

If the audit journal shows any egress.connect or ebpf.* event during a run, the runtime freezes the sandbox, sets agent_paused_reason: ebpf_deny and returns 409. There is no browser fallback. See confine.md.


Where next​

  • Add your own use case: demos/README.md.
  • Use cases that need the network or a browser are packs with an allowlist instead: Tutorial 16.