GitLab CI/CD
Bootstrap an ephemeral machine inside your GitLab CI/CD pipeline and pull SikkerKey secrets as environment variables at runtime.
SikkerKey integrates with GitLab CI/CD through a pipeline-time bootstrap. The dashboard generates a shell script and a .gitlab-ci.yml snippet that you commit to your repository. At runtime, the script registers an ephemeral machine bound to an enrollment token's policy, fetches the granted secrets, and exposes them as environment variables for subsequent pipeline jobs and steps.
Prerequisites
- An enrollment token scoped to the projects and secrets your pipeline needs
- Maintainer access to the target GitLab project (required to add CI/CD variables)
- A runner image with
curlandnpmavailable
1. Add the enrollment token to GitLab
Copy the enrollment token plaintext. The plaintext is shown only once at creation; if you've lost it, revoke the token and create a new one.
In your GitLab project:
Settings → CI/CD → Variables → Add variable
Set the key to SIKKERKEY_ENROLLMENT_TOKEN and paste the plaintext as the value. Mark the variable as Masked and Protected so it appears redacted in job logs and is only injected into protected pipelines.
2. Generate the bootstrap script
In the SikkerKey dashboard, go to Integrations and click Build on the GitLab CI/CD row. Paste the same enrollment token plaintext into the modal. SikkerKey verifies it server-side and renders two files:
sikkerkey-init.sh: the bootstrap script. Commit it at the root of your repository..gitlab-ci.ymlsnippet: the pipeline configuration. Paste the relevant pieces into your existing.gitlab-ci.yml(or create a new one).
3. Use it in your pipeline
The full shape of a job that uses SikkerKey looks like this:
deploy:
image: ubuntu:latest
before_script:
- apt-get update && apt-get install -y curl
- sh ./sikkerkey-init.sh
script:
- ./your-deploy-command.sh
SIKKERKEY_ENROLLMENT_TOKEN is injected automatically by GitLab from the CI/CD variable you added above. After before_script runs, every command in the same job sees the granted secrets as environment variables.
What happens at runtime
- The script reads
SIKKERKEY_ENROLLMENT_TOKENfrom the job environment. - It calls the SikkerKey enrollment endpoint, which generates a one-time Ed25519 keypair on the runner and registers an ephemeral machine bound to the token's policy.
- It installs the SikkerKey CLI via npm.
- It unlocks each project the token grants.
- It exports the granted secrets and prepends them to the job's environment for the remainder of the job.
Multiple jobs
Each GitLab CI/CD job runs on a fresh runner. If you have multiple jobs that need secrets, add the bootstrap step to each. Every job produces its own ephemeral machine that disappears when the runner is torn down.
Security model
- Scoped token. The enrollment token can only register machines bound to its configured policy: projects, secrets, source CIDR, hostname pattern, machine TTL, and max uses. It cannot read secrets directly.
- Ephemeral machine. Each pipeline job produces a unique machine identity, generated on the runner. The private key lives only in the runner's filesystem and is gone when the runner is torn down.
- Hash-only storage. SikkerKey stores only the SHA-256 hash of the enrollment token. The plaintext lives in GitLab's encrypted CI/CD variable store and is never sent back to you through SikkerKey.
- Audit trail. Every enrollment, every secret read, and every machine action is recorded in your audit log, attributed to the parent token along with the runner's IP and timestamp.
Troubleshooting
./sikkerkey-init.sh: Permission denied. The committed script doesn't have the execute bit. The generated snippet invokes the script via sh ./sikkerkey-init.sh, which doesn't require it. If you've modified the snippet to drop the sh prefix, restore it.
Enrollment token not found (404). The plaintext you pasted into the dashboard modal doesn't match any token in your account. The plaintext is shown only once at creation. If you've lost it, revoke the token and create a new one.
Token has been revoked / expired / no remaining enrollments (410). The token can no longer enroll machines. Create a new token from Enrollment Tokens, regenerate the script, replace the SIKKERKEY_ENROLLMENT_TOKEN value in your CI/CD variables, and re-run the pipeline.
Variable not visible to the script. The CI/CD variable is set to Protected but the pipeline is running on a non-protected branch. Either un-protect the variable or run the pipeline on a protected branch.