Security Policy
Keystone OS is a private, local-first workspace. Treat local state as sensitive: journal data, RAG records, runtime receipts, secrets, tokens, operator notes, and private test artifacts must not be committed or shared publicly.
Reporting Security Issues
Do not open public issues for secrets, authentication bypasses, private data exposure, unsafe remote dispatch, tunnel exposure, or local MCP/tooling leaks.
Use a private channel with the repository owner and include:
- A short description of the issue.
- The affected file, service, route, or workflow.
- Reproduction steps, if safe to share.
- Whether the issue was locally verified.
- Any redacted evidence paths or logs.
Local-First Verification
Before trusting a remote endpoint, tunnel, mirrored surface, or advertised tool catalog, verify the local source of truth:
- Git state and dirty worktree risk.
- Local service health.
- Actual exposed MCP tools.
- Queue, task, and log state when dispatch is involved.
Secret Handling
- Keep real secrets in ignored local environment files or a secret manager.
- Commit only safe examples such as
.env.example. - Rotate any secret that appears in Git history, logs, screenshots, or public
surfaces.
Critical Security Fixes (2026-06-08)
File Serving Path Traversal (routes/files.js)
Status: ✅ FIXED
Replaced unsafe startsWith() boundary check with path.relative() + denylist. Prevents access to .env*, data/private/, runtime files, and secrets.
Python Command Injection (routes/dream.js)
Status: ✅ FIXED
Removed user input interpolation from Python -c scripts. All untrusted data (userId, choice, entry content) now passed via stdin JSON with sys.stdin.read().
HTTP Security Headers (http-utils.js, server.js)
Status: ✅ FIXED
Removed CORS wildcard (Access-Control-Allow-Origin: *). Added CSP, X-Frame-Options, Permissions-Policy, Referrer-Policy to all HTML responses.
Best Practices (All Agents)
- NEVER interpolate user input into:
- Python
-cor-mscripts - Shell commands
- SQL queries (if applicable)
- File paths (use
path.relative()for boundary checks)
- Python
- ALWAYS:
- Use
path.relative(root, target)for file operations - Pass untrusted data via stdin, temp files, or argv with argparse
- Validate input types and lengths
- Maintain deny-lists for sensitive directories
- Use
- Test before commit:
npm run test:api --prefix apps/lantern-garage
curl http://localhost:4177/repo/../../../.env # Should 403 Forbidden
Agent Safety Principles (absorbed from GitHub Agentic Workflows)
The autonomous fleet (pr-watcher, autowork, Keystone) follows the defense-in-depth model proven by GitHub Agentic Workflows: agents propose, humans dispose. Five rules, with current status:
| # | Rule | Status | Where |
|---|---|---|---|
| #1251 | Protected-path human gate — a PR touching auth, trading/money, secrets, .github/workflows, schema, or SECURITY.md is never auto-merged; a human reviews it. Docs/deps/UI keep auto-merging. |
✅ Enforced | PrWatcher._shouldMerge + DEFAULT_PROTECTED_PATHS (override: PR_WATCHER_PROTECTED_PATHS) |
| #1252 | Untrusted external text — issue/PR/web content is data to analyze, never instructions to obey (prompt-injection guard). Reinforces the Σ₀ External Reality Rule. | ✅ In review prompt | PrWatcher._reviewPr message preamble |
| #1253 | Read-only by default; writes via a safe-output allowlist — agents emit pre-approved output types (open-PR, comment, label), not ambient write. | 🚧 Policy; enforcement follow-up | — |
| #1254 | Egress + secret sandboxing — constrain agent runs to an egress allowlist + scoped secrets so they can't re-introduce PII or leak keys. Worktree isolation is half. | 🚧 Policy; implementation follow-up | autowork-worktree.js (isolation only) |
| #1255 | Spec → artifact separation — keep agent intent in a reviewed plain-language spec; review the spec as code (à la gh-aw's .md → .lock.yml). |
🚧 Pattern; skills/SKILL.md leans this way |
— |
Read-Only Agents and Safe-Output Allowlist
By default, fleet agents (e.g., pr-watcher, autowork) operate in a read-only mode. They are designed to analyze, observe, and report without making direct modifications to the repository or system state.
Any write operations are strictly limited to a safe-output allowlist. This allowlist currently includes actions such as opening pull requests, adding comments, or applying labels. This policy ensures that agent actions are transparent, auditable, and confined to well-defined, non-destructive outputs.
Status: This is a policy declaration. Enforcement mechanisms (e.g., sandboxing, capability-based security) are a follow-up task.
The one deliberate divergence from
gh-aw: it never auto-merges. We do, by Alex's explicit choice — but the #1251 gate confines auto-merge to low-risk surfaces so sensitive changes still land on a human's desk.