cli

module
v6.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: MIT

README

Steadybit CLI  

Installation | Authorization | Usage | Changelog


The Steadybit CLI enables you to use the Steadybit platform features easier in an automated way and implement e.g. GitOps practices easily. You can retrieve, create or adjust experiment designs as well as running them straight away.

Prerequisites

You need a Steadybit account. You can create a free account via our website.

Installation

The CLI is a single binary for Linux, macOS and Windows, on amd64 and arm64.

With Homebrew, on macOS or Linux, which also installs the shell completions:

brew install steadybit/tap/steadybit

On Debian, Ubuntu, Fedora or RHEL, install the package attached to every release from v6.1.0 on, which also installs the shell completions:

# Debian, Ubuntu
curl -fsSLO https://github.com/steadybit/cli/releases/latest/download/steadybit-cli_amd64.deb
sudo apt-get install ./steadybit-cli_amd64.deb
# Fedora, RHEL, Amazon Linux
curl -fsSLO https://github.com/steadybit/cli/releases/latest/download/steadybit-cli_amd64.rpm
sudo dnf install ./steadybit-cli_amd64.rpm

Or download the archive for your platform from the releases (checksums.txt lists their SHA-256) and put steadybit on your PATH:

curl -sL https://github.com/steadybit/cli/releases/latest/download/steadybit_linux_amd64.tar.gz | tar -xz steadybit
sudo mv steadybit /usr/local/bin/

With Go installed:

go install github.com/steadybit/cli/v6/cmd/steadybit@latest

The CLI is also available as the container image steadybit/cli, and in GitHub Actions through steadybit/cli.

Up to version 5, the CLI was installed with npm install -g steadybit. That package is no longer updated; uninstall it with npm uninstall -g steadybit and install the binary instead. Profiles in ~/.steadybit keep working.

Shell completion is available for bash, zsh, fish and PowerShell, see steadybit completion --help.

At a terminal, the CLI tells you once a day when a newer release is out. Set STEADYBIT_NO_UPDATE_CHECK=1 to turn that off; it is always off in CI.

Authorization

You need an API access token. You can grab one via our platform through the Settings -> API Access Tokens page.

➜ steadybit config profile add
? Profile name: steadybit
? API access token: [hidden]
? Base URL of the Steadybit server: https://platform.steadybit.com

Rate limiting

The platform meters API requests with a token bucket: a burst of 100 requests, refilling by 25 every 15 seconds. The CLI paces itself to that allowance, so a command that walks a large tenant — experiment dump above all — takes a while rather than being rejected part way through. It warns up front when a dump covers more than 100 experiments.

Override the allowance if your deployment is configured differently:

Variable Default Meaning
STEADYBIT_RATE_LIMIT_BURST 100 Requests allowed before pacing
STEADYBIT_RATE_LIMIT_REFILL 25 Requests restored each interval
STEADYBIT_RATE_LIMIT_INTERVAL 15 Length of that interval, seconds

Usage

Get an existing experiment yaml from Steadybit and write it to file:

steadybit experiment get -k ADM-1 -f experiment.yml

Only apply the experiment:

steadybit experiment apply -f experiment.yml

Apply and run the experiment in one step:

steadybit experiment run -f experiment.yml

Run existing experiment:

steadybit experiment run -k ADM-1

Dump all experiments and executions from all teams:

steadybit experiment dump -d ./dump

Dump only certain teams, by team key:

steadybit experiment dump -d ./dump --team ADM WEBHOOK

Validate advice status

steadybit advice validate-status -e "Global" -q "k8s.cluster-name=dev-demo and k8s.namespace=steadybit-demo"

Every command shows examples with --help, e.g. steadybit schedule create --help.

Experiments from templates

Find a template and the placeholders it asks for:

steadybit template list --search kubernetes
steadybit template get -i <template-id> --placeholders -f values.yml

Create an experiment from it, or update the one created before with the same external id:

steadybit experiment apply --template <template-id> --team ADM --environment Global \
  --external-id shop-latency --placeholders values.yml -p CLUSTER=prod

Create and run it in one step:

steadybit experiment run --template <template-id> --team ADM --placeholders values.yml
Experiment runs
steadybit execution list --team ADM --state FAILED --from 2026-09-28
steadybit execution list --team ADM --state FAILED ERRORED --from 2026-09-28 --fail-on-match   # fail a pipeline
steadybit execution get -i 1234 -t json
steadybit execution cancel -i 1234
steadybit execution property set -i 1234 -k approvedBy --value "Jane Doe"
steadybit execution artifact list -i 1234
steadybit execution artifact download -i 1234 -d ./artifacts

