Security & Trust
Every write is signed. Every identity is verified. Every capability is pinned. ostk builds a defense-in-depth model that guarantees security from process sandbox to API boundary.
Defense-in-Depth Model
Security in ostk does not rely on a single firewall or sandbox boundary. Instead, four containment and audit layers wrap every agent action:
GPG-Rooted Trust Tiers
The kernel determines your tier at boot based entirely on your GPG keyring and active signatures. Tier defaults set the safety floor for filesystem and command execution:
Graduating Tiers via Ceremony
To transition from anonymous (T3) to a write-capable identity, you generate a GPG key, which moves you to T2. To reach T1, an active T0 or T1 holder must cross-sign your key. The cross-signature is verified at boot:
# T3 → T2: generate a GPG key $ gpg --full-generate-key $ ostk boot trust: T2 (read + narrow exceptions) # T2 → T1: have a T0 or T1 holder cross-sign your key $ ostk trust sign <your-fingerprint> # run by the cross-signer $ ostk boot trust: T1 (cross-signed, write access)
Capability Pins & Profiles
Pin caps bound what an agent can touch. While your trust tier sets the floor (you cannot write past it), custom pin profiles set a ceiling on top. The merge is a union of denies—pins can only attenuate capabilities; they can never relax tier defaults.
Bounding a Worker Profile
Create custom profiles inside .ostk/pins/<name>/pin.caps and activate them via the OSTK_PIN environment variable:
$ ostk issue_pin fix-bug created: .ostk/pins/fix-bug/pin.caps created: .ostk/pins/fix-bug/pin.boot $ cat .ostk/pins/fix-bug/pin.caps deny: write-kernel modify-governance deny-path: infra/ secrets/ .env* deny-verb: :shutdown # Execute agent bound to this pin profile $ OSTK_PIN=fix-bug ostk run .ostk/agents/fix-bug.af
Empirical Bounding with ostk learn
If you do not know what paths your worker needs, run it in observation mode to extract the minimal required permissions automatically:
$ ostk learn .ostk/agents/fix-bug.af --duration 120 LIMIT read-path src/ tests/ Cargo.toml LIMIT write-path src/ tests/ target/ LIMIT verb cargo build cargo test # Automatically apply the suggested LIMITs back into the Agentfile $ ostk learn .ostk/agents/fix-bug.af --apply
The Seven-Step Approval Chain
Every tool call requested by an agent passes through seven ordered validation steps. The chain sequences checks from cheapest/most-certain (pin caps) to most-expensive/ambiguous (human prompt). First match wins:
PIN_CAPS_HARD_DENY
Checks write capabilities against pin.caps. If matching write-kernel, modify-governance, or write-src, it is denied immediately. Fails closed.
DESTRUCTIVE_CHECK
Runs destructor checks on command strings. Dangerous commands (e.g. rm -rf) or active danger signals override all auto-approval paths and force a prompt.
KERNEL_READ_AUTO
If the command is exactly a read-only kernel inspect primitive (e.g. ostk ps, ostk clock, ostk show), it is automatically approved without prompts.
PERMISSION_MODE_GATE
Checks the active permission mode. Autonomous allows all; Auto allows standard reads; Governed and Plan deny all write classes by default.
SESSION_ALLOW_LIST
Checks transient in-memory approved verbs. If the operator approved a tool class with the "approve all" key, it is auto-approved until the session ends.
AGENTFILE_TOOL_PATTERNS
Compares the call target against Agentfile TOOL directives. Substring matches approve specific file paths or command classes.
USER_PROMPT
Falls back to prompting the human operator. Keybindings: y=approve, n=deny, a=approve class, Enter=deny (safety default).
Secrets Management & Masking
API keys never enter the LLM context. The kernel resolves credentials at execution time and injects them only into the environment of the active subprocess:
Interactive Secrets Administration
# Securely write a secret to the keychain $ ostk secret set ANTHROPIC_API_KEY Enter value: ●●●●●●●● ✓ stored in macOS Keychain (service: ostk, account: ANTHROPIC_API_KEY) # List stored secrets $ ostk secret list ANTHROPIC_API_KEY ✓ keychain GEMINI_API_KEY ✓ keychain OPENROUTER_API_KEY ✗ not found
Output Masking
To prevent accidental credential leaks in conversation histories or transcripts, all tool outputs (stdin, stdout, stderr, file reads, and errors) are passed through secrets::mask().
Any string matching a known API key structure with length ≥ 8 characters is automatically replaced with ●●●● (length).
Verifiable Audit Chains
Every action executed through a kernel session registers an entry in the append-only journal (.ostk/journal.jsonl). Each row is:
- Hash-chained: Contains the SHA-256 hash of the preceding line (
prev_hash). - Ed25519-signed: Signed in-process using the operator's session-key.
- Verifiable: You can replay and cryptographically verify the entire stack history at any time.
# Cryptographically audit the local journal $ ostk os audit audit: 18,442 rows, hash chain ok, signatures verified # Inspect the running log $ tail -f .ostk/journal.jsonl {"event":"tool.fs_ops","path":"src/lib.rs","gen_before":4,"gen_after":5,"writer":"claude-code-1","ts":"2026-05-22T21:42:11Z","prev_hash":"...","sig":"..."} {"event":"tool.bash","cmd":"cargo test","exit_code":0,"duration_ms":1842,...}
Because writes are audited and tracked, if two agents attempt to edit the same file concurrently, the kernel detects a generation conflict (gen_before mismatch) and rejects the write with an OCC (Optimistic Concurrency Control) error, preventing silent overwrites.
Signed Portable State (Bail)
A bail is a signed, compressed archive (.bail) containing identity metadata, INIT sequences, and selective workspace states. It allows operators to transfer state between isolated instances without reliance on shared filesystems or network servers.
Contains public bootstrap states (.boot/INIT, .primefile, ENTITYFILE). Signed with Ed25519. Safe to share publicly.
Adds encrypted internal kernel database (os.bin). Requires recipient key declarations. Unpack is strictly fail-closed on signature mismatches.
Selective export of needles, decisions, and markdown docs. Recipient merges items labeled with [I] import markers. GPG-signed.
Bail Administration Commands
ostk bail pack Pack full encrypted bundle. Defaults to public mode if no recipient key is configured. ostk bail pack --public Pack public bootstrap files (.boot/INIT, .primefile, ENTITYFILE). ostk bail pack --export @identity Export selective needles, decisions, and docs matching a query. ostk bail verify <file> Cryptographically verify all detached signatures inside the bail without unpacking. ostk bail unpack <file> Verify and merge the bail contents into the local .ostk/ directory. # Verify a bail package received from another machine $ ostk bail verify project-export.bail ostk bail verify: /tmp/project-export.bail Ed25519: VERIFIED (inline) GPG: no manifest.json.asc in bail created: 2026-05-22T14:23:10Z files: 5
Key Rotation & Revocation
If a private key is compromised, it must be revoked without invalidating historical signatures. Revocation uses the following workflow:
# Record a key revocation $ ostk trust revoke 7141A45868F8295E5BEB6286BAF08C963C7E3184 --reason "leak" ✓ Revocation registered # Generate a new key and request cross-signing $ gpg --full-generate-key $ ostk trust sign <new-fingerprint>