Skip to content

Deploy a static build from the command line with the bg-deploy binary and a scoped deploy token. It zips a folder (or uploads an existing .zip), uploads it, and publishes it live. The only input is a scoped deploy token, which carries both the target app and the endpoint URL, so there is no login, no AWS credentials, and no config file.

Install

bg-deploy is a single static binary with no runtime dependencies. Download the archive for your platform and put the extracted binary on your PATH:

PlatformDownload
Linux (x86-64)bg-deploy-linux-amd64.tar.gz
Linux (ARM64)bg-deploy-linux-arm64.tar.gz
macOS (Intel)bg-deploy-darwin-amd64.tar.gz
macOS (Apple silicon)bg-deploy-darwin-arm64.tar.gz
Windows (x86-64)bg-deploy-windows-amd64.zip
Windows (ARM64)bg-deploy-windows-arm64.zip
bash
curl -fsSLO https://app.behindgate.com/downloads/bg-deploy-linux-amd64.tar.gz
tar -xzf bg-deploy-linux-amd64.tar.gz
sudo mv bg-deploy /usr/local/bin/
bg-deploy --version

Every archive contains one executable named bg-deploy (bg-deploy.exe on Windows). To verify a download, fetch SHA256SUMS.txt alongside it and check it:

bash
curl -fsSLO https://app.behindgate.com/downloads/SHA256SUMS.txt
sha256sum -c SHA256SUMS.txt --ignore-missing

Get a deploy token

In the dashboard, open Settings → Deploy tokens and generate a token. The token is the only credential; it carries the target app and the endpoint URL.

Deploy

Set the token in the BEHINDGATE_TOKEN environment variable, then point bg-deploy at a folder or a .zip:

bash
export BEHINDGATE_TOKEN=<token>
bg-deploy ./dist            # zip ./dist and upload (asks to confirm)
bg-deploy -y ./dist         # skip the confirmation prompt (CI/unattended)
bg-deploy ./build.zip       # upload an existing .zip as-is

<path> is either a folder (zipped and uploaded) or an existing .zip file (uploaded as-is). bg-deploy prints the resolved endpoint first and asks you to confirm before it starts, unless you pass -y, so you can eyeball where a deploy is going.

Flags

FlagPurpose
-y, --yesSkip the confirmation prompt, for CI and other unattended runs.
--url <url>Pin the deploy endpoint instead of trusting the token's url claim, so a tampered or untrusted token can't send your build elsewhere (also useful for a local or dev endpoint).
--tag name=valueLabel the release, as name=value or a bare name. Repeat it for more than one.
--site-url <url>What to deploy to, as the URL it serves on: the host names the site and the path names the app (no path means the site root). Only for a CI trust, since a deploy token already names its target. Creating an app that is not there yet needs a trust that may create apps. Also BEHINDGATE_SITE_URL.
--create-appCreate the app --site-url names if it is not there yet, which needs a trust that may create apps. Without it a missing app is a configuration error, so a mistyped path cannot quietly become a new app.
--delete-appDelete the app --site-url names and exit, for tearing a preview down. A path with no app succeeds, so a teardown job is safe to re-run.
--trust <id>Name the CI trust to exchange under, when more than one in the workspace covers this pipeline. Also BEHINDGATE_TRUST_ID.
--jsonWrite one JSON result object to stdout and send everything else to stderr.
--versionPrint the version and exit.

The endpoint can also be pinned with the BEHINDGATE_URL environment variable, for CI systems configured through the environment rather than the command line. --url always wins over it.

By default bg-deploy reads the deploy endpoint from the token's own url claim. When you run a token whose origin you don't fully control, pass --url to pin the destination to an endpoint you name:

bash
bg-deploy --url <url> ./dist

A pinned endpoint is enforced, not merely preferred: if the token claims a different endpoint, the deploy is refused rather than overridden. So a token and a pinned endpoint have to agree; mint the token for the endpoint you deploy to, or leave the pin off and let the token's claim decide.

Use it in CI

CI never signs in: the deploy token is the whole credential. Store the token as a secret, expose it as BEHINDGATE_TOKEN, and run bg-deploy -y so it never waits on the confirmation prompt.

bash
BEHINDGATE_TOKEN=$BEHINDGATE_TOKEN bg-deploy -y ./dist

Revoke the token from Settings → Deploy tokens to cut off that pipeline immediately.

On GitHub Actions, GitLab CI and Bitbucket Pipelines you can skip the secret entirely: trust the repository once under Settings → CI trusts, leave BEHINDGATE_TOKEN unset, and bg-deploy authenticates as the job itself with the OIDC token the CI system already mints for it. See Deploy from CI without a secret.

Tag a release

--tag labels a release with whatever the pipeline knows about the build, so the deploy history says which commit is live rather than only when it went out. Tags appear on the release in the dashboard.

bash
bg-deploy -y \
  --tag sha=$GITHUB_SHA \
  --tag build=$GITHUB_RUN_NUMBER \
  --tag branch=$GITHUB_REF_NAME \
  ./dist

A tag is a name and an optional value, shown as name: value, or as just the name when it has no value (--tag nightly). A name starts with a letter and uses only letters, digits, dot, hyphen and underscore (sha, build.number, git-ref, run_id); the value is free text. Names are unique within a release, up to 20 tags. A value that resolves to nothing leaves the name as a plain marker, so an unset CI variable does not fail the deploy.

Exit codes

CodeMeaning
0Success.
1Runtime failure: network, upload, a server rejection.
2Configuration error: bad arguments or <path>, a missing or malformed token, an endpoint mismatch, or a --site-url naming an app that does not exist.

A missing and a malformed token are the same class of problem, a bad secret, so they share exit 2. Exit 1 is reserved for a deploy that actually failed.