Report privately through GitHub's Report a vulnerability form, which opens a draft advisory only the maintainers can see. Please do not open a public issue for anything exploitable.
Include what you need to make the problem reproducible: the version
(surface --version), your platform, and the smallest set of steps that shows
it. If you have a patch, attach it to the advisory rather than opening a pull
request, so the fix and the disclosure land together.
Expect an acknowledgement within a few working days. This is a small project
maintained during working hours, not a staffed security team — if the issue is
serious and you have heard nothing in a week, escalate to
security@holisticai.com.
surface runs unprivileged on your own machine and reads files that are already there. The things most worth reporting:
- Anything that transmits data off the machine. The only outbound request is
the model price table, and
--offlinemust suppress it. A request to anywhere else, under any setting, is a bug in the strongest sense. - Anything that leaks message content, URLs, paths, query strings or page
titles into the
--jsonpayload, the on-disk ledger, or the dashboard. Transcripts are parsed for token counts and model names only; browser history is filtered to known AI domains inside SQLite. There are tests for both, and a way past them is a vulnerability. - Writes outside the state directory, privilege escalation, or any prompt for elevation. surface never elevates.
- Installer integrity.
install.shandinstall.ps1are the primary install path and are piped straight into a shell. Anything that lets a download be substituted, a checksum check be skipped, or a path be written that the script did not intend belongs here. - Parser crashes on hostile input. A malformed transcript or history database should degrade that section, not take down the scan or read out of bounds.
- Findings that require an attacker who already controls your account. Anyone
who can write to your transcript files or your
PATHhas more direct options than surface. - The absence of a signature on
SHA256SUMSitself. It is served from the same release as the archives, so it proves the download is intact rather than that we produced it. Authenticity comes from the build provenance attestation — see below. - Cost or token inaccuracy. Prices are API list rates from a public table and unpriced models are reported as such. Wrong numbers are bugs; file them as issues.
- Reports generated by a scanner with no demonstrated impact.
Every release archive carries a Sigstore build provenance attestation, tying it to this repository, this workflow and the commit it was built from:
gh attestation verify surface-v0.1.0-aarch64-apple-darwin.tar.gz \
--repo holistic-ai/surfaceThat is a stronger check than the checksum, because it cannot be satisfied by anyone who merely controls the download. The installers verify the checksum, which catches corruption and a substituted file; the attestation is what catches a substituted release.
Pre-1.0, only the latest release gets fixes. There are no maintenance branches — upgrade to the newest version, and pin an exact one if you script against surface.