Skip to content

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:

TOOL_LAYER
Deny-based capability pins. Every tool call requested by the agent is checked against pin.caps deny tokens and path boundaries before execution.
SYSCALL_LAYER
Process-level sandboxing via Landlock (Linux) and Seatbelt (macOS). Restricts filesystem access at the OS kernel layer, enforcing boundaries even if the agent forks a shell.
AUDIT_LAYER
Append-only JSONL event log. Every action is timestamped, attributed, hash-chained to the previous row, and Ed25519-signed in-process. Replaying the log reconstructs verified state.
SECRET_LAYER
API keys are resolved at execution time from the platform keychain or local secret manager. Values never enter the LLM context and are masked from all stdout/stderr logs.

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:

GPG Trust Tiers Hierarchy
T0
Kernel Trust Anchor
Hardcoded in src/kernel/identity.rs (shipped with binary)
None — full governance authority
T1
Cross-Signed Identity
Your GPG key signed by a T0 key
Write access to source/needles. Denied: write-kernel, modify-governance
T2
Unsigned GPG Identity
GPG key exists but lacks T0/T1 cross-signature
Read everything. Narrow write exceptions. Denied: write-src, write-kernel, modify-governance
T3
Anonymous Mode
host_identity discovers no local GPG keys
Boots read-only. All writes through the tool layer are denied by default

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:

TERMINAL
# 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.

Pin Enforcement Flow
CAPABILITY_TOKEN
AFFECTS
DESCRIPTION
deny: write-kernel
.ostk/ state
Blocks all writes to internal kernel database and settings
deny: modify-governance
Governance files
Blocks modifications to .primefile, GOVERNANCE.md, ENTITYFILE, and Agentfiles
deny: write-src
Project source
Blocks all writes to main project directories and codebase source files
deny-path: <path>
Path matching
Blocks write, creation, or deletion of files matching prefix or substring
deny-verb: <cmd>
Tool commands
Blocks execution of exact or prefix-matched CLI or shell verbs

Bounding a Worker Profile

Create custom profiles inside .ostk/pins/<name>/pin.caps and activate them via the OSTK_PIN environment variable:

TERMINAL
$ 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:

TERMINAL
$ 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:

01

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.

02

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.

03

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.

04

PERMISSION_MODE_GATE

Checks the active permission mode. Autonomous allows all; Auto allows standard reads; Governed and Plan deny all write classes by default.

05

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.

06

AGENTFILE_TOOL_PATTERNS

Compares the call target against Agentfile TOOL directives. Substring matches approve specific file paths or command classes.

07

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:

01
BYO_SECRET_MANAGER
User-defined secret_cmd inside .ostk/config (e.g. bw, op, pass). Env var injections are blocked here to prevent exfiltration.
02
PLATFORM_KEYCHAIN
Uses OS native keychain services: security find-generic-password on macOS, secret-tool lookup on Linux.
03
ENVIRONMENT_VARIABLES
Standard shell environment fallback ($KEY). Least secure—visible in process tables.

Interactive Secrets Administration

TERMINAL
# 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.
TERMINAL
# 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,...}
CONCURRENCY & OCC INVARIANTS

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.

PUBLIC_MODE

Contains public bootstrap states (.boot/INIT, .primefile, ENTITYFILE). Signed with Ed25519. Safe to share publicly.

FULL_MODE

Adds encrypted internal kernel database (os.bin). Requires recipient key declarations. Unpack is strictly fail-closed on signature mismatches.

EXPORT_MODE

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.
TERMINAL
# 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:

01
Execute ostk trust revoke <fingerprint>, signed by a valid authority key (T0 or T1).
02
The revocation event is written to the journal, binding the compromised fingerprint.
03
The kernel reads the revocation list at boot. All actions signed by the key BEFORE the revocation timestamp remain valid; future actions are rejected.
04
The operator generates a fresh GPG key and initiates the cross-signing ceremony to re-establish a T1 identity.
TERMINAL
# 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>