ἕρκος — the defensive rampart.
Your never-list, enforced everywhere. You declare a short list of things an agent must never do on your machine — read your credentials, pipe fetched code into a shell — and herkos compiles that one policy into every agent harness you have installed, and enforces it in every mode, including headless and bypass/skip-permissions runs.
npx herkos init # detect installed harnesses, wire the policy into each
npx herkos check # prove the never-list is enforced
npx herkos status # what's protected, and with which rulesOut of the box, before any configuration, herkos blocks the near-universal never-list:
- Credential reads — SSH private keys, cloud credentials (AWS/GCP/Azure),
Kubernetes config,
.env-class files,.netrc/.npmrc/.pypirc, the GnuPG private keyring, Docker auth, and macOS keychain dumps. - Fetched-code execution — piping downloaded content straight into a shell
(
curl … | sh,eval "$(curl …)").
These are curated to be near-zero false alarm — the kind of thing no agent
session should ever legitimately do. You extend them with your own rules in
~/.config/herkos/policy.json, and you can disable any baseline rule by id
(per-rule and explicit, never "turn the guard off").
herkos is harness-agnostic at the policy layer (one never-list) but delivers enforcement through each harness's own extension point, so how much it can enforce depends on what the harness exposes:
- Claude Code — full enforcement. herkos installs a small, self-contained
shell hook on
PreToolUsethat blocks both rule classes on every tool call, in every mode (including headless / skip-permissions). - Codex CLI — credential reads OS-enforced; fetched-code via a hook you trust
once. herkos compiles the credential never-list into a Codex permission
profile whose filesystem
denyentries are enforced by the OS sandbox (Seatbelt/Landlock) — verified: a read of a denied path returnsOperation not permitted. This half is seamless and arguably stronger than a hook. For fetched-code, herkos installs the same shell hook into Codex'sPreToolUse, but non-managed Codex hooks require a one-time trust step — run/hooksin Codex once to activate fetched-code blocking (credential denies are live immediately). Requires Codex ≥ 0.146.
Adding a harness is adding an adapter, not redesigning — the policy never changes.
- Not a sandbox. OS-level containment is the platforms' job and they do it natively; herkos removes the payoff of a hijacked agent (reading and shipping your secrets), it does not jail the process.
- Not protection against everything. It enforces a declared never-list. A risk you don't put on the list is one it won't stop.
- Not a set-and-forget-and-never-check tool. Harnesses change; run
herkos checkafter upgrades, or on a schedule.
~/.config/herkos/policy.json:
{
"rules": [
{
"id": "my-vault",
"class": "credential-read",
"description": "Company vault dir",
"paths": ["secrets/prod/"]
}
],
"disable": ["docker-auth"]
}npm install
npm test # includes a self-check that runs the real generated hook
npm run build
npm run typecheckRoadmap: ROADMAP.md · Decisions: DECISIONS.md
