Browse the docs
CI/CD
Bitbucket Pipelines
Install crunu in a Bitbucket Pipelines step or use the crunu pipe, keep CRUNU_TOKEN in secured variables, and bind a step's OIDC token to your own audience.
Last updated
On this page
In Bitbucket Pipelines, a step either installs crunu with three commands and runs your command in the step's own image, or uses the crunu run pipe, which runs your command inside the pipe's container. Read Any CI with a service token first for how to create the token.
Repository variables
Add these under Repository variables:
CRUNU_TOKEN, the service tokencrunu_svc_…, marked Secured;CRUNU_SERVER,https://app.crunu.comor your own server's address;CRUNU_VERSION,CRUNU_INSTALL_URL,CRUNU_INSTALL_SHA256andCRUNU_BINARY_SHA256, from the CI setup block on the token's page.
With three commands
image: node:24
definitions:
steps:
- step: &test
name: Tests with staging variables
oidc: # only if the token has a CI binding
audiences:
- https://app.crunu.com # your server address: an audience of its own
script:
- curl -sSf "$CRUNU_INSTALL_URL" -o /tmp/crunu-install.sh
- echo "$CRUNU_INSTALL_SHA256 /tmp/crunu-install.sh" | sha256sum -c -
- sh /tmp/crunu-install.sh --version "$CRUNU_VERSION" --sha256 "$CRUNU_BINARY_SHA256" --user-install
- crunu run --env web-app/staging -- npm test
pipelines:
default:
- step: *testThe command runs in the step's image with all of its tools.
With the crunu run pipe
The pipe installs a pinned crunu, checks both checksums and runs:
crunu run --env <project/environment> -- sh -c "$COMMAND"Variables are decrypted in the memory of the crunu process and passed to the command through its environment. They aren't written to disk. The pipe's exit code is the command's exit code. If crunu couldn't get the variables, the exit code is its own and the command doesn't run.
The command runs inside the pipe's container, not in the step's image. The default base image is Node.js 24, with node, npm and npx. If the command needs other programs, build the pipe on another Debian, Ubuntu or Alpine base image.
pipelines:
default:
- step:
name: Tests with staging variables
script:
- pipe: docker://<registry>/<name>:<tag>
variables:
CRUNU_TOKEN: $CRUNU_TOKEN
CRUNU_SERVER: $CRUNU_SERVER
CRUNU_ENV: 'web-app/staging'
CRUNU_VERSION: $CRUNU_VERSION
CRUNU_INSTALL_URL: $CRUNU_INSTALL_URL
CRUNU_INSTALL_SHA256: $CRUNU_INSTALL_SHA256
CRUNU_BINARY_SHA256: $CRUNU_BINARY_SHA256
COMMAND: 'npm ci && npm test'| Variable | Required | Value |
|---|---|---|
CRUNU_TOKEN | yes | the service token |
CRUNU_SERVER | yes | the server address |
COMMAND | yes | a shell command, for example npm test |
CRUNU_ENV | no | one environment as project/environment. Without it and without CRUNU_ENVS, all environments granted to the token |
CRUNU_ENVS | no | several environments as a list |
CRUNU_VERSION | yes | the crunu version |
CRUNU_INSTALL_URL | yes, unless CRUNU_RELEASES_URL is set | the address of install.sh for this version |
CRUNU_INSTALL_SHA256, CRUNU_BINARY_SHA256 | yes | checksums from the CI setup block |
OIDC | no | 'true' when the token has a CI binding |
INHERIT_ENV | no | 'true' passes the whole environment of the pipe's container to the command, including BITBUCKET_* |
DEBUG | no | 'true' for a detailed crunu log. Secret values never appear in it |
By default the command gets only PATH, HOME, USER, LOGNAME, LANG, LC_ALL, TERM, TZ, SHELL, TMPDIR and the environment's variables. It runs in the clone directory of the repository.
OIDC in a Bitbucket step
A step with OIDC turned on gets a token in BITBUCKET_STEP_OIDC_TOKEN, and crunu picks it up itself. Bitbucket gives a step one token for all of its audiences. Add your server address as a custom audience under oidc: audiences:. The default audience, ari:cloud:bitbucket::workspace/<uuid>, also works, but every service in the workspace receives the same token, so your own audience is safer. Up to 10 audiences are allowed per step.
With the pipe, also pass OIDC: 'true'. The pipe then checks that the step's token exists and stops before installing crunu if it doesn't. Without OIDC: 'true' the pipe passes the step's token neither to crunu nor to the command. If the command needs an OIDC token for another cloud, run it in a separate step.
Bitbucket tokens have no jti claim. The server treats presenting the same token twice as a replay, so crunu signs in once per step and keeps that session.
A typical rule: provider Bitbucket, your workspace name and UUID, the repository UUID, branchName: main and, for production, the deployment environment UUID. See Bind a service token to CI with OIDC.
Where the token is visible
The pipe starts crunu with exec, so no other process in the pipe's container holds CRUNU_TOKEN, and on Linux crunu closes its own environment. That was checked with Docker's default container permissions: the command runs as root but without CAP_SYS_PTRACE. A process with that capability could read the environment of crunu. Repository variables are still visible to every other line of the step and to every step of the pipeline, so keep the token's grant small.