Show the state of an experiment's latest run in a README with a status badge. The badge URL carries the tenant key, never the access token:

steadybit experiment badge -k ADM-1              # Markdown; --format html or url
Experiment schedules
steadybit schedule create -k ADM-1 --cron "0 0 9 ? * MON-FRI" --timezone Europe/Berlin
steadybit schedule list --team ADM
steadybit schedule disable -i <schedule-id>

Schedules can be kept in Git like experiments. apply writes the id of a new schedule back into its file, so that applying it again updates it:

steadybit schedule get -i <schedule-id> -f schedule.yml
steadybit schedule apply -f ./schedules -R
Services

Keep services in Git like experiments. apply writes the id of a new service back into its file, so that applying it again updates it:

steadybit service list --team ADM
steadybit service get -i <service-id> -f service.yml
steadybit service apply -f ./services -R

Gate a pipeline on the risk of a service:

steadybit service risk -i <service-id> --fail-above 50

Manage the experiments and variables of a service:

steadybit service experiment list -i <service-id>
steadybit service experiment provide -i <service-id> --template <template-id> -p REPLICAS=3
steadybit service experiment link -i <service-id> -k ADM-1 --category Redundancy
steadybit service variable set -i <service-id> endpoint=http://shop.internal region=eu

Service profiles work the same way:

steadybit service-profile list --origin custom
steadybit service-profile apply -f profile.yml
Environments, teams and more as files in Git

Experiment templates, environments, teams, hubs, integrations and property definitions and associations are managed the same way, with list, get, apply and delete:

steadybit environment get -i <environment-id> -f environment.yml
steadybit team apply -f ./teams -R
steadybit integration webhook apply -f webhook.yml
steadybit template apply -f ./templates -R

Their parts have commands of their own:

steadybit environment variable set -i <environment-id> region=eu
steadybit team member add -k ADM --email jane@example.com --role OWNER
steadybit team environment add -k ADM --environment Global
Tenant administration
steadybit access-token create --name ci --type TEAM --team ADM --expires-at 2026-12-31
steadybit user invite --email jane@example.com --team ADM
steadybit killswitch status
steadybit audit-log --from 2026-09-01 -t json
steadybit license show
steadybit report experiments-executed --group-by STATE --rollup MONTHLY

Commands that cannot be undone, such as killswitch activate, access-token delete or team member set, ask for confirmation on a terminal; --yes skips the question.

Targets and actions
steadybit target query -e Global --target-type com.steadybit.extension_container.container --attribute k8s.namespace
steadybit target attribute values -e Global --target-type com.steadybit.extension_container.container -k k8s.namespace
steadybit target stats -q 'k8s.namespace="shop"'
steadybit action list --kind ATTACK

Everyday use

steadybit experiment init                     # create an experiment from a template, answering its placeholders
steadybit execution watch -k ADM-1            # follow the latest run of an experiment live
steadybit experiment get -k ADM-1 --profile prod   # use another configured profile for one command

Shell completion (steadybit completion --help) completes experiment keys, team keys, environment names, and the ids of templates, schedules, services and service profiles from the platform.

GitOps

Keep a team's experiments, schedules, services and custom service profiles in Git:

steadybit export --team ADM -d ./chaos    # write them as files
steadybit diff -d ./chaos                 # what differs from the platform; exits with 2 if anything does
steadybit apply -d ./chaos --dry-run      # what an apply would create or update
steadybit apply -d ./chaos                # profiles, services, experiments, then schedules

Keep the tenant's configuration in Git the same way: experiment templates, environments, teams, property definitions, hubs, integrations and custom service profiles, one directory each (templates/, environments/, teams/, property-definitions/, hubs/, integrations/<kind>/, service-profiles/):

steadybit export --tenant -d ./platform   # needs an admin access token
steadybit diff -d ./platform
steadybit apply -d ./platform --dry-run
steadybit apply -d ./platform             # definitions, environments, teams, hubs, templates, integrations, profiles

What the platform provides is left out: the hubs it connects, the templates imported from a hub (template import brings them back) and Steadybit's service profiles. Hubs are synchronized as they are applied, so that the service profiles find their templates.

Credentials of integrations (secrets, header values, Slack webhook URLs) are written as '********'. A mask stands for what the platform holds: diff does not report it, and apply leaves out the integrations that match the platform and sends the stored header values and URLs in place of their masks. The platform never reads a secret back, so to change an integration that has one, put the secret in, e.g. from a CI secret, before applying. As the platform cannot say whether that is the secret it holds, such a file is always a difference. diff never prints credentials.

Each kind also has its own diff, and its apply a --dry-run, e.g. steadybit experiment diff -f ./experiments -R or steadybit integration webhook diff -f ./platform/integrations/webhook -R. Fields the platform fills in with defaults are not reported as differences.

In CI

experiment run waits for the run and fails the job when the run fails; with --no-wait it still watches the run until it started, for up to 15 seconds, and fails when the platform canceled or errored it before it ran. A few options make it fit pipelines:

Option Does
--report steadybit.xml A JUnit report, one test case per step; .json for JSON
--timeout 30m Cancels the run and fails when it has not ended in time
--show-steps Prints each step's state as it changes
--keep-running-on-interrupt Leaves the run going when the job is cancelled; by default it is stopped
--parallel 3 Runs up to 3 of the experiments at once; all are reported
--expect-state FAILED Passes once the run reaches this state, and fails when it ends in another
--expect-reason "…" Also requires the run's reason to be exactly this
--expectation-retries 2 Runs the experiment again when a run did not end as expected
--busy-retries 3 Waits and tries again while another experiment runs, instead of failing
--external-id shop-latency Runs the experiment with this external id, instead of -k

In GitHub Actions a summary of every run is added to the job summary.

GitHub Actions
- uses: steadybit/cli@v6
- run: steadybit experiment run -f ./experiments -R --yes --report steadybit.xml
  env:
    STEADYBIT_TOKEN: ${{ secrets.STEADYBIT_TOKEN }}
- uses: mikepenz/action-junit-report@v5
  if: always()
  with:
    report_paths: steadybit.xml
Moving from steadybit/run-experiment

The steadybit/run-experiment action is being deprecated in favor of this CLI, which does what it does and more: it cancels the attack when the job is canceled, runs several experiments at once, writes a JUnit report, and works the same in any CI. A step using the action becomes:

# Before
- uses: steadybit/run-experiment@v1
  with:
    apiAccessToken: ${{ secrets.STEADYBIT_TOKEN }}
    experimentKey: ADM-1
    expectedState: FAILED

# After
- uses: steadybit/cli@v6
- run: steadybit experiment run -k ADM-1 --yes --busy-retries 3 --expect-state FAILED
  env:
    STEADYBIT_TOKEN: ${{ secrets.STEADYBIT_TOKEN }}
Action input experiment run
apiAccessToken the STEADYBIT_TOKEN variable
baseURL the STEADYBIT_URL variable, for an on-premise platform
experimentKey -k ADM-1
externalId --external-id shop-latency
expectedState --expect-state FAILED
expectedReason, expectedFailureReason --expect-reason "..."
parallel: true --allowParallel
maxRetries (3 by default) --busy-retries 3; the CLI does not retry unless asked
maxRetriesOnExpectationFailure --expectation-retries 2
delayBetweenRetriesOnExpectationFailure --expectation-retry-interval 1m (a duration, not ms)
maxRetriesOnValidationFailure --retries 2
delayBetweenRetriesOnValidationFailure --retryInterval 15 (seconds)

