-
Notifications
You must be signed in to change notification settings - Fork 8
FAQs
Questions we get most often, answered by the people who work on the CLI.
Don't see your question? Open a discussion or an issue. We triage every one.
In a hurry? Install, log in, and see everything you can do:
curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | sh harness auth login harness list noun --matrix
| Section | What's inside |
|---|---|
| Getting started | Install, upgrade, uninstall, version |
| Grammar and discovery | Verbs, nouns, --help, list noun --matrix
|
| Authentication and profiles | Login, SSO, PAT/SAT, profiles, credential storage |
| Daily use | Workflows, --set, -f, filters, scope |
| Harness Code | PRs, reviews, merge, checks, review insights |
| Output, scripting, and shell integration | Formats, exit codes, completion, NO_COLOR
|
Interactive TUI (--ui) |
Browsers, pickers, live log viewer |
| Comparisons | vs. old CLIs, REST, Terraform, curl
|
| AI agents | Claude Code, Cursor, MCP, RBAC, blast radius |
| Extending and contributing | Specs, plugins, local dev, issues |
| Trust and security |
curl | sh, cosign, telemetry, reporting |
| Troubleshooting | Common errors and how to unstick |
macOS / Linux
curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | shWindows (PowerShell)
irm https://raw.githubusercontent.com/harness/cli/main/install.ps1 | iexPlaces harness in ~/.local/bin on Unix or %LOCALAPPDATA%\Programs\harness on Windows. Override with --install-dir / -InstallDir. Prebuilt binaries for every release are on the releases page. The default installer also registers the har (Artifact Registry) plugin from the same bundle.
See docs/manual-install.md if you need to install from a downloaded archive or behind a proxy.
| Platform | Architectures | Status |
|---|---|---|
| macOS | arm64, amd64 | Supported |
| Linux | amd64, arm64 | Supported |
| Windows | amd64, arm64 | Supported (native binary + PowerShell installer) |
Homebrew, apt, and yum packages — coming soon.
harness install cli # upgrade core + installed modules to latest
harness install cli --version v3.2.1 # pin a specific version
harness install cli --core-only # upgrade harness only, skip module updates
harness install module har # upgrade a single module/pluginRe-running the curl | sh or irm | iex installer also works.
rm ~/.local/bin/harness # binary (Unix)
rm -rf ~/.harness # credentials + config (optional)On Windows, remove the install directory you chose (default %LOCALAPPDATA%\Programs\harness) and delete %USERPROFILE%\.harness if you want to clear config.
harness version
harness version --format json # for scriptsharness <verb> <noun> [identifier] [flags]
Core verbs — list, get, create, update, delete, execute — plus push, pull, and configure for artifacts. Self-management commands (auth, install, version, debug) sit outside the grammar because they act on the CLI itself, not on a Harness resource.
To keep the surface predictable. Every resource plugs into the same verbs — no deploy-with-canary, no pipeline-v2. When a resource needs a focused action, we add a qualified noun (execution:abort, pr:merge) instead of inventing a new verb.
harness list noun # every noun the CLI knows
harness get noun pipeline # aliases, fields, commands for one noun
harness list module # loaded modules
harness get module code # nouns and guides for a module
harness list noun --matrix # full noun × verb matrixEvery command supports --help at every depth. Typos get "did you mean…?" suggestions.
For the full command catalog, see the Command Reference wiki page (or docs/Command-Reference.md in the repo).
A sub-operation on the same resource. Keeps the verb set closed:
harness list pr:mine # PRs you authored, across every repo
harness list pr:review_pending # PRs awaiting your review, across every repo
harness execute pr:merge <repo>/<num> # merge a PR
harness execute pr:review <repo>/<num> # approve or request changes
harness execute execution:abort <exec-id> # abort a running execution
harness get pipeline:summary <id> # condensed pipeline view
harness get pr:insight <repo>/<num> # AI risk summary for a PREverything after : is spec-defined, so --help on each variant lists its flags.
10 public modules, 276 commands, 86 nouns (as of CLI 3.x). Three additional modules (kg, aievals, fme) ship in the binary but are gated to harness.io accounts.
| Module | Commands | What it covers |
|---|---|---|
core |
22 | Auth, install, discovery, debug |
platform |
48 | Orgs, projects, connectors, secrets, delegates, agents |
pipeline |
45 | Pipelines, executions, logs, triggers, templates, approvals |
cd |
20 | Services, environments, infrastructure |
iacm |
13 | Terraform workspaces, Ansible |
har |
47 | Artifact Registry (plugin binary) |
code |
41 | Harness Code — repos, PRs, reviews, checks |
gitops |
27 | GitOps agents, apps, clusters, repos |
governance |
11 | OPA policies and policy sets |
audit |
2 | Audit trail |
Run harness list noun --matrix on your install for the live number — it always reflects what's loaded in your binary and profile.
Interactive (PAT/SAT wizard)
harness auth loginNon-interactive (CI, scripting)
harness auth login \
--api-url app.harness.io \
--api-token <pat-or-sat> \
--org <org> \
--project <project> \
--overwriteOr skip profiles entirely and set HARNESS_API_KEY + HARNESS_ACCOUNT (see docs/auth.md).
Browser SSO
harness auth login --ssoOpens a browser OAuth flow. Tokens are stored in the OS keychain where available. Refresh with harness auth sso_refresh; check expiry with harness auth sso_status.
Both PAT (pat.…) and SAT (sat.…) tokens are supported. SATs may need manual scope after login:
harness auth setscope --org myorg --project myprojectProfiles.
harness auth login --profile prod
harness auth login --profile staging
harness auth setscope --profile prod --org acme --project checkout
harness auth profiles # list them
harness auth status # active profile + validation
export HARNESS_PROFILE=staging # default for the shell session
harness --profile staging list pipeline # override per invocationThere is no auth setdefault command — use HARNESS_PROFILE or --profile per invocation.
Resolved in this order — the first match wins:
| Priority | Source |
|---|---|
| 1 |
--profile flag |
| 2 |
HARNESS_API_KEY env var (plus HARNESS_ACCOUNT, optional org/project) |
| 3 |
HARNESS_PROFILE env var |
| 4 | CI runner env vars (auto-detected) |
| 5 |
default profile from ~/.harness/config.yaml
|
When --profile is set, auth env vars are ignored entirely — no blending between modes.
No — every resource command hits the Harness API. You can install the CLI and run harness list noun without an account to browse the grammar; nothing else works offline.
Deploy a service, watch it, abort if it goes sideways:
# What's out there
harness list pipeline
harness get pipeline deploy-checkout
# Run it
harness execute pipeline deploy-checkout --set image_tag=v2.31.4
# Watch
harness list execution --filter pipeline_id=deploy-checkout --limit 5
harness get execution_log <pipeline-id>/<execution-id> --follow
# Or open the live log viewer (TTY required)
harness get execution_log <pipeline-id>/<execution-id> --ui
# Abort if needed
harness execute execution:abort <execution-id>Two ways, and you can mix them:
# Inline
harness create secret my-token --set value=abc123
# From a YAML file (or stdin)
harness create secret -f secret.yaml
cat secret.yaml | harness create secret -f -
# From a file, with an override
harness update pipeline deploy-checkout -f pipeline.yaml --set variables.region=us-east-2harness list execution --limit 50
harness list execution --limit 50 --offset 100
harness list execution --all # walk every page
harness list execution --count # total only, no rows
harness list audit_event --since 24hNote:
--allis convenient but chatty on large collections. Add--filteror--limitfirst when exploring.
harness --org acme list pipeline
harness --project checkout list pipeline
harness --level org list connector # some nouns exist at multiple levelsFlags override the profile's default scope for that invocation only.
Yes — that's what the code module is for. A typical flow:
# See what's on your plate
harness list pr:mine --state open
harness list pr:review_pending
# Open and review
harness create pr my-repo --set title="fix: retry" source_branch=fix/retry
harness get pr my-repo/42
harness list pr_check my-repo/42 # checks tied to pipeline executions
harness execute pr:review my-repo/42 --decision approve
harness create pr_comment my-repo/42 -f review.md
# Merge
harness execute pr:merge my-repo/42 --method squash --delete-branchCompound IDs use <repo>/<pr_number> — not separate --pr flags.
Harness Code AI review surfaces risk summaries, suggested reviewers, and success criteria through the same CLI grammar:
harness get pr:insight <repo>/<pr>
harness get pr:review_group <repo>/<pr>
harness list pr_suggested_reviewer <repo>/<pr>
harness list pr_success_criterion <repo>/<pr>Pass an email, Harness UID, or numeric principal ID — the CLI resolves it automatically. You can also look up principals with harness list code_principal --search <name>.
| Format | Default for | Notes |
|---|---|---|
table |
list |
Human-readable, terminal-width aware |
text |
get |
Key: value lines |
json |
— | Full API response (envelope included) |
jsonl |
— | One record per line — best for streaming and agents |
yaml |
get (some) |
Round-trippable with -f
|
csv, tsv
|
— | For spreadsheets and Unix pipelines |
markdown |
— | For dropping into docs, issues, or Slack |
-o is a short alias for --format.
harness list pipeline --format json | jq '.[] | .identifier'
harness list execution --format jsonl | head -100
harness get pipeline my-pipe --yaml > pipe.yamlOn list, table/csv/tsv show projected columns only. On any verb, --format json returns the raw API envelope — use that when you need fields not shown in the table.
Field names on list/get output are covered by our compatibility contract and change only on a major version. Fields we add are additive.
Zsh (recommended — live in shell)
source <(harness completion zsh) # add to ~/.zshrcBash
source <(harness completion bash) # add to ~/.bashrcFish
harness completion fish > ~/.config/fish/completions/harness.fishCompletion is live-API-backed where it makes sense — harness list pr <repo><TAB> calls the API and lists real PR numbers. Code commands use contextual completion sequences (repo → PR → comment).
Everything under ~/.harness/:
| Path | Contents |
|---|---|
config.yaml |
Profile metadata (no tokens) |
credentials |
Tokens only |
completions-cache/ |
Cached IDs for live tab completion |
bin/ |
Installed plugin binaries (e.g. harness-har) |
update-check.json |
Background update-check cache |
Override the config location with HARNESS_CONFIG_HOME.
Opens a Bubble Tea TUI for browsing, picking, or watching — a middle ground between list output and the web UI.
harness list pipeline --ui # paged, searchable browser
harness list execution --ui
harness list pr:mine --ui
harness get project --ui # org-aware picker
harness get artifact_version --ui
# Live log viewer with a step graph
harness get execution_log <pipeline-id>/<execution-id> --uiEvery paged list command gets --ui for free — the flag is auto-wired from the spec, not hand-added per command.
--uirequires a TTY. It will not run in CI, under a pipe, or with redirected output. Use--followand--format jsonlthere instead.
Other restrictions:
- Mutually exclusive with
--format,--out, and shell redirection. - On the log viewer, don't combine with
--stage/--step— use the<pipeline-id>/<execution-id>form and navigate inside the TUI.
For searching log output in scripts, redirect plain-text logs and use grep/rg/less:
harness get execution_log <id> --follow | grep -i errorNot yet. Defaults follow common conventions:
| Key | Action |
|---|---|
Arrows or hjkl
|
Navigate |
/ |
Filter (list browser) |
enter |
Drill in |
q or ctrl-c
|
Quit |
? |
Keybinding overlay |
The live log viewer supports step selection, tab switching (logs/details/inputs/outputs), refresh, and save-to-file — see harness get execution_log --help.
Most Harness modules never had a first-class CLI — the developer experience was fragmented. The legacy hc CLI is being deprecated in favor of this unified binary.
The new CLI is one grammar that covers every module through the same auth, discovery, and output conventions. Legacy tools keep working through a deprecation window — no same-day cutover.
The code module covers the core repo/PR loop (create, list, comment, review, merge, checks) with Harness-specific advantages: cross-repo queues (pr:mine, pr:review_pending), review insights, and PR checks that carry pipeline execution IDs natively. See docs/harness-cli-positioning.md for a detailed comparison.
| Use case | Reach for |
|---|---|
| Interactive work, scripting, CI glue | CLI — shorter, consistent auth and output |
| Building a service that talks to Harness | REST API or language SDKs — the CLI isn't designed to be embedded |
Different jobs.
| Tool | Best for |
|---|---|
| Terraform provider | Declarative infrastructure — state files, plan/apply, drift detection |
| Harness CLI | Imperative work — one-shot commands, exploration, incident response, ad-hoc CI steps |
Most teams use both.
You can. Things the CLI does that curl doesn't, unless you rebuild them:
- One auth flow across every Harness endpoint, including SSO refresh
- Live tab completion of real resource IDs
- Consistent
--format, filtering, and paging on every list endpoint - Interactive TUI for browsing and live log viewing
- Self-describing grammar (
list noun --matrix) for humans and agents
For a one-off request, curl is fine. For anything you'd re-run, the CLI ends up shorter.
Yes — this is one of the two audiences we designed for. Point the agent at:
harness list noun --matrix --format json
harness get module code --format json
harness get noun pr --format json… and it has the entire action surface as structured data. Ask it to prefer harness <verb> <noun> over raw REST. The Command Reference and cheat sheet section are written for agent consumption.
The CLI also detects and reports the coding agent in telemetry (Claude Code, Cursor, Codex, Cline, and others) so operators know how the CLI is being driven.
The CLI doesn't enforce anything — the Harness API does. Every request goes through the same auth, RBAC, and audit path as the web UI. An agent using the CLI is a client with a token; whatever that token can do, the agent can do. No side channel, no "AI mode."
Give agents scoped tokens the same way you'd give a service account one — project-scoped PATs or SATs, not admin tokens.
Yes, for Cursor and compatible hosts — the official Harness Cursor plugin ships consolidated MCP tools (harness_list, harness_get, harness_create, etc.) that cover 160+ resource types.
A native CLI MCP server (harness mcp serve) is on the roadmap but not shipped yet. Until then, use the plugin MCP or point agents at harness list noun --matrix + --format json.
An agent with a production token can do whatever that token permits — same as any script. Controls to reach for:
- Scoped PATs/SATs (project-scoped or role-scoped) instead of admin tokens
-
Confirmation prompts —
deleteand someexecutevariants require explicit confirmation; instruct the agent never to bypass them -
The audit trail —
harness list audit_eventcatches everything after the fact
github.com/harness/cli. Apache 2.0. All development on main, in the open.
For most nouns, add or edit a spec file under pkg/spec/ — declarative YAML that describes the verb, noun, HTTP endpoint, flags, and output shape. No Go code needed for the common case.
For commands with custom logic (artifact push/pull, the log viewer, PR merge body builders), write a handler under modules/<module>/ and reference it from the spec. Full walkthrough in AGENTS.md.
Yes. The Artifact Registry (har) already ships as a companion binary — same grammar, separate go.mod, installed via harness install plugin har. See docs/plugins.md for the plugin packaging model.
harness install plugin har # by name
harness install plugin https://example.com/foo.tar.gz # from a tarball URL
harness install plugin ./foo.tar.gz # from a local tarball
harness list plugin # what's installedIf you have a use case, open a discussion so we know what you need before the SDK freezes.
git clone https://github.com/harness/cli
cd cli
task build # requires go-task: brew install go-task
cp bin/harness ~/.local/bin/harness # active binary path
harness list nountask build:main skips the HAR plugin for faster iteration when you're not touching artifact code. go test ./... runs unit tests.
| Channel | Use for |
|---|---|
| Issues | Bugs, feature requests, "what does this flag do?" |
| Discussions | Design conversations, ideas |
We triage every issue.
The installer script at install.sh. It:
- Detects your OS/arch.
- Downloads the matching binary and checksum from GitHub releases.
- Verifies the checksum. If
cosignis on your PATH, verifies the signature too. - Moves the binary into the install directory.
- Optionally registers the
harplugin and shell completions.
It doesn't touch anything outside the install directory, doesn't require root, and doesn't modify shell configs unless you pass --modify-shell.
Read it before you run it:
curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | less
Yes. Every release binary is signed with keyless Sigstore. See BUILD.md for verification commands.
Report security issues to security@harness.io, not the public tracker.
You're running in an environment without a TTY on stdin or stdout (CI, a pipe, a headless container). Drop --ui and use --format jsonl / --follow instead.
Run harness auth status. Common causes:
- PAT/SAT expired or was rotated → re-run
harness auth login. -
HARNESS_API_KEYset to a stale value →unset HARNESS_API_KEYif you meant to use a profile. - Wrong account →
harness --profile <name> auth status. - SSO token expired →
harness auth sso_refreshor re-runharness auth login --sso.
Service account tokens are often scoped to specific resources. Log in with the SAT, then set scope manually:
harness auth login --api-token sat.xxx --overwrite
harness auth setscope --org myorg --project myprojectOr use --no-validate during login if validation fails due to limited SA permissions, then verify with harness auth status.
Almost always a scope mismatch. Check harness auth status for the active org/project, and try adding --org and --project explicitly. Some resources live at account or org level and won't appear under a project scope.
Run harness version and compare to releases. Some modules (kg, aievals, fme) are hidden unless your profile is on a harness.io account. Run harness list module to see what's loaded for you.