Skip to content

Security: rpwalsh/scce

Security

docs/SECURITY.md

SCCE Security Posture

Status: Living document. Updated 2026-04 hostile-review pass. Reviewer-facing: the goal is no surprises if you're auditing this for deployment in a regulated, high-assurance, or air-gapped environment.

1. Threat surface (one page)

Surface Mitigation
HTTP API Fastify with strict body-limit, CORS allowlist, per-request UUID, sanitized error envelopes (no stack traces leaked)
Auth Bearer-token via SCCE_API_TOKEN; fail-closed in production unless SCCE_DEV_MODE=1 is set explicitly
Rate limit Token-bucket per identity (apiKey > x-forwarded-for > socket); heavy routes (/api/reason, /api/compose) get a 12-burst / 1-per-5s policy
Hostile prompts Frame-injection sanitizer in packages/core/src/promptSanitizer.ts; refuses prompts containing nested role tokens, system-override imperatives, base64 payloads above thresholds
Hostile reviews packages/core/src/hostileReviewGuards.ts refuses to count reviews from cold reviewer accounts, identical-template reviews, or reviewers whose corpus contradicts itself
Federation poisoning Bundle imports are weighted by signer reputation + signature freshness + corroboration count; see packages/core/src/federationTrust.ts
Unsupported claims Per-sentence faithfulness check (packages/core/src/citationFaithfulness.ts) — sentences whose content tokens are not grounded in any cited excerpt fire unsupported_claim and force shouldAbstain when the floor is breached
Internal contradictions Functional-predicate contradiction detector (packages/core/src/contradictionDetector.ts) — born_in, capital_of, equal_to etc. cannot have two competing high-confidence values without flagging
Confidence inflation Calibration layer (packages/core/src/confidenceCalibration.ts) — runtime announces "CALIBRATION OFF (identity)" via /health/deep until a fitted curve is loaded
CPU bombs Hard clamps on every public route: /api/reason beam ≤ 16, hops ≤ 5, sentences ≤ 12, question ≤ 1024 chars; /api/compose prompt ≤ 2048; /api/environment/scan files ≤ 5000 / 50 MB
Stack-trace leakage Unified error envelope {error, code, requestId} set in apps/server/src/middleware/requestContext.ts; 5xx never returns err.message, only 'internal error'
Observability Prometheus exposition at GET /metrics (counters, histograms); per-request logger child with reqId; deep diagnostics at GET /health/deep (no auth bypass on data, only the indicator endpoint itself)

2. Things SCCE does NOT do

These are intentional and reviewer-relevant:

  • No outbound network calls at runtime. The brain is offline by design.
  • No LLM in the loop — neither for generation nor for re-ranking.
  • No silent fallback to "best guess" when evidence is thin. Abstain is the default; shouldAbstain=true is returned with a machine-readable rationale.
  • No exposure of stack traces to clients on 5xx.
  • No untrusted code execution. The codegen route stubs out unsafe template surfaces.
  • No telemetry. Prometheus exposition is local-only by default; bind your reverse proxy to localhost.

3. Operational guidance

SCCE_API_TOKEN=<long-random>            # required in production
SCCE_DB_URL=postgres://…                # required, no default
SCCE_CORS_ORIGINS=https://your.app      # comma-separated allowlist
SCCE_BODY_LIMIT_MB=50                   # default 50
SCCE_FORCE_RATE_LIMIT=1                 # makes rate limiter active in dev too
SCCE_CALIBRATION_PATH=data/calibration.json  # optional, loads piecewise-linear curve
SCCE_BUNDLE_PATH=…                      # path to signed brain bundle

The server logs the calibration status at startup. If you see Calibration: CALIBRATION OFF (identity) in the logs, every reported self-confidence is the raw blended score — usable, but not calibrated to your evaluation suite.

4. Disclosure

Report vulnerabilities to security@walshtechnicalgroup.com. We commit to acknowledge within 72 hours and to publish coordinated disclosure timelines for any CVSS ≥ 7.0 issue.

There aren’t any published security advisories