CI/CD Integration
Keyway integrates seamlessly with CI/CD pipelines. This guide covers common platforms.
Authentication in CI/CD
Use a GitHub Fine-grained Personal Access Token for CI/CD:
- Go to GitHub Settings → Tokens
- Generate new token (fine-grained)
- Select repository access
- Required permissions:
Contents: Read - Store the token as a CI secret
GitHub Actions
Basic setup
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Keyway CLI
run: npm install -g @keywaysh/cli
- name: Pull secrets
run: keyway pull -e production -y
env:
KEYWAY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy
run: ./deploy.sh
Using GitHub token
GitHub Actions provides a GITHUB_TOKEN automatically. For public repos or repos where the workflow has access, this works directly:
- name: Pull secrets
run: keyway pull -e production -y
env:
KEYWAY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Using a PAT
For cross-repo access or more control, use a PAT:
- name: Pull secrets
run: keyway pull -e production -y
env:
KEYWAY_TOKEN: ${{ secrets.KEYWAY_PAT }}
Caching the CLI
Speed up workflows by caching:
- name: Cache Keyway CLI
uses: actions/cache@v4
with:
path: ~/.npm
key: keyway-cli-${{ runner.os }}
- name: Install Keyway CLI
run: npm install -g @keywaysh/cli
GitLab CI
stages:
- deploy
deploy:
stage: deploy
image: node:20
before_script:
- npm install -g @keywaysh/cli
script:
- keyway pull -e production -y
- ./deploy.sh
variables:
KEYWAY_TOKEN: $KEYWAY_PAT
Store KEYWAY_PAT in GitLab CI/CD Variables (Settings → CI/CD → Variables).
CircleCI
version: 2.1
jobs:
deploy:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run:
name: Install Keyway CLI
command: npm install -g @keywaysh/cli
- run:
name: Pull secrets
command: keyway pull -e production -y
environment:
KEYWAY_TOKEN: ${KEYWAY_PAT}
- run:
name: Deploy
command: ./deploy.sh
workflows:
deploy:
jobs:
- deploy
Store KEYWAY_PAT in CircleCI Environment Variables.
Jenkins
pipeline {
agent any
environment {
KEYWAY_TOKEN = credentials('keyway-pat')
}
stages {
stage('Setup') {
steps {
sh 'npm install -g @keywaysh/cli'
}
}
stage('Pull Secrets') {
steps {
sh 'keyway pull -e production -y'
}
}
stage('Deploy') {
steps {
sh './deploy.sh'
}
}
}
}
Docker builds
Build-time secrets
For Docker builds that need secrets:
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
# Secrets are pulled at build time
ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL
RUN npm run build
# GitHub Actions
- name: Pull secrets
run: keyway pull -e production -y -f .env.build
- name: Build Docker image
run: |
source .env.build
docker build \
--build-arg DATABASE_URL=$DATABASE_URL \
-t myapp:latest .
Runtime secrets
Better approach - pull secrets at runtime:
FROM node:20-alpine
WORKDIR /app
RUN npm install -g @keywaysh/cli
COPY package*.json ./
RUN npm ci
COPY . .
# Pull secrets at container start
CMD keyway pull -y && npm start
Vercel
Vercel has built-in environment variables, but you can sync from Keyway:
# GitHub Action to sync secrets to Vercel
- name: Pull from Keyway
run: keyway pull -e production -y
- name: Sync to Vercel
run: |
while IFS='=' read -r key value; do
vercel env add "$key" production <<< "$value"
done < .env
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
Best practices
1. Use environment-specific tokens
Create separate PATs for different environments:
KEYWAY_PAT_STAGING- access to staging onlyKEYWAY_PAT_PRODUCTION- access to production
2. Minimize secret exposure
Pull secrets only when needed:
# Good - secrets only in deploy job
jobs:
test:
# No secrets needed
deploy:
needs: test
steps:
- run: keyway pull -e production -y
3. Don't log secrets
Ensure your CI doesn't log secret values:
- name: Pull secrets
run: keyway pull -e production -y > /dev/null
4. Rotate CI tokens
Set calendar reminders to rotate CI/CD tokens periodically.
5. Use read-only access
CI/CD typically only needs to read secrets, not write them. Use read-only repository access for the PAT.