Security
Last updated 2026-08-17 · describes the current implementation, verifiable in the source
The most sensitive thing this service can hold is a GitHub personal access token you optionally provide for faster refreshes and private-contribution counting. The design goal is simple: even a full copy of the database should not be enough to recover your token.
How stored tokens are protected
- Envelope encryption, split key. Your token is encrypted with AES-256-GCM. The encryption key is derived (HKDF-SHA-256) from two halves: a server-side master secret and a random key share that is embedded only in your card URL. The database stores the ciphertext but never the key share, so the server — or anyone who obtains its storage — cannot decrypt tokens without also knowing each card's URL.
- Sent once, never returned. The token travels once over HTTPS at registration. No API response, page, or error ever includes it afterwards — including to you. Lose it and the recovery path is to register a new card.
- Hashed manage keys. The revocation key is shown exactly once; only its SHA-256 hash is stored. Revoking deletes the registration and its ciphertext immediately.
Least privilege by default
- Cards work with no token at all — anonymous mode uses a shared, public-data-only server token.
- A fine-grained, read-only token is all that's ever needed. Registration probes the token and rejects ones that can't serve the required fields, tokens that can't see your full public repo list (they would silently undercount), and private counting with a token that isn't yours.
- All displayed statistics are public-only by construction — the queries themselves are pinned to public data, so even an over-privileged token can't leak private repository details onto a card.
Abuse resistance
- Per-IP rate limits on rendering and registration, plus a global budget for anonymous GitHub API usage.
- A per-user render lock prevents request stampedes from hammering GitHub.
- Dynamic endpoints (
/api/*,/c/*) are excluded from search indexing by bothrobots.txtandX-Robots-Tagresponse headers. - The application writes no request logs; errors render as themed SVGs without leaking internals.
Reporting a vulnerability
Please report suspected vulnerabilities privately via GitHub security advisories for this repository, or open an issue if the report is not sensitive. The full policy lives in SECURITY.md. Only the latest deployment is supported. No bug bounty is offered, and no security certifications are claimed — the source is open for your own review.