Command reference
Four commands: scan, login, submit, logout. Only login and submit ever touch the network. scan makes zero network calls, no exceptions. Run with npx @redential/cli <command>, or redential <command> after a global install.
scan
Scans the local git history and prints the proof bundle. Nothing is uploaded.
redential scan [options]
Flags
| Flag | Default | Description |
|---|---|---|
| --repo <path> | . | Path to the git repository to scan. |
| --author <email> | (none) | Author email that is yours. Repeatable. Passing at least one enables non-interactive mode for identity selection. |
| --yes | false | Confirm “I am authorized to analyze this repository” non-interactively. |
| --json | false | Force JSON-only output, even on an interactive terminal (this is already the default when stdout is piped). |
Interactively (a real TTY, no --author/--yes), scanasks which of the repo's author emails are yours, then asks you to confirm you're authorized to analyze the repository. Both are required before a bundle is produced. --author alone never implies authorization.
Output
Prints the full JSON bundle first, byte for byte what submit would later send. When stdout is an interactive terminal (and --jsonwasn't passed), a human-readable "wrapped" summary follows underneath it, rendered entirely from the same bundle, no new data, no network:
{
"schema_version": "1.0.0",
"runner": "local",
"tool_version": "0.1.0",
"created_at": "2026-07-09T14:32:01.000Z",
"repo": { "host_type": "github", "age_days": 742, "repo_fingerprint": "a3f9…" },
"identity": { "author_identity_hashes": ["9c1e…"], "other_contributors_count": 3 },
"commits": { "user_total": 1847, "first_at": "2024-06-02T09:14:00Z", "last_at": "2026-07-08T21:05:00Z", "span_days": 767, "hour_histogram": [...], "weekday_histogram": [...] },
"signed": { "count": 831, "ratio": 0.45 },
"languages": [ { "extension": ".ts", "share": 0.62 }, { "extension": ".sql", "share": 0.14 } ],
"categories": [ { "name": "backend", "commit_count": 902, "churn_share": 0.51 } ],
"detected_skills": [ { "slug": "payments/stripe", "commit_count": 12, "first_seen": "2024-09-01T10:00:00Z", "last_seen": "2025-11-20T18:30:00Z" } ],
"ownership": { "user_commit_ratio": 0.78 },
"integrity": { "merkle_root": "7be2…", "algorithm": "sha256" },
"attestation": { "authorized_confirmation": true, "confirmed_at": "2026-07-09T14:32:01.000Z" }
}
────────────────────────────────────────────────────────────
╔════════════════════════════════════════════════════════════╗
║ YOUR PRIVATE REPO, WRAPPED ║
╚════════════════════════════════════════════════════════════╝
2 years, 1,847 commits
COMMITS BY HOUR (UTC)
0 6 12 18
▁····▁▁▃▅█▇▄▃▂▂▁▁▁▁▁····
COMMITS BY WEEKDAY
Sun ██░░░░░░░░░░░░░░░░░░ 5
Mon ███████████████████░ 40
TOP LANGUAGES
.ts ████████████████████ 62%
.sql ████░░░░░░░░░░░░░░░░ 14%
SKILLS DETECTED
payments/stripe 12 commits
Ownership 78% of this repo's commits are yours
Signed commits 45% of your commits are cryptographically signed
Nothing left your machine. Verify: github.com/Redential/redential-cliEvery field is documented in Trust & privacy. Pipe it (redential scan | jq) and you get only the raw JSON: the wrapped summary is a terminal-only convenience, never a second source of data.
Warnings (non-blocking)
If the repo's remote looks like a known public host (github.com, gitlab.com, bitbucket.org), scanprints a warning to stderr suggesting the GitHub App instead. It never blocks or refuses to scan, because "known host" isn't the same as "publicly accessible" and scan has zero network access to tell the difference. The CLI's primary use case is a private employer repo hosted on github.com.
login
Authenticates via device flow (RFC 8628) and stores a session token locally. No flags.
redential login
Prints a verification URL and a short code, and makes a best-effort attempt to open the URL in your default browser. Auto-open is never load-bearing: on a headless box, over SSH, or if no browser is installed, it silently fails and login proceeds exactly as if auto-open didn't exist; the printed URL and code are always the fallback. Approve the code in the browser, and login polls until it receives an access token, then stores it at ~/.config/redential/credentials.json (mode 0600).
REDENTIAL_SITE_URL, submit refuses and asks you to log in again rather than silently sending a token to a different host. See Troubleshooting.submit
Scans, shows you the bundle, and uploads it after you confirm. Requires a prior redential login.
redential submit [options]
Flags
| Flag | Default | Description |
|---|---|---|
| --repo <path> | . | Path to the git repository to scan, same as scan. |
| --author <email> | (none) | Author email that is yours. Repeatable. Enables non-interactive identity selection, same as scan. |
| --yes | false | Confirm “I am authorized to analyze this repository” non-interactively, same meaning as scan --yes. |
| --confirm-upload | false | Confirm the upload itself non-interactively. Separate from --yes on purpose: consenting to be scanned and consenting to upload are different decisions. |
redential submit --repo . --author you@company.com --yes --confirm-upload
What happens, in order
| Step | Behavior |
|---|---|
| 1. Build the bundle | Exact same code path as scan, same author selection, same authorization prompt. |
| 2. Print it | Byte for byte what step 4 sends, not a re-serialization, the literal printed string. |
| 3. Ask to upload | “Upload this bundle?”, a separate confirmation from step 1's authorization attestation. |
| 4. Visibility gate | An anonymous HEAD request straight to the repo's remote URL (never to Redential's servers). A confirmed public remote (2xx/3xx) blocks the upload outright. |
| 5. Upload | POST to Redential with the bearer token from login. On success, only the bundle id is printed, never the full response. |
The visibility gate is submit-only. It's a real network check, stronger than scan's local heuristic. Anything inconclusive (private/gated, network error, timeout) doesn't block; it falls back to the same warning scan would have shown, and proceeds.
logout
Deletes the locally stored session token. No flags.
redential logout
Removes ~/.config/redential/credentials.json only. It never touches the device salt (a separate file used to make repo/author fingerprints non-reversible), which is device-local and unrelated to your session.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success. |
| 1 | Any handled failure: a scan/auth/submit/network error, a denied or expired device-flow login, or EOF on an interactive prompt (see Troubleshooting). |
Every command-level error is one of four typed errors (scan, auth, submit, or network), and every one of them sets a non-zero exit code rather than hanging or silently succeeding. Network-error messages are built only from the request's host and HTTP status, never from headers or body, so a failed request can never echo your bearer token or bundle content into a printed error.
Something not matching what you see locally? Open an issue.
← CLI overview