Security
Deterministic by default. Hardened where it matters.
The CLI is designed to minimise exposure. The hosted service is designed to fail safe. Full posture in SECURITY.md. This page is the summary.
CLI
- No implicit network calls.
spine compile,spine drift check, andspine exportrun entirely offline. Workspace commands (login,publish,drift check --push) are the only surfaces that touch the network, and only after you explicitly opt in. - Bearer tokens at rest.CLI bearer tokens live in
~/.project-spine/config.jsonwith0600permissions. On the server side only a sha256 hash is stored; plaintext tokens never hit the database. - Opt-in LLM enrichment.Rationale enrichment via Anthropic's API is opt-in per command and requires an explicit key in env. Prompts run through a secrets scrubber (PATs, API keys, PEM blocks) before leaving your machine.
Hosted service (projectspine.dev)
- Auth.GitHub OAuth device flow for CLI; web OAuth for the workspace UI. The two share a single unified callback with cookie-bound state to prevent cross-device session fixation.
- Rate limits on every auth endpoint.Per-IP and per-device-code fixed-window limits backed by Postgres. Atomic UPSERT prevents thundering-herd bypass. Fails open if the DB is unavailable so auth never becomes unreachable because of a limiter bug.
- CSP with per-request nonce.
script-src 'self' 'nonce-<fresh>' 'strict-dynamic', with no'unsafe-inline'on scripts. Middleware mints a fresh nonce per request; every route renders dynamically so Next stamps it onto its inline RSC payload scripts. - Transport.HTTPS only.
.devis HSTS-preloaded at the TLD; we additionally sendStrict-Transport-Security: max-age=63072000; includeSubDomains; preload.
PlusX-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin,Permissions-Policylocking out geolocation / microphone / camera. - Authorization.Every workspace API route requires a valid bearer AND membership. Non-members get 404, not 403, so workspace existence isn't leaked.
- XSS on public rationale URLs.Markdown is rendered via
markedand then passed throughsanitize-htmlwith an allowlist. Scripts, iframes, inline styles, andjavascript:schemes are stripped. Rationales setnoindex, nofollow.
What we don't collect
- Your repo source.The CLI runs offline for compile and drift. Workspace commands upload only what you explicitly push: templates, rationales, drift summaries. Never the full repo.
- Analytics or third-party trackers.Zero. Check the site's Content-Security-Policy header in devtools.
connect-srcallows'self',api.github.com, andregistry.npmjs.org. Nothing else. - Request bodies in logs.Vercel logs access lines (IP, path, status, timestamp) only, retained per Vercel's policy. Tokens never appear in logs; API routes don't print auth headers.
Reporting vulnerabilities
Email security@projectspine.dev or use GitHub private vulnerability reporting on the repo. Acknowledgement within 72 hours, initial assessment within 7 days, coordinated disclosure on a timeline agreed with you.