GitLab CI/CD - Manual Setup
Manually configure GitLab CI/CD with SikkerKey secrets.
For a faster setup experience, use the automated setup which handles everything from the dashboard.
Pipeline Configuration
stages:
- secrets
- build
sikkerkey:
stage: secrets
image: node:20
script:
- npm install -g sikkerkey 2>/dev/null
- VAULT_DIR="$HOME/.sikkerkey/vaults/$SIKKERKEY_VAULT_ID"
- mkdir -p "$VAULT_DIR"
- chmod 700 "$HOME/.sikkerkey" "$HOME/.sikkerkey/vaults" "$VAULT_DIR"
- cp "$SIKKERKEY_PRIVATE_KEY" "$VAULT_DIR/private.pem"
- chmod 600 "$VAULT_DIR/private.pem"
- printf '{"machineId":"%s","machineName":"gitlab-ci","vaultId":"%s","apiUrl":"https://api.sikkerkey.com","privateKeyPath":"%s/private.pem"}' "$SIKKERKEY_MACHINE_ID" "$SIKKERKEY_VAULT_ID" "$VAULT_DIR" > "$VAULT_DIR/identity.json"
- chmod 600 "$VAULT_DIR/identity.json"
- sikkerkey connect $SIKKERKEY_VAULT_ID
- sikkerkey unlock $SIKKERKEY_PROJECT_ID
- sikkerkey export --project $SIKKERKEY_PROJECT_ID > sikkerkey.env
artifacts:
reports:
dotenv: sikkerkey.env
build:
stage: build
needs: [sikkerkey]
script:
- echo "Secrets are available as environment variables"
The sikkerkey stage installs the CLI, configures the machine identity, fetches secrets, and exports them as a dotenv artifact. All downstream jobs in later stages receive the secrets as environment variables automatically.
Setup
1. Bootstrap a CI machine
From the dashboard, go to Machines and click + Validate. Select the CI/CD tab and run the command:
curl -sSL https://api.sikkerkey.com/v1/bootstrap/YOUR_TOKEN/ci | sh
This generates a keypair locally, registers the public key with SikkerKey, and prints the credentials:
SIKKERKEY_VAULT_ID=vault_abc123
SIKKERKEY_MACHINE_ID=9daae125-1f61-4eca-bde6-70aaa40db018
SIKKERKEY_PRIVATE_KEY:
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIHN...
-----END PRIVATE KEY-----
2. Add CI/CD variables
In your GitLab project, go to Settings > CI/CD > Variables and add:
| Variable | Type | Masked | Value |
|---|---|---|---|
SIKKERKEY_VAULT_ID | Variable | Yes | The vault ID from the output |
SIKKERKEY_PROJECT_ID | Variable | Yes | Your project ID (from the dashboard sidebar) |
SIKKERKEY_MACHINE_ID | Variable | Yes | The machine ID from the output |
SIKKERKEY_PRIVATE_KEY | File | No | The full PEM private key including headers |
Set the private key as a File type variable. Set Visibility to Visible -- masked variables cannot contain whitespace, and PEM keys contain newlines. File type variables write the content to a temporary file, so the key never appears in job logs.
3. Approve and grant access
The machine appears as pending in the dashboard. Approve it, add it to your project, and grant it access to the secrets your pipeline needs.
Examples
Inject and run
deploy:
image: node:20
script:
# ... CLI install + identity setup ...
- sikkerkey run --all -- ./deploy.sh
Fetch individual secrets
deploy:
script:
# ... CLI install + identity setup ...
- export DB_PASSWORD=$(sikkerkey get sk_db_prod password)
- export API_KEY=$(sikkerkey get sk_api_key)
- ./deploy.sh
Reusable template
Create a template in your group for reuse across projects:
# .gitlab/ci/sikkerkey.yml
.sikkerkey-setup:
image: node:20
before_script:
- npm install -g sikkerkey 2>/dev/null
- VAULT_DIR="$HOME/.sikkerkey/vaults/$SIKKERKEY_VAULT_ID"
- mkdir -p "$VAULT_DIR"
- chmod 700 "$HOME/.sikkerkey" "$HOME/.sikkerkey/vaults" "$VAULT_DIR"
- cp "$SIKKERKEY_PRIVATE_KEY" "$VAULT_DIR/private.pem"
- chmod 600 "$VAULT_DIR/private.pem"
- printf '{"machineId":"%s","machineName":"gitlab-ci","vaultId":"%s","apiUrl":"https://api.sikkerkey.com","privateKeyPath":"%s/private.pem"}' "$SIKKERKEY_MACHINE_ID" "$SIKKERKEY_VAULT_ID" "$VAULT_DIR" > "$VAULT_DIR/identity.json"
- chmod 600 "$VAULT_DIR/identity.json"
- sikkerkey connect $SIKKERKEY_VAULT_ID
- sikkerkey unlock $SIKKERKEY_PROJECT_ID
Then use it:
include:
- local: .gitlab/ci/sikkerkey.yml
deploy:
extends: .sikkerkey-setup
script:
- sikkerkey run --all -- ./deploy.sh
Security Notes
- The private key is stored as a file type CI/CD variable and never printed to logs
- The identity is created in the runner's home directory and discarded when the job ends
- Every secret read is authenticated with Ed25519 signatures and recorded in the SikkerKey audit log
- Each pipeline run uses the same machine identity, so all reads are logged with the same machine ID