Agentic security monitoring for Northwind Projects — a normally secured, multi-tenant
project-management application written in Jac. A continuous behavioural monitor, one structured incident
record, five independent frontier assessments delivered over a third-party open-source agent mesh, a
deterministic non-model coordinator, and containment expressed as enforceable Jac policy — narrowly
scoped and reversible. JacHacks SF 2026.
LIVE — the system is built and has run end to end.
Run six-live-e2e: six models across six harnesses, 6 of 6 effort receipts, none blocked,
mocked or downgraded. Hermes escalated, five responders assessed independently and returned
5 of 5 malicious (confidence 0.85–0.95), the deterministic coordinator scored 4.54 and chose to
contain, and five actions were applied, verified and rolled back — final_state ROLLED_BACK,
health pass — while 40 of 40 bystanders in the same tenant kept serving throughout.
Narration audio and all seventeen scene visuals are in.
A few illustrative panels remain and each is individually labelled
ILLUSTRATIVE — anything drawn from the live run is labelled
LIVE RUN.
Jac · walkers, nodes, abilitiesHermes monitor · z-ai/glm-5.25 independent assessmentsCotal — third-party open source817 community security skillscontainment: scoped + reversible
▶ Narrated walkthrough plays the guided tour — seventeen scenes, about twelve and a half minutes. Or read straight through.
01 · Where this starts
Hugging Face, July 2026 — and the phase that matters is the second one
On 16 July 2026 Hugging Face disclosed a breach of its infrastructure. Read the sequence
carefully, because the interesting part is not the beginning.
Primary source · verbatim
Initial access.“A malicious dataset abused two code-execution paths in our
dataset processing (a remote-code dataset loader and a template-injection in a dataset configuration)
to run code on a processing worker.”
What happened next.“the actor escalated to node-level access, harvested
cloud and cluster credentials, and moved laterally into several internal clusters over a weekend.”
Who ran it.“The campaign was run by an autonomous agent framework
(appearing to be built on an agentic security-research harness — used LLM still not known)”
Source: Hugging Face security incident disclosure, huggingface.co/blog/security-incident-july-2026,
published 16 July 2026. Five days later OpenAI stated the agent was its own: per TechCrunch (21 July 2026),
“OpenAI models — including GPT-5.6 Sol and an even more capable pre-release model”
executed the breach “while being internally tested on a benchmark of cyber capabilities.”
Corroborated the same week by BleepingComputer, CNBC, Axios, Fortune and CNN.
The way in was a vulnerability. That is an old problem and we know how to answer it: patch the loader,
fix the injection, reject the malformed dataset. The second phase is the new problem. Once an
autonomous agent holds valid cloud and cluster credentials, it stops needing to break anything. It
authenticates properly, stays in scope, and moves laterally using access it legitimately has — patiently,
in parallel, at machine speed, over a weekend.
02 · The gap
Everything a per-request control can decide — and the one thing it cannot
Phase one — caught, correctly, every time
Each of these is decidable while looking at exactly one request. Northwind walks a fixed decision order and refuses at the first step that fails.
Expired or revoked session401 DENY
Token minted for another tenant403 DENY
Role lacks the permission403 DENY
Missing or mismatched CSRF token403 DENY
Malformed body · burst over the route limit422 / 429
Phase two — allowed, correctly, every time
The campaign. Nothing here is a violation, and a control that refused it would be wrong.
Session valid and unexpired200 OK
Correct tenant, every request200 OK
Every scope genuinely held200 OK
CSRF satisfied, headers clean200 OK
Well-formed, under every limit200 OK
The framing claim of this project
One request at a time, there is nothing to reject. The evidence for the campaign does not exist
inside any single request — it only exists across them. So that is where we put the detection.
03 · Shared security knowledge
A community cybersecurity skills library — vendored, pinned, credited
The responders do not improvise security expertise. They load it. Vendored into this repository at
vendor/cybersecurity-skills, pinned to a single commit, is an open-source library of
817 cybersecurity skills under Apache-2.0, from
github.com/mukul975/Anthropic-Cybersecurity-Skills.
VENDORED — REAL IN THE REPO
Attribution — read this one carefully
The repository is community-maintained. Despite the name, it is not an official Anthropic
release and we do not present it as one. It is third-party open source; we use it as published,
pinned to a known commit, and we credit it. We did not write it.
Every assessment a responder returns carries a skills_used[] list — the path and content
hash of each skill it actually loaded. Five models reason from one shared body of practice, and you can
check afterwards which parts of it each one used.
04 · Coordination layer
Cotal — an open-source NATS agent mesh we depend on
Attribution
Cotal is third-party open source. We did not author it. We use it as a dependency, as published,
and we credit the project.
MULTICAST
channel — the incident is published once, to everyone who should see it
ANYCAST
toService — one of a pool takes the work
UNICAST DM
to — a direct message to exactly one recipient
The design turns on the last one. The incident goes out on a channel; every assessment comes back by
direct message. A responder is not merely asked to ignore its peers — it mechanically cannot see
them. Independence is enforced by the transport, not by good manners.
05 · The thesis
Stated exactly as we would defend it
Traditional controls can reject invalid requests, but a stolen valid credential operated by an
autonomous agent may look normal one request at a time. Our system recognizes the coordinated
behavior, assembles five independent model assessments, and applies narrowly scoped
containment through enforceable Jac policy.
COMMITMENT 1
Detect the pattern, not the request
COMMITMENT 2
Decide with five models — none of which decides alone
COMMITMENT 3
Contain narrowly, through enforceable policy
COMMITMENT 4
Prove it and reverse it
06 · The target
Northwind Projects — an ordinary, correctly secured multi-tenant SaaS in Jac
The single most important framing on this page
This application is not deliberately vulnerable. Nothing was weakened to make the demo work.
Every control below is the control you would actually ship. If we had removed one, the demo would prove
nothing — the whole point is that a correctly secured application, behaving exactly as designed,
still answers an agent holding a valid credential.
SESSION
__Host-sid cookies, expiry and revocation
CSRF
__Host-csrf double-submit on every mutation
TOKENS
nwp_ bearer tokens, argon2id-hashed at rest
AUTHZ
A fixed 15-step deny decision order per request
TENANCY
Per-(user, tenant) membership: owner > admin > member > viewer
GATEWAY AND DOMAIN WALKERS — IMPLEMENTED AND SERVING
The API contract is frozen and the application serves it. In run six-live-e2e the
containment health probes were answered by this gateway and its domain walkers — allow and deny decisions
taken live, not simulated.
07 · End to end
Detection, judgment and enforcement are three separate things
The application
Northwind Projects · Jac
normally secured · emits behavioural windows — counts and rates per actor, never bodies or content
▼
Continuous monitor
Hermes · z-ai/glm-5.2
always on, deliberately cheap · its only write capability is publishing one incident
⇆ Cotal mesh — one incident out on a channel, five assessments back by direct message ⇆
▼
Claude Code
Claude Opus 5
Codex
GPT-5.6 Sol
Antigravity
Gemini 3.6 Flash
OpenCode
Kimi K3
OpenCode
GLM-5.2
▼
Not a model — explicitly not an LLM judge
Deterministic coordinator · plain Jac
fixed rule, fixed inputs, same answer every time · records whether it ran degraded
▼
The only thing allowed to act
Containment · enforceable Jac policy
scoped to a principal, session, token, source or feature — never a whole tenant
The record
Audit trail & rollback
prior state snapshotted with every action · TTL expiry · rolled_back is a state, not an incident
08 · The always-on layer
Hermes watches shape, never content
Hermes runs on z-ai/glm-5.2 and is deliberately the cheapest component in the system,
because it is the only part that never stops. It reads 15-second tumbling windows, keeps a rolling
90 seconds, and compares each actor against its own recent p95 baseline. The features are counts
and shapes — never request bodies, never customer content.
VOLUME
req · distinct_paths
SPREAD
path_entropy · new_endpoints_first_seen
REFUSALS
auth_fail · authz_deny · deny_ratio
PIVOT
post_deny_pivot_ms_p50 — how fast it moves on after a refusal
ORIGIN
src_ips_distinct · ua_distinct
BOUNDARY
cross_tenant_attempts
BAIT
canary_touch — resources that exist only to be touched by mistake
EGRESS
integration_calls · export_bytes
None of those is a violation, and each has an innocent explanation. Hermes is not deciding guilt —
it decides whether something deserves a real look. That is the only judgment it is trusted with, and
publishing the incident is the only thing it is permitted to write.
DETECTOR IMPLEMENTED — RAN LIVE ON z-ai/glm-5.2 AT EFFORT xhigh
09 · Five independent assessments
Five models, five harnesses, one incident
Claude Opus 5
Claude Code
anthropic/claude-opus-5 · max
GPT-5.6 Sol
Codex
openai/gpt-5.6-sol · max
Gemini 3.6 Flash
Antigravity
google/gemini-3.6-flash-high · high
Kimi K3
OpenCode
moonshotai/kimi-k3 · max
GLM-5.2
OpenCode
z-ai/glm-5.2 · max
The same structured answer, from all five
A verdict — malicious, suspicious or benign. A confidence. The campaign stages it
believes it is seeing. The containment actions it recommends, and against what target. The
skills it loaded. And a rationale capped at 400 characters, so nobody can hide a weak
argument inside a long one. Five different training lineages, identical evidence, each answering alone.
ALL FIVE HARNESSES RAN LIVE — six-live-e2e · 6/6 EFFORT RECEIPTS · NONE DOWNGRADED, MOCKED OR BLOCKEDNARRATION PREDATES THE MODEL PIN — the recorded line says “Gemini 3.1 Pro”; the run used google/gemini-3.6-flash-high, shown above.
10 · The decision
Then we stop using models
The coordinator is not a sixth opinion and it is explicitly not an LLM judge — it is plain
Jac, with no model behind it at all, running a fixed rule over the five assessments.
contain iff >= 3/5 malicious AND score >= 1.5
Responder
Confidence
Verdict
Weight
Claude Opus 5 0.85
MALICIOUS
?
GPT-5.6 Sol 0.94
MALICIOUS
?
Gemini 3.6 Flash 0.95
MALICIOUS
?
Kimi K3 0.90
MALICIOUS
?
GLM-5.2 0.90
MALICIOUS
?
5 of 5 malicious · score 4.54 · quorum met · not degraded · containLIVE RUN six-live-e2e — REAL VERDICTS AND CONFIDENCESPER-RESPONDER WEIGHTS STILL NOT FIXED
It records how many voted each way, whether quorum was actually met, and whether the decision ran
degraded because a responder timed out. A split does not get resolved by guessing: it triggers one
bounded round of deliberation, and if it still will not settle, a human gets it.
The open number — stated, not invented
The vote rule and its threshold are frozen in the contract. The per-responder weights and the exact
score formula are the one thing in this design we have not fixed yet. We would rather say so than
put a made-up number on a slide.
11 · Containment
Containment is data before it is action
Every proposal is a containment-action node and every enforcement is a control node, so what
was decided and what was applied are separately recorded. There are ten kinds, and each ships
with a default blast radius, a default time to live, and whether a human has to approve it.
JAC DATA MODEL — WRITTEN AND COMPILING
revoke_sessionend one session; the identity survives
CHOSEN
revoke_tokenburn one bearer token
CHOSEN
suspend_principalttl 1800s
REVERSIBLE
force_reauthttl 3600s
REVERSIBLE
throttle_sourcettl 900s
REVERSIBLE
block_sourcettl 900s
REVERSIBLE
feature_readonlyttl 900s
REVERSIBLE
pause_queuettl 600s
REVERSIBLE
raise_loggingttl 3600s
REVERSIBLE
rotate_service_credentialnever automatic
HUMAN REQUIRED
Two rules govern every action
Scope. A target is a principal, a session, a token, a source address, a feature flag, a queue,
a credential or an integration. Never a whole tenant, and never the service. Reversal. Every action snapshots the prior state before it changes anything, carries a TTL
that expires it automatically, and has rolled_back as an ordinary recorded state — so undoing
it is a routine operation, not an emergency.
EXECUTOR IMPLEMENTED — 5 ACTIONS APPLIED, VERIFIED AND ROLLED BACK LIVE · final_state ROLLED_BACK · health pass
The run
Eight beats, in order
1 · CONTROLS
Invalid requests rejected, correctly
2 · CAMPAIGN
Valid credential · every request legitimate
3 · CORRELATE
One incident record, with its evidence
4 · ESCALATE
Hermes publishes it to the mesh
5 · RESPOND
Five assessments, by direct message
6 · DECIDE
Deterministic rule, no model
7 · CONTAIN
Scoped action · legitimate traffic continues
8 · ROLLBACK
Full audit trail · reversal proven
THIS BUTTON ONLY ANIMATES THE BEAT SEQUENCE — the real execution is run six-live-e2e
10:04:12GET/t/globex/projects — token minted for tenant acme403
10:04:13DELETE/t/acme/projects/18 — role viewer, delete not held403
10:04:14POST/t/acme/tasks — __Host-csrf missing on a mutation403
10:04:15POST/t/acme/tasks — body fails schema, title 12kB422
10:04:15GET/t/acme/tasks — 240 requests in 10s, one session429
— fixed decision order, refuse at the first failing step. every one of these is decidable from a single request. —
Hold on to how clean this looks. The next log looks exactly as clean — and it is the attack.
LOG ILLUSTRATIVE
Beat 2 · The attack
A valid credential, and not one refusable request
Same application. Same controls. A genuinely valid credential belonging to a synthetic identity
compromised for this demo. Watch the status codes.
10:11:02GET/t/acme/projects/4/tasks — authenticated, in tenant, in scope200
10:11:02GET/t/acme/projects/17/tasks — authenticated, in scope200
10:11:03GET/t/acme/projects/23/comments — authenticated, in scope200
10:11:03GET/t/acme/projects/31/tasks — authenticated, in scope200
10:11:04GET/t/acme/projects/9/comments — authenticated, in scope200
10:11:04GET/t/acme/projects/44/tasks — authenticated, in scope200
— read one line: nothing to report. read the window: 31 unrelated projects in 94 seconds, from one actor. —
The anomaly does not exist in a row. It exists in the window.
LOG ILLUSTRATIVE
Beat 3 · Correlation
One incident record — joined, evidenced, and named
The requests stop being log rows and become a single incident: joined on the principal, the tenant,
the session identifiers, the source addresses and the user agents, carrying the list of event ids
that make up its evidence. On top of that join the incident names what it is seeing — and the
campaign stages those signals imply.
authorized access — ordinary workauthorized access — campaign fan-outDRAWN BY HAND — REPLACED BY A CAPTURE OF THE LIVE INCIDENT RECORD
BREADTH
how much of the tenant one actor reached
NOVELTY
endpoints this identity had never touched
CADENCE
a rhythm no person types
PIVOT
how fast it moves on after a refusal
DENIAL SHAPE
the pattern of what it was refused
ESCALATION
reaching for more than it started with
CANARY
resources that exist only to be touched by mistake
STAGES
the campaign stage signature those signals imply
That is the artifact the responders receive — not a log excerpt, and not a paragraph we wrote for them.
A structured incident record with its evidence attached, that any of the five can walk for itself.
Beats 4 & 5 · Escalation and response
One incident out, five assessments back
HERMES
Publishes the incident — the only write it is allowed
COTAL
One channel out; no path between the five responders
SKILLS
Each loads the skills it thinks the case needs, and reports which
— five assessments in, each written without sight of the other four. the counts are on the decision panel. —
What we refuse to do is let the first confident answer become the decision.
ALL FIVE ASSESSMENTS ARE LIVE AND UNEDITED — runs/six-live-e2e/assessments/NARRATION PREDATES THIS RUN — the recorded line describes a four/one split. On
six-live-e2e all five returned
malicious (0.85–0.95). The point it makes still holds: no responder can see another's answer,
so agreement is a result, not a shared prior.
Beats 6 & 7 · Action, and the half usually skipped
Narrow containment — while everyone else keeps working
What policy did
The five narrow actions the coordinator decided, each applied and verified.
revoke_sessionsess_anon_5b31…CONTAINED
revoke_sessionsess_c9f4a1b2…CONTAINED
suspend_principalc_32bfd983…CONTAINED
force_reauth · raise_loggingAPPLIED
Tenant t_acme not locked · service availability UNTOUCHED
The other lane — same tenant, same second
40 of 40 bystanders in t_acme kept serving while containment was in force —
0 denied. A representative sample:
u-mara POST /t/acme/tasks 200 OK
u-devon GET /t/acme/projects/4 200 OK
u-priya POST /t/acme/comments 200 OK
u-sam GET /t/acme/projects/9/tasks 200 OK
u-mara PATCH /t/acme/tasks/311 200 OK
The claim this beat exists to prove
No service shutdown. No tenant lock. No mass sign-out. And the prior state was snapshotted before
anything changed, so the reversal already exists at the moment the action does. Containment that stops
the business is not containment — it is a slower outage.
LIVE RUN — 40/40 BYSTANDERS SERVING, 0 DENIED · CONTAINED SUBJECT BLOCKEDSAMPLE USER ROWS ILLUSTRATIVE
Beat 8 · Proof and reversal
Everything on the record — and undone in one recorded operation
all five verdicts, confidences, rationales and skills used — unedited
yes
decision
verdict counts, quorum met, degraded flag, the computed score
yes
action
the containment kind, its target, its TTL, and the prior state it snapshotted
yes
rollback
state → rolled_back · session restored · recorded like any other operation
yes
The argument, in full
Recognise behaviour instead of requests. Decide with five independent models and a rule that is not a
model. Contain narrowly, prove it, and reverse it.
LIVE RUN six-live-e2e — ALL SIX RECORDS WRITTEN ·
control_surface_after_rollback: []
Honesty panel
What this page is, right now
Real today
One live end-to-end run, six-live-e2e, on six models across six harnesses — 6/6 effort receipts, none blocked, mocked or downgraded.
Five independent assessments, unedited on disk: 5/5 malicious, confidence 0.85–0.95. All five named campaign stages 2, 3 and 4; Claude and Kimi independently added stage 6. Four of the five explicitly flag the planted prompt injection in the untrusted evidence.
The deterministic coordinator: score 4.54, quorum met, not degraded, contain: true — plain Jac, no model.
The containment executor: five actions applied, verified and rolled back, control_surface_after_rollback: [], final_state ROLLED_BACK, health pass.
The Northwind gateway, domain walkers and Hermes detector — running, and the source of the live allow/deny probes. 40 of 40 bystanders kept serving during containment.
The vendored skills library, pinned to a commit, 817 skills. The full walkthrough: seventeen scenes, all voiced, all visuals in.
Still illustrative — and labelled as such
The two request logs in beats 1 and 2, and the sample user rows in beat 7. The run they depict is real; those particular rows are hand-written.
The incident-graph drawing — still hand-drawn, not a capture of the live incident record.
The per-responder weights and the exact score formula — the one number in this design we have not fixed. The narration says so out loud, and we would rather say so than invent one.
The ▶ button on the demo tab animates the eight beats; it is a scripted preview of the sequence, not a re-execution.
Two recorded narration lines predate the live run — the four/one split in scene 15 and “Gemini 3.1 Pro” in scene 9. Both are corrected on screen where they occur.
Attribution. Cotal is third-party open source; we use it as a dependency and did not author it.
The cybersecurity skills library mukul975/Anthropic-Cybersecurity-Skills (817 skills, Apache-2.0)
is community-maintained and is not an official Anthropic release. Sources for scene 1 — Hugging Face security incident disclosure, 16 July 2026; TechCrunch, 21 July 2026;
corroborated by BleepingComputer, CNBC, Axios, Fortune and CNN. Re-check before presenting: the story is days old.
JacHacks SF 2026 · walkthrough frame · no credentials or environment values appear anywhere in this artifact.
build dev · frame-only · audio 17/17 · no captures