Skip to content

Security: markmhendrickson/neotoma

SECURITY.md

Security Policy

Supported Versions

Version Supported
0.13.x Yes
0.12.x Yes
< 0.12 No (patch only on critical advisories — see advisories index)

The most recent published Neotoma version is the only one that receives proactive support. Critical advisories may produce a one-off patch on the previous minor when the affected range is large; see the per-advisory file under docs/security/advisories/ for the exact range.

Reporting a vulnerability

If you discover a security vulnerability in Neotoma, please report it privately. Do not open a public GitHub Issue.

  • Preferred: Use the repository Security page to send a private vulnerability report to the maintainers (the same UI that opens a private GitHub Security Advisory).
  • Email fallback: if the GitHub flow is not available, email security@neotoma.io (or the address listed on the Security page) with the same content the GHSA template asks for.
  • Response time: we aim to acknowledge a private report within 48 hours and confirm or refute the regression within 5 business days.
  • Include: description of the vulnerability, affected versions, reproduction steps (sanitized of any real data or credentials), suggested fix when known, and the disclosure timeline you prefer.

Disclosure flow

  1. Private intake. A reporter files via the GitHub Security tab or security@. The maintainer opens (or accepts) a private GHSA and requests a CVE when warranted.
  2. Hotfix branch. Fix lands on hotfix/<version>-<slug> cut from the affected main SHA, with regression tests under tests/integration/ or tests/security/ that fail on the pre-fix code and pass post-fix.
  3. Pre-release security gates (docs/security/threat_model.md, .cursor/skills/release/SKILL.md):
    • G1 npm run security:classify-diff confirms the diff is sensitive.
    • G2 npm run security:lint is clean.
    • G3 npm run security:manifest:check + npm run test:security:auth-matrix are green.
    • G4 docs/releases/in_progress/<TAG>/security_review.md is filled and signed off.
  4. Coordinated release. Tag, GitHub Release, npm publish, and Fly deploy follow .cursor/skills/release/SKILL.md.
  5. Deployed probes. G5 bash scripts/security/deployed_probes.sh --tag <TAG> runs from an external host; the report lands at docs/releases/in_progress/<TAG>/post_deploy_security_probes.md.
  6. Public advisory. A dated file is added to docs/security/advisories/ using the template in that directory's README.md. The release supplement's Security hardening section links the advisory and the post-deploy probe report.
  7. Direct notification. The maintainer reaches out to known operators (issue threads, mailing list, peer instances when Track 2 lands) with the upgrade instruction and any rotation guidance.

Security model

Neotoma implements defense-in-depth at the State Layer:

See docs/subsystems/auth.md, docs/subsystems/aauth.md, and docs/subsystems/privacy.md for details.

Pre-release gates (operator-visible summary)

Every release runs through the pre-release security gates before tagging and again after deploy:

Gate Stage What it does
G1 — diff classifier PR + /release Step 3.5 Flags any change touching src/actions.ts, src/services/{root_landing,auth,aauth,subscriptions,sync,issues,entity_submission,access_policy}/**, src/middleware/**, openapi.yaml security blocks, or `LOCAL_DEV_USER_ID
G2 — static rules PR + /release Step 3.5 npm run security:lint — Semgrep rules (with a Node fallback runner) for the v0.11.1 bug class.
G3 — auth topology matrix PR + /release Step 3.5 npm run test:security:auth-matrix — cross product of transport × env × X-Forwarded-For × socket; manifest sync against openapi.yaml.
G4 — AI adversarial review /release Step 3.5 npm run security:ai-review — produces docs/releases/in_progress/<TAG>/security_review.md for human sign-off.
G5 — deployed probes /release Step 5 + weekly bash scripts/security/deployed_probes.sh — external probe of every protected route in the manifest against the live host.

The full plan and rationale are in .cursor/skills/release/SKILL.md.

Security best practices for operators

When deploying or developing Neotoma:

  1. Set NEOTOMA_BEARER_TOKEN for any deployment exposed to the public internet, even when the deployment is behind a reverse proxy. Loopback alone is not a trust signal; the v0.11.1 advisory documents that regression class.
  2. Set NEOTOMA_ENV=production explicitly in production. The runtime infers production by default, but explicit env variables improve observability and unlock the production-safe loopback policy.
  3. Use OAuth or AAuth for verified MCP attribution rather than long-lived bearer tokens whenever the harness supports it.
  4. Use HTTPS for all API endpoints and Inspector access.
  5. Verify configuration with npm run doctor before exposing the server.
  6. Keep storage paths and data directories private; do not symlink them into a web-served directory.
  7. Rotate bearer tokens periodically and after any advisory in docs/security/advisories/ whose affected range includes your deployment.
  8. Never commit .env or credentials — see docs/conventions/code_conventions.md.
  9. Tune the guest-write and token-TTL knobs for hosted / multi-tenant deployments. The defaults (NEOTOMA_GUEST_WRITE_RATE_LIMIT_PER_MIN=30, NEOTOMA_GUEST_TOKEN_TTL_SECONDS=2592000) suit single-tenant self-hosted instances; lower them in hosted contexts. See docs/security/threat_model.md ## Operator hardening knobs.
  10. Set NEOTOMA_HOSTED_MODE=1 on hosted / multi-tenant deployments so inbound peer-sync rejects private / loopback sender_peer_url values; see docs/subsystems/peer_sync.md ## Concepts.
  11. Set MCP_PROXY_FAIL_CLOSED=1 on AAuth-signed hosted MCP proxies so unsigned downstream requests are refused when signing or session preflight fails; see docs/developer/mcp/proxy.md.

Index

Learn more about advisories related to markmhendrickson/neotoma in the GitHub Advisory Database