Skip to content

Instantly share code, notes, and snippets.

@jespada
Created July 7, 2026 20:59
Show Gist options
  • Select an option

  • Save jespada/9008b1e36ddd77ff6cf9623aee469b29 to your computer and use it in GitHub Desktop.

Select an option

Save jespada/9008b1e36ddd77ff6cf9623aee469b29 to your computer and use it in GitHub Desktop.
fedi-sec overview.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>fedi-sec — overview</title>
<style>
:root {
--bg: #0f1115; --panel: #171a21; --panel2: #1e222b; --ink: #e7e9ee;
--muted: #9aa3b2; --line: #2a2f3a; --accent: #6ea8fe; --good: #5bd6a0;
--warn: #f0b429; --bad: #f2739a;
}
@media (prefers-color-scheme: light) {
:root { --bg:#f6f7f9; --panel:#fff; --panel2:#f0f2f5; --ink:#1a1d24;
--muted:#5b6472; --line:#e2e6ec; --accent:#2563eb; --good:#0f9d6c;
--warn:#b7791f; --bad:#c02a63; }
}
* { box-sizing: border-box; }
body { margin:0; background:var(--bg); color:var(--ink);
font: 15px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
.wrap { max-width: 960px; margin: 0 auto; padding: 40px 20px 80px; }
h1 { font-size: 30px; margin: 0 0 4px; letter-spacing: -0.02em; }
h2 { font-size: 19px; margin: 40px 0 14px; letter-spacing: -0.01em; }
.tag { display:inline-block; font-size:12px; color:var(--muted);
border:1px solid var(--line); border-radius:999px; padding:2px 10px; }
.lede { color: var(--muted); font-size: 16px; max-width: 70ch; }
code, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; }
.pipe { display:flex; flex-wrap:wrap; gap:10px; align-items:stretch; margin:8px 0 4px; }
.step { flex:1 1 150px; background:var(--panel); border:1px solid var(--line);
border-radius:12px; padding:14px 16px; position:relative; }
.step h3 { margin:0 0 4px; font-size:14px; }
.step p { margin:0; color:var(--muted); font-size:12.5px; }
.step .n { position:absolute; top:10px; right:12px; font-size:11px; color:var(--muted); }
.arrow { align-self:center; color:var(--muted); font-size:20px; }
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:12px; }
.card { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:16px; }
.card h3 { margin:0 0 6px; font-size:14px; }
.card p, .card li { color:var(--muted); font-size:13px; }
.card ul { margin:6px 0 0; padding-left:18px; }
table { width:100%; border-collapse:collapse; margin-top:6px; font-size:13.5px; }
th, td { text-align:left; padding:9px 10px; border-bottom:1px solid var(--line); vertical-align:top; }
th { color:var(--muted); font-weight:600; font-size:12px; text-transform:uppercase; letter-spacing:.03em; }
.pill { font-size:11px; padding:1px 8px; border-radius:999px; border:1px solid var(--line); }
.pill.good { color:var(--good); border-color:var(--good); }
.pill.warn { color:var(--warn); border-color:var(--warn); }
pre { background:var(--panel2); border:1px solid var(--line); border-radius:12px;
padding:14px 16px; overflow-x:auto; }
a { color:var(--accent); }
.foot { margin-top:48px; color:var(--muted); font-size:12.5px; border-top:1px solid var(--line); padding-top:16px; }
</style>
</head>
<body>
<div class="wrap">
<span class="tag">v0.1 · laptop · Claude Max</span>
<h1>fedi-sec</h1>
<p class="lede">AI vulnerability-scanning harness for Fedi. Point Claude at a repo; it
hunts the bugs pattern-matchers and fuzzers miss — logic, auth/authz, Fedimint/Lightning
custody, Rust correctness — and verifies each one adversarially before it reaches a report.</p>
<h2>The pipeline</h2>
<div class="pipe">
<div class="step"><span class="n">0</span><h3>threat model</h3><p>Per-repo trusted-vs-attacker model. Read by discover + verify. The #1 false-positive reducer.</p></div>
<div class="arrow">→</div>
<div class="step"><span class="n">1</span><h3>discover</h3><p><code>claude -p</code> reads each file (read-only, injection-guarded) and proposes JSON candidates.</p></div>
<div class="arrow">→</div>
<div class="step"><span class="n">2</span><h3>verify</h3><p>Adversarial re-check. Evidence gate + verdict gate. Only survivors keep a real severity.</p></div>
<div class="arrow">→</div>
<div class="step"><span class="n">3</span><h3>report</h3><p><code>findings.json</code>, <code>TRIAGE.md</code>, SARIF. Stable fingerprints; diffable across runs.</p></div>
</div>
<h2>Two gates protect precision</h2>
<div class="grid">
<div class="card">
<h3>Evidence gate</h3>
<p>Every finding must cite a <code>quote</code> that matches the file byte-for-byte
(whitespace-normalized). A hallucinated quote is clamped to <code>insufficient-evidence</code>
— it can never reach P0/P1.</p>
</div>
<div class="card">
<h3>Verdict gate</h3>
<p>Verify is <em>refute-by-default</em>. Only a <code>verified</code> verdict keeps a
real severity; anything else (false-positive, mitigated, needs-investigation) is
demoted before it can be filed.</p>
</div>
</div>
<h2>What it hunts</h2>
<div class="grid">
<div class="card"><h3>Auth / authz boundaries</h3><ul><li>NIP-98 replay, missing verification</li><li>Bearer-token leakage, internal-port authz</li><li>IDOR / missing ownership checks</li></ul></div>
<div class="card"><h3>Fedimint / Lightning custody</h3><ul><li>Guardian quorum &amp; DKG assumptions</li><li>Gateway hot-wallet &amp; liquidity paths</li><li>Dual-control gaps on fund movement</li></ul></div>
<div class="card"><h3>Rust correctness</h3><ul><li>unwrap / panic on prod paths</li><li>Integer overflow, async-cancellation tears</li><li>Concurrent state-machine races</li></ul></div>
<div class="card"><h3>Input / injection / SSRF</h3><ul><li>Untrusted parsers (protobuf/CBOR/PSBT)</li><li>SQL injection, SSRF in fan-in services</li><li>Secret/PII leakage in logs &amp; metrics</li></ul></div>
</div>
<h2>Anti-drift guarantees</h2>
<table>
<tr><th>Guarantee</th><th>What it does</th><th>Status</th></tr>
<tr><td>Evidence validation</td><td>Quote must match the file, or the finding is clamped.</td><td><span class="pill good">v0</span></td></tr>
<tr><td>Stable finding IDs</td><td><code>sha256(repo·class·file·±3-line context)[:12]</code> — diffable, survives reformatting.</td><td><span class="pill good">v0</span></td></tr>
<tr><td>Fail-closed reporting</td><td>Total discover/verify failure aborts with no <code>findings.json</code>; no silent-clean reports.</td><td><span class="pill good">v0</span></td></tr>
<tr><td>Verdict gating</td><td>Only verified findings get severity + issue filing.</td><td><span class="pill good">v0</span></td></tr>
<tr><td>FP ledger</td><td>Expiring ignore-list; ignored findings labeled, not deleted.</td><td><span class="pill warn">v0.2</span></td></tr>
<tr><td>Regression fixtures (<code>smoke</code>)</td><td>Deterministic verify-phase guard; fails if a gate regresses.</td><td><span class="pill good">v0.1</span></td></tr>
</table>
<h2>Run it</h2>
<pre class="mono">nix develop # python + deps + gh + ruff (no pip)
pytest -q # unit tests
fedi-sec smoke # deterministic fixtures, no live model
# live single-file scan (~2 min, uses Claude Max):
fedi-sec scan decentralized-federations --crate push-gateway \
--classes authz --file nostr_http_auth</pre>
<h2>Provider today &amp; tomorrow</h2>
<div class="grid">
<div class="card"><h3>v0 — laptop</h3><p><code>claude -p</code> on the Claude Max subscription. No API key, no per-token cost. Read-only tool allowlist, scrubbed env, bounded resume loop.</p></div>
<div class="card"><h3>CI — later</h3><p>Same <code>Provider</code> interface, swapped to API-key or AWS Bedrock (OIDC). Adds a $ budget ledger + GitHub Actions cron. See SPEC §11–12.</p></div>
</div>
<div class="foot">
Source of truth: <a href="SPEC.md">docs/SPEC.md</a> · working rules:
<a href="../CLAUDE.md">CLAUDE.md</a> · Modeled on Anthropic's
<a href="https://github.com/anthropics/defending-code-reference-harness">defending-code reference harness</a>.
Docs and code move together — change one, update the SPEC in the same commit.
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment