Security engineering log

Every hardening sprint, written down in full.

tun-el is partly a hosted service. You trust us with your tunnels, sometimes with your data. We believe radical transparency about security — including what is not yet covered — is the best way to earn that trust.

Timeline

9 entries
  1. 2026-05-29Sprint 8MAR-94

    Abuse detection + auto-revoke

    Sprint 7 laid down the traversing rate limit — passive detection. Sprint 8 enforces: in-memory behavioral tracker, per-token accumulation of denials over a sliding window, auto-revoke plus teardown of active tunnels past threshold. 18 paranoid security tests (per-token isolation, idempotence under race, GC never touches a revoked entry, nil-safe). Zero regressions.

    abuseauto-revokebehavioraudit
    Read the full write-up
  2. 2026-05-29Sprint 7MAR-93

    Traversing HTTP rate limit (3 axes)

    Before: HTTP requests flowing through the tunnels were not rate-limited — abusive bandwidth, hotlinking, pass-through DDoS. Sprint 7 introduces a 3-axis rate limit (tunnel + token + IP) with an IP → tunnel → token short-circuit to avoid amplification, configurable env vars, and a dedicated audit event.

    rate-limitddosabuseaudit
    Write-up coming
  3. 2026-05-28Sprint 6MAR-70

    Token peppering on self-host

    On the SaaS side, the pepper had been active since init. On self-host (tokens.json), the hash was a bare SHA-256(secret). Sprint 6 extends Store to accept an optional pepper via TUNL_TOKEN_PEPPER, backward compatibility preserved bit-for-bit, fail-loud on invalid format.

    tokensself-hostdefense-in-depth
    Write-up coming
  4. 2026-05-28Sprint 5MAR-100

    Persistent error logging on SaaS

    Capture of errors surfaced in app/error.tsx into a Supabase table indexed by digest, with full context (message, stack, path, user_id, user_agent). Strict RLS (INSERT service_role only, SELECT own), per-field truncation, fire-and-forget on the client.

    observabilitysupabaseserver-actions
    Write-up coming
  5. 2026-05-28Sprint 4MAR-71

    Strict protocol-version check at handshake

    Clean reject of an incompatible client (instead of a crash after the handshake), a transport-side error sentinel to tell a version mismatch apart from an auth failure, a clean client-side exit instead of reconnect spam, and a WARN audit event to drive version bumps.

    protocolhandshakefail-fastaudit
    Write-up coming
  6. 2026-05-28Sprint 3MAR-69

    Strict CSP on the embedded inspector

    Removal of every third-party resource (Tailwind CDN, Google Fonts), self-hosting of the Geist Variable fonts, full de-inlining of JS and CSS, and a 9-directive CSP applied to every route — assets and API included.

    cspinspectorfrontendsupply-chain
    Write-up coming
  7. 2026-05-28Sprint 2MAR-66MAR-67MAR-68

    Edge hardening and security observability

    Systematic 308 → HTTPS redirect, security headers HSTS preload + nosniff + X-Frame-Options + Referrer-Policy (Go and Next.js aligned), and a structured JSON Lines audit log covering sensitive events.

    httpshstsaudit-log
    Write-up coming
  8. 2026-05-27Sprint 1MAR-61MAR-62MAR-64

    Control-plane hardening

    WebSocket origin check, handshake rate-limiting, tunnel quotas, elimination of a subtle race on subdomain allocation, and a memory bound on the handshake.

    websocketrate-limiting
    Write-up coming
  9. 2026-05-27Audit

    SAST audit — gosec + Semgrep + CodeQL

    Static analysis of the Go code with three complementary tools. Every finding triaged true/false positive, justified, and linked to its fix.

    sastgosecsemgrepcodeql
    Write-up coming
Analysis pipeline

The full chain, from code to production.

Every layer is traced, every tool is replayable, every run is archived. Target: MAR-106.

14/19
Tools wired
1
Partial tools
11
Archived runs
11/11
Pass verdict

Source code

SAST

operational
  • Semgrep
  • gosec
  • staticcheck

Source code

Data flow

operational
  • CodeQL
  • Bearer

Source code

Semantic

partial
  • Joern
  • Qwiet

Supply chain

Deps & CVE

operational
  • govulncheck
  • Trivy (fs + binary)
  • Grype
  • Syft (SBOM)

Runtime

Tests

operational
  • go test -race
  • go fuzz

Runtime

DAST (black box)

to wire
  • OWASP ZAP
  • Burp Suite
  • Nuclei

AI review

Automated reviews

operational
  • Claude /ultrareview
  • Vercel Agent
  • GPT-5

Audit log

11 runs archived · latest 2026-06-05T19:21

docs/security/AUDIT-LOG.md

TimestampRunVerdict
2026-06-05T19:21turbopass
2026-06-01T14:53supply-chainpass
2026-05-31T19:32supply-chainpass
2026-05-29T02:30sprint-8pass
2026-05-29T01:10sprint-7pass
2026-05-29T00:30sprint-6pass
2026-05-28T23:55sprint-5pass
2026-05-28T23:30sprint-4pass
2026-05-28T22:00sprint-3pass
2026-05-28T11:00sprint-2pass
2026-05-27T20:24turbopass

Append-only. Every run is versioned in the repository under docs/security/audits/<date>/ with its raw outputs (SARIF, JSON) and a run.json manifest.

Why this page?

tun-el is partly a hosted service. You trust us with your tunnels, sometimes with your data. We believe radical transparency about security — including what is not yet covered — is the best way to earn that trust. The complete reports are also versioned in the upcoming public repository, under docs/security/.