Skip to content

Secrets

Secrets are application variables marked as secret. Shipper encrypts their values at rest, masks them in ordinary reads, and never includes them in deployment logs.

Mark a value as secret when it is a password, API token, private key, database URL with credentials, or any value whose disclosure grants access.

Non-secret values stay visible in the .env editor and the review list. Marking everything as secret makes changes harder to review without adding protection.

  • Secret values are encrypted at rest with the instance encryption key.
  • Ordinary reads return masked values and a hasValue marker.
  • The review list names the variable and its effect without repeating the value.
  • Release logs and deployment history do not contain secret values.
  • Revealing a saved value is an explicit action and requires the secrets capability for an API token.
  • Viewers cannot reveal secrets, open a terminal, or download backups.

The instance encryption key lives in /var/lib/shipper/encryption.key. An instance recovery archive includes the original key so existing values remain readable after recovery. Losing both the key and a valid archive makes encrypted values unrecoverable.

For Dockerfile builds, use a BuildKit secret mount:

# syntax=docker/dockerfile:1
FROM node:24-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN="$(cat /run/secrets/npm_token)" npm run build

Configure a variable named npm_token with Build scope and mark it as a secret. The secret id must match the variable name. The value is available to the build step but is not stored in the image layer.

Do not do this:

ARG NPM_TOKEN
RUN npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN

The ARG value is visible in image history and build cache metadata.

  1. Create the new credential at the provider.
  2. Update the secret in .env.
  3. Apply the change and restart or redeploy.
  4. Verify the application uses the new credential.
  5. Revoke the old credential.

A secret with Build scope is baked into the image if the build reads it. Rotating it requires a rebuild. A runtime secret can be applied and restarted without rebuilding.

  • Using ARG for a password and pushing the image.
  • Marking a build secret as Runtime and expecting it during docker build.
  • Leaving a blank secret in place instead of removing the variable.
  • Pasting a .env file without reviewing detected values.
  • Storing the same secret in three applications and rotating only one.
  • Assuming a masked value in the UI is absent from the container. Masking is a display boundary, not a runtime boundary.