spacectl, the Spacelift CLI
spacectl is a utility wrapping Spacelift's GraphQL API for easy programmatic access in command-line contexts - either in manual interactive mode (in your local shell), or in a predefined CI pipeline (GitHub actions, CircleCI, Jenkins etc).
Its primary purpose is to help you explore and execute actions inside Spacelift. It provides limited functionality for creating or editing resources. To do that programatically, you can use the Spacelift Terraform Provider.
Installation
Officially supported packages
Officially supported packages are maintained by Spacelift and are the preferred ways to install spacectl
Homebrew
You can install spacectl using Homebrew on MacOS or Linux:
brew install spacelift-io/spacelift/spacectl
Windows
You can install spacectl using winget:
winget install spacectl
or
winget install --id spacelift-io.spacectl
Docker image
spacectl is distributed as a Docker image, which can be used as follows:
docker run -it --rm ghcr.io/spacelift-io/spacectl stack deploy --id my-infra-stack
> Don't forget to add the required environment variables in order to authenticate.
asdf
asdf plugin add spacectl
asdf install spacectl latest
asdf global spacectl latest
GitHub Release
Alternatively, spacectl is distributed through GitHub Releases as a zip file containing a self-contained statically linked executable built from the source in this repository. Binaries can be download directly from the Releases page.
Usage on GitHub Actions
We have setup-spacectl GitHub Action that can be used to install spacectl:
steps:
- name: Install spacectl
uses: spacelift-io/setup-spacectl@main
- name: Deploy infrastructure
env:
SPACELIFT_API_KEY_ENDPOINT: https://unicorn.app.spacelift.io
SPACELIFT_API_KEY_ID: ${{ secrets.SPACELIFT_API_KEY_ID }}
SPACELIFT_API_KEY_SECRET: ${{ secrets.SPACELIFT_API_KEY_SECRET }}
run: spacectl stack deploy --id my-infra-stack
Authenticating with GitHub OIDC instead (no long-lived secret)
Instead of storing a long-lived secret, let spacectl mint a short-lived GitHub OIDC token and use it as the API key secret. This needs an API key configured for OIDC and id-token: write permission on the job.
Set SPACELIFT_API_KEY_OIDC_PROVIDER=github-actions in place of SPACELIFT_API_KEY_SECRET. spacectl requests a new token from GitHub every time it exchanges the key for a Spacelift session, so long-running commands keep working after GitHub's ~5 minute token expires.
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Install spacectl
uses: spacelift-io/setup-spacectl@main
- name: Deploy infrastructure
env:
SPACELIFT_API_KEY_ENDPOINT: https://unicorn.app.spacelift.io
SPACELIFT_API_KEY_ID: ${{ vars.SPACELIFT_API_KEY_ID }}
SPACELIFT_API_KEY_OIDC_PROVIDER: github-actions
run: spacectl stack deploy --id my-infra-stack
The token's audience defaults to the endpoint host (unicorn.app.spacelift.io above), so set the API key's client ID to that host. If your key uses a different client ID, set SPACELIFT_API_KEY_OIDC_AUDIENCE to it.
Disclaimer: These packages are community-maintained, please verify the package integrity yourself before using them to install or update spacectl.
Arch linux
Install spacectl-bin from the Arch User Repository (AUR):
yay -S spacectl-bin
Please make sure to verify the PKGBUILD before installing/updating.
Alpine linux
Install spacectl from the Alpine Repository (alpine packages):
apk add spacectl --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing
Please make sure to verify the APKBUILD before installing/updating.
Quick Start
Authenticate using spacectl profile login:
> spacectl profile login my-account
Enter Spacelift endpoint (eg. https://unicorn.app.spacelift.io/): https://unicorn.app.spacelift.io
Select authentication flow:
1) for API key,
2) for GitHub access token,
3) for login with a web browser
Option: 3
Use spacectl :rocket::
> spacectl stack list
Name | Commit | Author | State | Worker Pool | Locked By
stack-1 | 1aa0ef62 | Adam Connelly | NONE | |
stack-2 | 1aa0ef62 | Adam Connelly | DISCARDED | |
Getting Help
To list all the commands available, use spacectl help:
> spacectl help
NAME:
spacectl - Programmatic access to Spacelift GraphQL API.
USAGE:
spacectl [global options] [command [command options]]
VERSION:
1.13.0
COMMANDS:
profile Manage Spacelift profiles
whoami Print out logged-in user's information
registry Work with Spacelift's private module and provider registry
version Print out CLI version
module Manage a Spacelift module
stack Manage a Spacelift stack
provider Manage a Terraform provider
run-external-dependency Manage Spacelift Run external dependencies
workerpool Manages workerpools and their workers.
blueprint Manage Spacelift blueprints
template Manage Spacelift templates
policy Manage Spacelift policies
audit-trail Manage Spacelift audit trail entries
ai Work with Spacelift Intelligence
mcp Manage MCP server
help, h Shows a list of commands or help for one command
GraphQL:
api Call the Spacelift GraphQL API
GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
To get help about a particular command or subcommand, use the -h flag:
> spacectl profile -h
NAME:
spacectl profile - Manage Spacelift profiles
USAGE:
spacectl profile [command [command options]]
COMMANDS:
current Outputs your currently selected profile
export-token Prints the current token to stdout. In order not to leak, we suggest piping it to your OS pastebin
usage-csv Prints CSV with usage data for the current account
list List all your Spacelift account profiles
login Create a profile for a Spacelift account
logout Remove Spacelift credentials for an existing profile
select Select one of your Spacelift account profiles
OPTIONS:
--help, -h show help
Example
The following screencast shows an example of using spacectl to run a one-off task in Spacelift:

