Validation and Privacy
Picket separates offline structural validation from live provider verification.
Defaults
Section titled “Defaults”- No telemetry is collected.
- Live network verification is disabled by default.
- Plain
picket scanand compatibility commands do not contact provider APIs. picket verify --offlineand native scan validation use local checks only.picket scan --verify,picket verify --live, andpicket analyze --liveare explicit opt-in provider calls. The initial live provider is GitHub token validation.picket revokecommands are separate, explicit, irreversible provider mutations and never run as part of scanning, verification, or analysis.
Offline Validation
Section titled “Offline Validation”Offline validation never sends secrets, hashes, paths, or metadata to a network endpoint. Current validators inspect local finding data and return one of these report values:
unknown: no validator could prove a stronger state.structurally-valid: the secret has a valid local shape for the detected rule.test-credential: the secret appears to be a dummy, example, placeholder, repeated-character, or repeated-pattern credential.invalid: the secret fails a local structural check.active,inactive,skipped, anderror: reserved for opt-in live verification results.
Use --results with native scan, verify, and analyze commands to keep specific validation states. --only-verified is shorthand for keeping structurally-valid offline findings and active live-verification findings; it does not keep inactive, skipped, error, invalid, test-credential, or unknown findings.
Current offline coverage includes:
- Anthropic OAuth access and refresh token prefix, length, and alphabet checks.
- AWS access key ID shape and alphabet checks.
- Native AWS access key pair checks that require a valid access key ID and a 40-character secret access key alphabet.
- Azure Storage connection-string structure, account name, endpoint suffix, and 512-bit Base64 account-key checks.
- Claude Code session URL host, path, and identifier checks.
- Codex OAuth access-token JWT shape and refresh-token structure checks.
- Database connection URL structure, known database schemes, username, and embedded password checks.
- Docker registry basic credential checks after bounded Base64 decoding from an
authsobject. - GCP API key prefix, length, and alphabet checks.
- GCP service account key JSON structure, project ID, private key ID, private-key envelope, service account email, and token URI checks.
- GitHub classic, OAuth, refresh, app, stateless app installation, and fine-grained token shape checks.
- Groq, OpenAI, and xAI API key prefix, length, and alphabet checks.
- private JWK parameter checks within complete RSA, EC, or OKP key objects.
- JWT and Base64-wrapped JWT segment, header, payload, algorithm, and signature-shape checks.
- Kubernetes Secret values selected from bounded YAML structure without alias expansion.
- credential-bearing MCP server environment values selected from
mcpServers.<server>.env, excluding environment-variable references. - npm token and decoded basic credential checks from bounded npmrc assignments, excluding interpolation.
- private-key envelope checks.
- Sourcegraph
sgp_access token shape checks. - common test, dummy, fake, placeholder, repeated-character, and repeated-pattern suppression signals.
Native rule metadata can list supported validation templates with stable identifiers such as offline:gcp-api-key or live:github-rest-user-v1. These identifiers document available capability and appear in rich native rule catalogs; they do not enable live provider calls unless the user selects an explicit live-verification command or flag.
Live Verification Model
Section titled “Live Verification Model”Live provider calls are opt-in behavior for picket scan --verify, picket verify --live, and picket analyze --live. The reusable verification layer defines the provider contract and safety envelope that provider validators must use:
ISecretLiveValidatordescribes one provider validator, its endpoint, provider ID, version, and support check.SecretLiveVerifierchooses the first supporting validator, evaluates the endpoint guard before the validator runs, honors cancellation, and returnsskippedwhen no validator supports a finding.SecretLiveVerifierOptionslimits live provider concurrency to four total provider requests and one request per provider by default, spaces requests to the same provider by one second by default, and can also enforce a global request interval.SecretValidationCachestores live results with rule/provider/config fingerprint invalidation, expiration, authenticated entries, owner-only file permissions on Unix-like systems and Windows, and atomic writes.SecretValidationCacheKeyis built from provider, validator version, rule ID, endpoint, and a SHA-256 secret hash. It rejects raw secret material where a hash is required.- Cache files store fingerprints, report states, expiration, non-secret reasons, and non-secret analysis metadata such as provider identity, scopes, resources, and evidence. They do not store raw secrets, raw matches, or endpoint query strings.
- Transient provider failures use the configured in-process error-cache duration to avoid repeating the same failed request during one verifier run. They are never written to the persistent cache.
- Live results include non-secret audit evidence for the provider, normalized endpoint without query or fragment data, endpoint policy decision, whether the provider was contacted for the current verification call, and whether the result came from the request or persistent cache.
- Findings already marked
invalidortest-credentialby offline validation are not sent to live providers.
The first provider validator is GitHub:
- supported compatibility rule IDs:
github-pat,github-oauth,github-refresh-token,github-app-token, andgithub-fine-grained-pat, - supported native rule IDs:
picket-github-personal-access-token,picket-github-oauth-token,picket-github-refresh-token,picket-github-app-token, andpicket-github-fine-grained-personal-access-token, - default endpoint:
https://api.github.com/user, - endpoint override:
--github-api-endpoint <absolute-uri>, intended for GitHub Enterprise and recorded/local test hosts, - proxy override:
--github-api-proxy <https-uri>, intended for enterprise and CI egress environments and rejected when the URI uses HTTP or includes user info, query, or fragment data, - TLS mode override:
--live-tls-mode system|tls12-plus, wheresystemuses platform defaults andtls12-plusrestricts provider requests to TLS 1.2 or TLS 1.3; certificate validation is not bypassed, - rate-limit overrides:
--live-provider-rate-limit-ms <n>changes the same-provider minimum interval and--live-rate-limit-ms <n>changes the global minimum interval;0disables the selected interval, - default endpoint policy: HTTPS required and non-public addresses blocked,
- explicit non-public endpoint escape hatch:
--allow-non-public-endpoints, - transient
408,500,502,503, and504responses and transport timeouts/failures are retried once by default, 200 OKmaps toactiveand can add non-secret user login, scope, reachable-resource, and evidence metadata forpicket analyze --live,401 Unauthorizedmaps toinactive,- automatic HTTP redirects are disabled; redirect responses map to
error, 403 Forbidden,429 Too Many Requests, other unexpected statuses, request failures, and endpoint-policy failures map toerror.- HTTP responses include non-secret
httpStatusevidence for audit and troubleshooting.
Before additional providers can be enabled in the CLI, each validator also requires a threat-model entry with:
- data sent,
- endpoint contacted,
- auth required,
- rate limits,
- expected success and failure codes,
- retry policy,
- cache key,
- revocation support and safe command-template output,
- known provider side effects,
- SSRF and redirect protections.
Provider requests must use Picket.Security endpoint checks to block loopback, private, link-local, metadata-service, reserved, and non-public redirect targets by default. Redirects are disabled unless a provider implements explicit target re-checking before following. Responses must be size-limited and redacted before diagnostics.
Explicit Revocation
Section titled “Explicit Revocation”picket revoke github submits exposed GitHub credentials to GitHub’s credential revocation API. The workflow is intentionally separate from live verification and analysis:
picket revoke github --credential-env EXPOSED_GITHUB_TOKEN --confirm-revocationRepeat --credential-env to submit more than one credential. The named variables must already exist in the process environment; Picket does not accept raw credential values as command arguments. The command requires --confirm-revocation because GitHub cannot reactivate a revoked credential.
The GitHub workflow has these boundaries:
- accepted families:
ghp_,github_pat_,gho_,ghu_,ghs_, andghr_, - default endpoint:
https://api.github.com/credentials/revoke, - request authentication: none; GitHub rejects authenticated requests to this endpoint,
- request limit: 1,000 credentials and one request per command invocation,
- provider rate limit: 60 unauthenticated requests per hour,
- endpoint policy: HTTPS, preflight and connect-time address checks, non-public addresses blocked by default, no user info/query/fragment in endpoint overrides, and no automatic redirects,
- proxy policy: optional HTTPS proxy with no user info/query/fragment,
- retry policy: none, because replaying an irreversible request after a timeout or transport failure can hide whether the first request succeeded,
- response handling:
202is accepted, provider validation and client errors are rejected, redirects are blocked, and transport failures, timeouts, unexpected success responses, and server errors are indeterminate, - output: fixed non-secret reasons and credential counts only; request and response bodies are not logged, cached, or included in diagnostics.
An accepted result exits 0, a rejected or locally blocked result exits 1, and an indeterminate provider outcome exits 2. Invalid command input also exits nonzero without contacting GitHub. The command reports acceptance rather than claiming completed revocation because GitHub’s documented success response is 202 Accepted. See the GitHub credential revocation API for the provider contract.
Reporting
Section titled “Reporting”Native report writers expose validation state in Picket JSON, JSONL, SARIF, CSV, JUnit, HTML, TOON, and GitLab code-quality outputs where the format supports it. Gitleaks-compatible report writers preserve the compatibility schema and do not add Picket-native validation fields.
Native analysis reports can include provider-specific revocation availability, command templates, and guidance. Current offline analysis guidance covers AWS, Azure Storage, database connection URLs, GCP, GitHub, GitLab token families, and Sourcegraph access tokens; live provider verification remains opt-in and GitHub-focused until additional provider validators have endpoint threat models and tests. Revocation is never automatic during scan, verification, or analysis. Command templates must be derived from non-secret identifiers and must never include raw secret values. Direct revocation uses provider-specific typed clients and never executes report command-template text as a shell command.
Secrets must be redacted before logs, action annotations, summaries, diagnostics, and crash data. The scanner and TUI outer exception boundaries report only the unexpected exception type and fixed explanatory text; exception messages and stack traces are withheld because they can contain scanned source or credential-bearing provider data. Expected operational failures retain their specific non-secret diagnostics. Secret hashes are intended for deduplication and triage, not as proof that a credential is safe to disclose.