Pinion is a tool you point at proprietary source code and, on generate, one that executes
that code to capture its behavior. That deserves a plain statement of how it handles your data and
how to report a problem.
Please report privately — do not open a public issue.
Use GitHub private vulnerability reporting (Security → Report a vulnerability). If that is unavailable to you, email the maintainer via the address on the commits in this repository.
Please include the version (pinion --version), your OS and .NET SDK, the command you ran, and a
minimal reproduction if you have one. Do not include proprietary source in a report — a
redacted snippet or synthetic reproduction is always enough.
Expect an acknowledgement within a few days. This is a small project without a paid security team, so please allow reasonable time for a fix before public disclosure. Credit is given in the changelog unless you prefer otherwise.
The short version: by default, nothing. Pinion makes no network request unless you explicitly pass
an AI provider (--provider anthropic, openai, or azure-openai). None is the default and none is
ever selected for you. A key in the environment does not enable anything by itself: each key variable
is read only inside the branch its own provider selects, so a CI runner or shared machine with a key in
its environment is unaffected.
| Command | Network |
|---|---|
analyze, verify, accept, seam, ci, init-tests |
none |
generate (default, --provider deterministic) |
none |
prove |
none by Pinion; Stryker.NET may restore NuGet packages |
| `generate --provider anthropic | openai |
There is no telemetry, no analytics, no license activation call, and no update check. The deterministic path has no HTTP client in it at all. TRUST.md documents this per command against the actual code, and the source is public so you can verify rather than trust.
If you enable the AI provider, these apply:
- A secret scrubber strips keys, passwords, tokens, and connection-string credentials before anything is sent.
--no-send(and a.pinionnosendfile) marks files or namespaces whose source must never leave the machine. It is enforced at the outbound boundary — such code is never read into a payload at all, including under--dry-run.--dry-runprints the exact bytes that would be sent and makes no network call.--base-urlpoints the client at a local or self-hosted model instead.
generate runs the target code to record what it does. That is inherent to characterization
testing, and it is the sharpest edge in this tool. Mitigations:
- Methods tagged
io(may touch filesystem/DB/network) are skipped unless you pass--allow-side-effects. Methods taggedmoney/auth still run, but are called out up front so you review their snapshots before committing. --excludeand.pinionignoreremove methods from consideration entirely.- A per-method timeout (
--timeout, default 180s) kills hung or infinite-looping targets. - Captured golden masters are scrubbed before being written, because return values can contain real secrets or PII — review snapshots before committing them.
Run generate against a development checkout with test credentials, never production
configuration. Pinion cannot tell that a method named SendInvoice really sends invoices.
The licensing signing key is a private key and has never been committed; only the corresponding
public key ships in the binary, which can verify but not mint. .gitignore excludes
tools/pinion-signing-key.txt and *.license.
Pre-1.0: fixes land on main and in the next release. Please report against the latest version.