Do not open a public issue.
Email mikael.muniz@mkmuniz.dev with:
- a description of the vulnerability and its impact
- steps to reproduce
- any proof-of-concept code, logs or screenshots
You will get an acknowledgement within 72 hours.
vedei detects credentials and personal data. Two classes of bug matter most, and both should be reported privately:
- Leaking a detected value. Any path where a detected secret or personal datum reaches somewhere it should not — a report, a log, telemetry, an LLM request. This is the worst failure this project can have.
- Failing to detect. A false negative in a validator that causes real sensitive data to pass through a redaction path.
A false positive is a normal bug — open a public issue for those.
- Findings in the default rule set inherited from betterleaks — report those upstream.
- Reports generated by automated scanners without a reproducible case.
Until v1.0, only the latest release receives fixes.
| Version | Supported |
|---|---|
| latest | ✅ |
| older | ❌ |
Stated here rather than discovered by a user.
Memory scales with input size. Scan copies the content it is given, so
peak use is roughly twice the input. A 1 GB file needs about 2 GB. Streaming
arrives with the CLI in M4; until then, do not point the library at
arbitrarily large input.
The upstream secret rules were built around English key names. Measured
on betterleaks v1.8.1, a real credential was found 100% of the time under an
English name but 57% under a Spanish one and 29% under a Portuguese one:
senha and segredo were never recognized. vedei translates key names and
scans again, reaching 100% in all three; the corpus in corpus/ pins it.
The upstream rules also report instructional placeholders such as
"your-password-here" at low confidence — in every language equally, so it is
noise, not a language bias. An earlier note here claimed Portuguese placeholders
were the problem; measured end to end, they are not.
124 transitive dependencies. Two direct ones, of which betterleaks
brings the rest, including cloud SDKs it uses for credential validation that
vedei does not enable. govulncheck runs on every push and weekly, in
.github/workflows/security.yml, alongside gosec, Trivy and the fuzzers.
Weekly matters as much as per-push: a new advisory against a dependency that did not change is the case a push-triggered scan never sees.
Run the same checks locally with make security and make fuzz.
A structurally valid document may still be fabricated. vedei validates check digits, never identity, and never will (ADR-002). A generated CPF in a test fixture is indistinguishable from a real one by arithmetic alone.
AWS access key IDs are detected; the secret access key is not. vedei owns one
rule the upstream corpus lacks: an access key id (AKIA…, ASIA…) is matched
structurally — a credential-bearing prefix and a 16-character base32 body. It is
reported High confidence and Unknown validity, because the shape proves it is
well-formed, not that it still works. The 40-character secret access key has no
structure to key on and is left to context-based rules, which is a known gap. The
account-id checksum an access key id also carries is not yet verified; doing so
would raise confidence and surface the account. Stripe, GitHub PAT and Slack
tokens are detected by the upstream corpus.
The daemon is a long-lived process holding a Unix socket. If you run
vedei daemon, note what it is and is not:
- The socket is created mode
0600. Where vedei creates its directory, that directory is0700; where the directory already existed, vedei refuses to bind if it is world-writable without the sticky bit, and otherwise leaves the mode alone — restricting a shared directory is not its call. - Unix-domain only. There is no TCP mode and there should not be one: everything crossing that socket is text that was just judged sensitive.
- Anyone who can open the socket can send text and read the redacted answer.
That is the same reach as running
vedeiyourself, which is why the mode and the directory check matter. - Requests are never logged. Only accept and handler failures are, because the text is the sensitive part.
- The daemon holds no state beyond the compiled rule set, and no value is
written to disk.
--idle-timeoutmakes it exit when unused. - A request is capped at 16 MB, so one client cannot decide how much memory the process holds.
- None of the above holds on Windows. vedei builds there, and Windows 10
1803+ supports Unix-domain sockets, but
os.Chmodon Windows only toggles the read-only attribute: the0600and0700modes restrict nobody, because Windows controls access with ACLs. The socket's privacy then rests on the default ACL of the user's profile directory — normally the user, Administrators and SYSTEM — which vedei does not verify. It is also untested on Windows. Until that changes, runvedei hookwithout the daemon on Windows (seehooks/README.md).
Findings crossing the socket cannot carry the raw value. Finding.Raw is
json:"-", so the process boundary enforces ADR-003 rather than trusting it.
There is a test that reads the raw bytes off the wire and fails if the value
appears.