Skip to content
Mohit Suman edited this page Jul 15, 2026 · 1 revision

Harness CLI — FAQ

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

Contents

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

Getting started

How do I install it?

curl -fsSL https://raw.githubusercontent.com/harness/cli/main/install.sh | sh

Places 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.

Which platforms are supported?

Platform Architectures Status
macOS arm64, amd64 Supported
Linux amd64, arm64 Supported
Windows WSL only today

Homebrew, apt, and yum packages - Coming Soon.

How do I upgrade?

harness install cli

Checks the GitHub releases API and replaces the running binary in place. Re-running the curl | sh installer also works.

How do I uninstall?

rm ~/.local/bin/harness    # binary
rm -rf ~/.harness          # credentials + config (optional)

There's nothing else on your machine.

What version am I running?

harness version
harness version --format json   # for scripts

↑ back to top


Grammar and discovery

What's the command shape?

harness <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.

Why only six verbs?

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.

How do I find the command for X?

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 module

Every command supports --help at every depth. Typos get "did you mean…?" suggestions.

What's a "qualified noun" like pr:merge or execution:abort?

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 view

Everything after : is spec-defined, so --help on each variant lists its flags.

How many commands and modules are there today?

Latest release: **12 module spec files, 87 distinct nouns, 279 commands.

Run harness list noun on your install for the live number.

↑ back to top


Authentication and profiles

How do I log in?

harness auth login       # paste a PAT, saved to a named profile

OAuth based login - Coming Soon.

How do I switch between accounts or environments?

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 invocation

Which profile does the CLI pick?

Resolved 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

Can I use the CLI without a Harness account?

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.

↑ back to top


Daily use

Show me a real workflow

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>

How do I pass structured input?

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-2

How do I filter and paginate a list?

harness 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.

How do I change scope for one command?

harness --org acme list pipeline
harness --project checkout list pipeline
harness --level org list connector    # some nouns exist at multiple levels

Flags override the profile's default scope for that invocation only.

↑ back to top


Output, scripting, and shell integration

What output formats are supported?

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.yaml

Is the JSON contract stable?

Field names on list/get output are covered by our compatibility contract and change only on a major version. Fields we add are additive.

How do I enable tab completion?

# bash
harness completion bash > /etc/bash_completion.d/harness

# zsh
harness completion zsh > "${fpath[1]}/_harness"

# fish
harness completion fish > ~/.config/fish/completions/harness.fish

Completion is live-API-backed where it makes sense — harness get pipeline <TAB> calls the API and lists real pipeline IDs, cached briefly on disk.

Where does the CLI keep its files?

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.

↑ back to top


Interactive TUI (--ui)

What does --ui do?

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> --ui

Every paged list command gets --ui for free — the flag is auto-wired from the spec, not hand-added.

When does --ui refuse to run?

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.

Are keys configurable?

Not yet. Defaults follow common conventions:

Key Action
Arrows or hjkl Navigate
/ Filter
enter Drill in
q or ctrl-c Quit
? Keybinding overlay

↑ back to top


Comparisons

How is this different from the older Harness CLIs?

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.

Should I use the CLI or the REST API?

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

Should I use the CLI or the Terraform provider?

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.

Why not just use curl and jq?

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.

↑ back to top


AI agents

Can I hand this to Claude Code / Cursor / Copilot CLI?

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.

Does the CLI enforce RBAC when an agent runs it?

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.

Is there an MCP server?

Yes — Harness supports official Harness MCP.

Can an agent break something in production?

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 promptsdelete and some execute:* variants require --yes on the command line; instruct the agent never to pass it
  • The audit trail — catches everything after the fact

↑ back to top


Extending and contributing

Where's the source?

github.com/harness/cli. Apache 2.0. All development on main, in the open.

How do I add a new command?

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.

Can I write a plugin or a whole module?

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.

How do I run the CLI locally against my changes?

git clone https://github.com/harness/cli
cd cli
make build
./bin/harness list noun

make test runs unit tests. make e2e runs the integration suite against a Harness account — you'll need one and a PAT.

Where do I file bugs or requests?

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.

↑ back to top


Trust and security

What does curl … | sh actually run?

The installer script at install.sh. It:

  1. Detects your OS/arch.
  2. Downloads the matching binary and checksum from GitHub releases.
  3. Verifies the checksum. If cosign is on your PATH, verifies the signature too.
  4. Moves the binary into $HOME/.local/bin (or HARNESS_INSTALL_DIR).
  5. Prints a hint to add that directory to your PATH if 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.

Can I verify releases with cosign?

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_amd64

Important

Report security issues to security@harness.io, not the public tracker.

↑ back to top


Troubleshooting

--ui requires an interactive terminal (TTY)

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.

authentication failed (exit 2)

Run harness auth status. Common causes:

  • PAT expired or was rotated → re-run harness auth login.
  • HARNESS_API_KEY set to a stale value → unset HARNESS_API_KEY if you meant to use a profile.
  • Wrong account → harness --profile <name> list account.

resource not found (exit 3) on something I can see in the UI

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.

↑ back to top


Clone this wiki locally