Skip to content

Latest commit

 

History

History
52 lines (48 loc) · 2.92 KB

File metadata and controls

52 lines (48 loc) · 2.92 KB

AGENTS.md — Rules for AI agents working in this repo

This repository builds a security tool. The same discipline applies to agents that develop it.

Secret handling (hard rules)

  • Never read key.txt or secrets.enc directly (test fixtures excepted, and even then only via the store package API).
  • Never print, log, or commit a secret value — including in test output.
  • When debugging the store, use the store's own List() (masked) or assert on masked forms, not raw Get().
  • e2e_test.py intentionally asserts plaintext does NOT appear in MCP output. Keep it that way.
  • verify_redeem.py asserts on hashes, /proc/<pid>/environ and /proc/<pid>/cmdline — never print a value to check one. Keep it that way.
  • If you must inspect an on-disk blob, read it as bytes and check only for the armor markers / absence of plaintext — never dump the decrypted data.

Security invariants (do not regress)

  1. secrets.enc must never contain plaintext key material (age-encrypted).
  2. key.txt must be 0600, store dir 0700.
  3. Every MCP tool result and resource must be masked — no plaintext in tool results, ever.
  4. put must accept a value_file path, read it, and delete it after.
  5. Masking rules live in internal/mask — keep the entropy/prefix/URL segmentation tests green.
  6. Redemption fails closed (internal/redeem, docs/THREAT-MODEL.md). On any error — unknown session, expired session, name not issued in that session, missing or empty value, malformed reserved prefix, token in argv, audit write failure — the command is NOT started. There is no fallback that forwards the literal token and none that forwards the plaintext, and no error message may contain a value.
  7. Redemption never puts a value in argv, and never logs a value or a full argument list (<store>/audit.log records key names only).
  8. A bound token must be enforced. A token issued with --allow-host, --allow-path or --allow-header may only be redeemed when keysmith run --target satisfies every recorded binding (host match, path prefix, header present). A missing --target, a non-matching target, a non-https target (except loopback http) and a target carrying a query string all refuse. The binding is checked before the audit write and before the child starts, and a re-issue that would widen or drop a binding must fail with ErrBindingConflict.

Workflow

  • Run go test ./... before committing — all packages must pass.
  • Run go vet ./... — no warnings.
  • Run python3 e2e_test.py after any change to internal/mcp or internal/store — the protocol round-trip must stay green.
  • Run python3 verify_redeem.py after any change to internal/redeem or to the token/run commands — the fail-closed end-to-end checks must stay green.
  • Keep the Go SDK (github.com/modelcontextprotocol/go-sdk) on a version with no open OSV advisories; bump deliberately.