The action's outputs are in the JSON report: --report run.json writes each run's id, state, reason and apiLocation (the action's executionUrl).

- id: chaos
  run: |
    steadybit experiment run -k ADM-1 --yes --report run.json
    echo "state=$(jq -r '.[0].state' run.json)" >> "$GITHUB_OUTPUT"
GitLab CI
chaos:
  image:
    name: steadybit/cli:6
    entrypoint: ['']
  script:
    - steadybit experiment run -f ./experiments -R --yes --report steadybit.xml
  artifacts:
    when: always
    reports:
      junit: steadybit.xml

Every listing prints the platform's items with -t json or -t yaml, and --jq filters whatever JSON a command prints, without jq installed:

steadybit service list --team ADM --jq '.[] | "\(.id) \(.name)"'

Container Image

You can also use the cli via our container image:

docker run -e"STEADYBIT_TOKEN=****" steadybit/cli:latest experiment get -k ADM-1

Directories

Path Synopsis
Package api is the platform client, generated from the committed OpenAPI spec.
Package api is the platform client, generated from the committed OpenAPI spec.
cmd
steadybit command
internal
accesstoken
Package accesstoken implements the `access-token` commands, on the v2 endpoints only.
Package accesstoken implements the `access-token` commands, on the v2 endpoints only.
action
Package action implements the `action` commands.
Package action implements the `action` commands.
advice
Package advice implements `advice validate-status`.
Package advice implements `advice validate-status`.
auditlog
Package auditlog implements the `audit-log` command.
Package auditlog implements the `audit-log` command.
badge
Package badge implements the `experiment badge` command: a status badge to embed in a README, which is served without an access token.
Package badge implements the `experiment badge` command: a status badge to embed in a README, which is served without an access token.
cli
Package cli wires the commands.
Package cli wires the commands.
config
Package config reads and writes the CLI configuration exactly as the TypeScript CLI did, so that an upgrade keeps every profile a user has already set up.
Package config reads and writes the CLI configuration exactly as the TypeScript CLI did, so that an upgrade keeps every profile a user has already set up.
environment
Package environment implements the `environment` commands.
Package environment implements the `environment` commands.
execution
Package execution implements the `execution` commands on experiment runs.
Package execution implements the `execution` commands on experiment runs.
experiment
Package experiment implements `experiment get`, `apply` and `run`.
Package experiment implements `experiment get`, `apply` and `run`.
gitops
Package gitops compares files kept in Git with what the platform holds, for `diff` and `apply --dry-run`, and moves whole projects between the two.
Package gitops compares files kept in Git with what the platform holds, for `diff` and `apply --dry-run`, and moves whole projects between the two.
hub
Package hub implements the `hub` commands.
Package hub implements the `hub` commands.
integration
Package integration implements the `integration` commands.
Package integration implements the `integration` commands.
interrupt
Package interrupt decides what Ctrl-C and SIGTERM do.
Package interrupt decides what Ctrl-C and SIGTERM do.
jsyaml
Package jsyaml writes YAML and JSON exactly as the TypeScript CLI did with js-yaml's dump and JSON.stringify.
Package jsyaml writes YAML and JSON exactly as the TypeScript CLI did with js-yaml's dump and JSON.stringify.
killswitch
Package killswitch implements the `killswitch` commands.
Package killswitch implements the `killswitch` commands.
license
Package license implements the `license` commands.
Package license implements the `license` commands.
output
Package output formats documents and gates colour on stdout being a terminal, as the TypeScript CLI did: its output is routinely parsed by GitOps pipelines.
Package output formats documents and gates colour on stdout being a terminal, as the TypeScript CLI did: its output is routinely parsed by GitOps pipelines.
platform
Package platform builds the generated API client with what every request needs: authentication, a User-Agent, request logging, and retries that are safe to make.
Package platform builds the generated API client with what every request needs: authentication, a User-Agent, request logging, and retries that are safe to make.
platformtest
Package platformtest runs commands against a fake platform: an httptest server whose endpoints a test declares, which records every request it receives.
Package platformtest runs commands against a fake platform: an httptest server whose endpoints a test declares, which records every request it receives.
prompt
Package prompt asks questions on a terminal.
Package prompt asks questions on a terminal.
property
Package property implements the `property` commands: the definitions of the properties experiments and services carry, and their associations, which say who carries them.
Package property implements the `property` commands: the definitions of the properties experiments and services carry, and their associations, which say who carries them.
report
Package report implements the `report` commands: time series over the tenant, printed as the platform sends them.
Package report implements the `report` commands: time series over the tenant, printed as the platform sends them.
resource
Package resource holds what the commands managing schedules, services, profiles, templates and runs share: writing a document to a file or stdout, reading one back, and applying files with the new id written into them.
Package resource holds what the commands managing schedules, services, profiles, templates and runs share: writing a document to a file or stdout, reading one back, and applying files with the new id written into them.
schedule
Package schedule implements the `schedule` commands.
Package schedule implements the `schedule` commands.
service
Package service implements the `service` commands.
Package service implements the `service` commands.
serviceprofile
Package serviceprofile implements the `service-profile` commands.
Package serviceprofile implements the `service-profile` commands.
table
Package table prints tables laid out as console-table-printer did for the TypeScript CLI: box drawing, one space of padding, right-aligned unless a column says otherwise.
Package table prints tables laid out as console-table-printer did for the TypeScript CLI: box drawing, one space of padding, right-aligned unless a column says otherwise.
target
Package target implements the `target` commands.
Package target implements the `target` commands.
team
Package team implements the `team` commands.
Package team implements the `team` commands.
template
Package template implements the `template` commands.
Package template implements the `template` commands.
tools/spec command
Command spec keeps the committed platform spec and the client generated from it in step with the platform.
Command spec keeps the committed platform spec and the client generated from it in step with the platform.
update
Package update tells someone at a terminal, at most once a day, that a newer release of the CLI exists.
Package update tells someone at a terminal, at most once a day, that a newer release of the CLI exists.
user
Package user implements the `user` commands.
Package user implements the `user` commands.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL