-
Notifications
You must be signed in to change notification settings - Fork 3
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.
Tip
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, profiles, credential storage |
| Daily use | Workflows, --set, -f, filters, scope |
| 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, 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 |
curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | shPlaces harness in ~/.local/bin. Override with HARNESS_INSTALL_DIR or the installer's --install-dir flag. Prebuilt binaries for every release are on the releases page.
| Platform | Architectures | Status |
|---|---|---|
| macOS | arm64, amd64 | Supported |
| Linux | amd64, arm64 | Supported |
| Windows | — | WSL only today |
Homebrew, apt, and yum packages - Coming Soon.
harness install cliChecks the GitHub releases API and replaces the running binary in place. Re-running the curl | sh installer also works.
rm ~/.local/bin/harness # binary
rm -rf ~/.harness # credentials + config (optional)There's nothing else on your machine.
harness version
harness version --format json # for scriptsharness <verb> <noun> [identifier] [flags]
Six verbs — list, get, create, update, delete, execute — plus push and pull 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 six 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 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 pipeline # nouns and guides for a moduleEvery command supports --help at every depth. Typos get "did you mean…?" suggestions.
A sub-operation on the same resource. Keeps the verb set closed:
harness list pr:mine # my open PRs across every repo
harness execute execution:abort <exec-id> # abort a running execution
harness execute pr:merge <repo>/<num> # merge a PR
harness get pipeline:summary <id> # condensed pipeline viewEverything after : is spec-defined, so --help on each variant lists its flags.
Latest release: **12 module spec files, 87 distinct nouns, 279 commands.
Run harness list noun on your install for the live number.
harness auth login # paste a PAT, saved to a named profileOAuth based login - Coming Soon.
Profiles.
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
harness auth setdefault prod # persist the default
harness --profile staging list pipeline # override per invocationResolved in this order — the first match wins:
| Priority | Source |
|---|---|
| 1 |
--profile flag |
| 2 |
HARNESS_API_KEY env var (plus HARNESS_ACCOUNT_ID) |
| 3 |
HARNESS_PROFILE env var |
| 4 | Default profile from ~/.harness/config
|
No — every 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 --set env=prod
# Watch
harness list execution --filter pipeline_id=deploy-checkout --limit 5
harness get execution_log <pipeline-id>/<execution-id> --follow
# 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 --set scope=project
# 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 24h
harness list audit_event --filter "action=execute,resource_type=pipeline"Warning
--all is convenient but chatty on large collections. Pipe through head or add --filter first.
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.
| Format | Default for | Notes |
|---|---|---|
table |
list |
Human-readable, terminal-width aware |
text |
get |
Key: value lines |
json |
— | Full array on list, object on get
|
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.yamlField names on list/get output are covered by our compatibility contract and change only on a major version. Fields we add are additive.
# bash
harness completion bash > /etc/bash_completion.d/harness
# zsh
harness completion zsh > "${fpath[1]}/_harness"
# fish
harness completion fish > ~/.config/fish/completions/harness.fishCompletion is live-API-backed where it makes sense — harness get pipeline <TAB> calls the API and lists real pipeline IDs, cached briefly on disk.
Everything under ~/.harness/:
| Path | Contents |
|---|---|
config |
Profiles and default scope |
completions-cache/ |
Cached IDs for live tab completion |
logs/ |
Recent debug logs when HARNESS_DEBUG=1
|
Override the whole 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 get project --ui # org-aware picker
harness get workspace --ui
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.
Warning
--ui requires a TTY. It will not run in CI, under a pipe, or with redirected output. Use --follow and --format jsonl there 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.
Not yet. Defaults follow common conventions:
| Key | Action |
|---|---|
Arrows or hjkl
|
Navigate |
/ |
Filter |
enter |
Drill in |
q or ctrl-c
|
Quit |
? |
Keybinding overlay |
In the past, most of the Harness Modules did not had any CLI. So the developer experience was fragmented. The old cli hc will be deprecated in the upcoming releases.
The new CLI is one binary that covers every module through the same grammar and the same auth.
Note
Legacy CLIs keep working through the beta and a deprecation window after GA. No same-day cutover.
| 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 the 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
- Stable, snapshot-tested output contracts
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 and it has the entire action surface as structured data. Ask it to prefer harness <verb> <noun> over raw REST.
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."
Tip
Give agents scoped tokens the same way you'd give a service account one.
Yes — Harness supports official Harness MCP.
An agent with a production token can do whatever that token permits — same as any script. Controls to reach for:
- Scoped PATs (project-scoped or role-scoped) instead of admin tokens
-
Confirmation prompts —
deleteand someexecute:*variants require--yeson the command line; instruct the agent never to pass it - The audit trail — catches 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), write a handler under modules/<module>/ and reference it from the spec. Full walkthrough in docs/docs/contributing/adding-a-command.md.
Yes, the Plugin SDK is available. The Artifact Registry (harness-har) already ships as a companion binary using the pattern we'll open to the community — external module, same grammar, discovered at runtime.
If 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
make build
./bin/harness list nounmake test runs unit tests. make e2e runs the integration suite against a Harness account — you'll need one and a PAT.
| Channel | Use for |
|---|---|
| Issues | Bugs, feature requests, "what does this flag do?" |
| Discussions | Design conversations, ideas |
We triage every issue. Response time in beta is usually one working day.
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
$HOME/.local/bin(orHARNESS_INSTALL_DIR). - Prints a hint to add that directory to your
PATHif it isn't already.
It doesn't touch anything outside $HOME/.local/bin, doesn't require root, and doesn't modify shell configs unless you pass --modify-shell.
Tip
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:
cosign verify-blob \
--certificate harness_linux_amd64.pem \
--signature harness_linux_amd64.sig \
--certificate-identity-regexp 'https://github.com/harness/cli/.github/workflows/release.yml@refs/tags/v.+' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
harness_linux_amd64Important
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/--follow instead.
Run harness auth status. Common causes:
- PAT 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> list account.
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.