Authentication
spacectl is designed to work in two different contexts - a non-interactive scripting mode (eg. external CI/CD pipeline) and a local interactive mode, where you type commands into your shell. Because of this, it supports two types of credentials - environment variables and user profiles.
We refer to each method of providing credentials as "credential providers" (like AWS), and details of each method are documented in the following sections.
Authenticating using environment variables
The CLI supports the following authentication methods via the environment:
spacectl looks for authentication configurations in the order specified above, and will stop as soon as it finds a valid configuration. For example, if a Spacelift API token is specified, Spacelift API keys and GitHub tokens will be ignored, even if their environment variables are specified.
Spacelift API tokens
Spacelift API tokens can be specified using the SPACELIFT_API_TOKEN environment variable. When this variable is found, the CLI ignores all the other authentication environment variables because the token contains all the information needed to authenticate.
NOTE: API tokens are generally short-lived and will need to be re-created often.
Spacelift API keys
To use a Spacelift API key, set the following environment variables:
SPACELIFT_API_KEY_ENDPOINT - the URL to your Spacelift account, for example https://unicorn.app.spacelift.io.
SPACELIFT_API_KEY_ID - the ID of your Spacelift API key. Available via the Spacelift application.
SPACELIFT_API_KEY_SECRET - the secret for your API key. Only available when the secret is created.
For an OIDC API key used from GitHub Actions, spacectl can mint the token itself. Replace SPACELIFT_API_KEY_SECRET with:
SPACELIFT_API_KEY_OIDC_PROVIDER - set to github-actions. The job needs permissions: id-token: write.
SPACELIFT_API_KEY_OIDC_AUDIENCE - optional. The audience of the minted token, which must match the key's client ID. Defaults to the host of SPACELIFT_API_KEY_ENDPOINT.
Setting both SPACELIFT_API_KEY_SECRET and SPACELIFT_API_KEY_OIDC_PROVIDER is an error.
GitHub tokens
GitHub tokens are only available to accounts that use GitHub as their identity provider. To use a GitHub token, set the following environment variables:
SPACELIFT_API_KEY_ENDPOINT - the URL to your Spacelift account, for example https://unicorn.app.spacelift.io.
SPACELIFT_API_GITHUB_TOKEN - a GitHub personal access token.
More information about API authentication can be found at .
Authenticating using account profiles
In order to make working with multiple Spacelift accounts easy in interactive scenarios, Spacelift supports account management through the profile family of commands:
❯ spacectl profile
NAME:
spacectl profile - Manage Spacelift profiles
USAGE:
spacectl profile command [command options] [arguments...]
COMMANDS:
current Outputs your currently selected profile
export-token Prints the current token to stdout. In order not to leak, we suggest piping it to your OS pastebin
list List all your Spacelift account profiles
login Create a profile for a Spacelift account
logout Remove Spacelift credentials for an existing profile
select Select one of your Spacelift account profiles
help, h Shows a list of commands or help for one command
OPTIONS:
--help, -h show help (default: false)
Each of the subcommands requires an account alias, which is a short, user-friendly name for each set of credentials (account profiles). Profiles don't need to be unique - you can have multiple sets of credentials for a single account too.
Account profiles support three authentication methods:
- GitHub access tokens
- API keys
- Login with a browser (API token).
In order to authenticate to your first profile, type in the following (make sure to replace ${MY_ALIAS} with the actual profile alias):
❯ spacectl profile login ${MY_ALIAS}
Enter Spacelift endpoint (eg. https://unicorn.app.spacelift.io/):
In the next step, you will be asked to choose which authentication method you are going to use. Note that if your account is using SAML-based SSO authentication, then API keys and login with a browser are your only options. After you're done entering credentials, the CLI will validate them against the server, and assuming that they're valid, will persist them in a credentials file in .spacelift/${MY_ALIAS}. It will also create a symlink in ${HOME}/.spacelift/current pointing to the current profile.
By default the login process is interactive, however, if that does not fit your workflow, the steps can be predefined using flags, for example:
❯ spacectl profile login --method browser --endpoint https://unicorn.app.spacelift.io local-test
You can switch between account profiles by using spacectl profile select ${MY_ALIAS}. What this does behind the scenes is point ${HOME}/.spacelift/current to the new location. You can also delete stored credetials for a given profile by using the spacectl profile logout ${MY_ALIAS} command.
Selecting a profile per command or shell
spacectl profile select changes the profile for every shell, since the selection is stored in the config file. When you need one terminal on a different profile - a different organization, or a different API key within the same organization - set the SPACELIFT_PROFILE environment variable instead:
export SPACELIFT_PROFILE=my-other-account # for the rest of this shell
SPACELIFT_PROFILE=my-other-account spacectl stack list # for a single command
The variable selects an existing profile by alias, so credentials stay in the config file rather than being exported into your environment. It never modifies the stored selection, so spacectl profile select in another shell is unaffected, and unsetting it returns you to the selected profile.
SPACELIFT_PROFILE takes precedence over credentials supplied through the environment (SPACELIFT_API_KEY_ID and friends): naming a profile is deliberate, whereas those variables are easy to leave behind in a shell. If the named profile does not exist, spacectl reports that rather than falling back to another credential source.
Overriding the config directory location
By default profiles are stored in ${HOME}/.spacelift. In containers or CI runners $HOME may not be set or writable, so you can point spacectl at a different directory with the SPACELIFT_CONFIG_DIR environment variable:
export SPACELIFT_CONFIG_DIR=/workspace/.spacelift
spacectl profile login my-account
When SPACELIFT_CONFIG_DIR is set it takes precedence over ${HOME}/.spacelift; otherwise the default location is used.
Custom TLS configuration
If your Spacelift endpoint is served behind a custom or internal CA, spacectl needs to trust that CA to establish a TLS connection. This usually works out of the box on a workstation where the certificate is installed in the OS trust store, but not in minimal environments that only ship the public CA bundle, where the same command fails with a TLS verification error.
spacectl reads the following environment variables to configure TLS for API requests:
SPACELIFT_API_TLS_CA - path to a PEM bundle used to verify the Spacelift API endpoint. Use this to trust a custom or internal CA.
SPACELIFT_API_TLS_CERT and SPACELIFT_API_TLS_KEY - paths to a client certificate and key, for endpoints that require mutual TLS.
If SPACELIFT_API_TLS_CA is not set, spacectl falls back to the standard SSL_CERT_FILE variable (honored by Go's TLS stack), also pointing at a PEM file.
> [!NOTE]
> When a CA bundle is provided through either variable, it replaces the system trust store rather than extending it, so the file must contain the full chain needed to verify the endpoint.
Authenticating through a reverse proxy
Some Spacelift deployments sit behind a reverse proxy that requires its own credential, such as GCP Identity-Aware Proxy or Azure AD Application Proxy. The proxy expects that credential in the Proxy-Authorization header, separate from the Authorization header that carries your Spacelift token. spacectl can supply it from one of three sources, checked in this order:
- The
SPACELIFT_PROXY_AUTH_TOKEN environment variable. This suits CI and scripts, where another step has already obtained the proxy token.
- A
token_file named in the profile. The file is re-read whenever the proxy rejects the current token, so an external process can keep it fresh.
- A
command named in the profile. spacectl runs it to obtain a token, and runs it again if the proxy rejects the token it produced. This suits interactive use with short-lived proxy tokens, where re-running a helper is simpler than refreshing a file by hand.
The first source that is set wins. The file and command sources are configured through an optional proxy_auth object in the profile's credentials in config.json:
{
"proxy_auth": {
"token_file": "/run/secrets/proxy-token"
}
}
{
"proxy_auth": {
"command": ["/usr/local/bin/proxy-auth", "--cached"]
}
}
token_file - path of a file whose contents, trimmed of whitespace, are sent as the bearer token.
command - program and arguments that print a bearer token on stdout. The program must be an absolute path; nothing is resolved against the working directory or PATH. The command runs with your privileges, so set it only in a configuration file you control. spacectl refuses to run it if the configuration file is a symbolic link or is writable by other users.
spacectl profile login keeps the proxy_auth settings of an existing profile when it re-authenticates it, so a browser login does not have to be followed by editing config.json again.
The token is only ever sent to the profile's Spacelift endpoint. If a response redirects somewhere else, the redirected request goes out without it. The token is cached for the life of the process while the proxy accepts it. On a 401, a 407, or a redirect to another host, spacectl discards it, consults the source again, and retries the request once. If the retry is still rejected, a single warning names the source so you know which credential to refresh. When proxy_auth is not configured and the variable is unset, requests are sent unchanged.
Private module and provider registry
terraform init and tofu init need a credential for Spacelift's private module and provider registry. spacectl registry credentials prints one for the current session. It resolves credentials the same way as spacectl profile export-token: the selected profile first, then the environment. That makes it work with an OIDC API key in CI.
$ spacectl registry credentials
TF_TOKEN_app_spacelift_io=eyJ...
TF_TOKEN_spacelift_io=eyJ...
--format terraformrc prints credentials blocks for ~/.terraformrc or ~/.tofurc in place of env lines. The registry hosts come from the Spacelift endpoint: unicorn.app.spacelift.io gives app.spacelift.io and spacelift.io, and a self-hosted endpoint gives its own host, port included. TF_TOKEN_* names can't hold a port, so a self-hosted endpoint with a port needs --format terraformrc. Use --host (repeatable) to set the hosts yourself.
To use it in your own shell, export the variables. A plain eval only sets shell variables, which Terraform doesn't see:
set -a; eval "$(spacectl registry credentials)"; set +a
terraform init
On GitHub Actions, authenticate spacectl as in Usage on GitHub Actions, then write the credentials to a CLI config file:
- name: Configure registry credentials
run: |
spacectl registry credentials --format terraformrc > "$RUNNER_TEMP/spacelift.tfrc"
echo "TF_CLI_CONFIG_FILE=$RUNNER_TEMP/spacelift.tfrc" >> "$GITHUB_ENV"
- run: terraform init
Don't write the env format to $GITHUB_ENV. The runner lists those variables in the log of every later step, and it only masks values it knows are secret, which a freshly exchanged token isn't. TF_CLI_CONFIG_FILE points Terraform and OpenTofu at the file, so only its path ends up in the logs, and an existing ~/.terraformrc is left alone.
The command prints your current Spacelift token and doesn't extend it. Tokens exchanged from an API key or GitHub token last between 1 and 10 hours, so run the command again in jobs that take longer. A token stored by spacectl profile login keeps its original expiry, and the command fails once it has expired.
MCP Server
Spacectl includes an MCP (Model Context Protocol) server that allows AI models to interact with Spacelift through a standardized interface. MCP is an open protocol that standardizes how applications provide context to LLMs, similar to how USB-C provides a standardized way to connect devices to peripherals.
Authentication
The MCP server uses the same authentication methods as the standard CLI. You can use any of the authentication methods described above.
Configuration
To use the Spacelift MCP server with your AI tool:
- Find your tool's MCP configuration file
- Add the following configuration:
{
"mcpServers": {
"spacelift": {
"command": "spacectl",
"args": ["mcp", "server"]
}
}
}
Or if you prefer using Docker:
{
"mcpServers": {
"spacelift": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e", "SPACELIFT_API_TOKEN=your-api-token-here",
// Or use API key authentication:
// "-e", "SPACELIFT_API_KEY_ENDPOINT=https://your-account.app.spacelift.io",
// "-e", "SPACELIFT_API_KEY_ID=your-key-id",
// "-e", "SPACELIFT_API_KEY_SECRET=your-key-secret",
"ghcr.io/spacelift-io/spacectl",
"mcp",
"server"
]
}
}
}
- Restart your AI tool to apply the changes
Stack Management
- list_stacks: Browse and search stacks with pagination
- list_stack_runs: View tracked runs for a stack
- list_stack_proposed_runs: View preview runs for a stack
- get_stack_run: Get run details
- get_stack_run_logs: Access run logs with pagination
- get_stack_run_changes: See infrastructure changes from a run
- trigger_stack_run: Start new runs (PROPOSED or TRACKED)
- confirm_stack_run: Approve runs waiting for confirmation
- discard_stack_run: Cancel pending or in-progress runs
- list_resources: View infrastructure resources managed by stacks
- local_preview: Create preview runs using local workspace files
Module Registry
- list_modules: Browse modules in your private registry
- get_module: Get module information including metadata, inputs, outputs
- list_module_versions: List all versions for a module
- get_module_version: Get version information including dependencies and consumers
- search_modules: Search with filtering by provider, labels, space, public/private status
GraphQL Schema
- introspect_graphql_schema: Complete schema introspection
- get_graphql_type_details: Information about specific GraphQL types
- search_graphql_schema_fields: Search for fields, types, or operations
- get_authentication_guide: Authentication guidance with examples
Agent Skill
spacectl ships with an agent skill for LLM-based coding agents (Claude Code, OpenCode, etc.). Install it with:
npx skills add spacelift-io/spacectl
Contributing
For information about how to contribute to the development of spacectl, please see our CONTRIBUTING.md file.