iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Environments

Environment variables in CI fall into three tiers: public (commit messages, branch names), team-visible (build matrix, feature flags), and secret (API keys, OIDC tokens). Treat each tier differently: log the first, surface the second in logs sparingly, and never echo the third — most providers will redact known secret values from logs, but the safe move is not to print them at all.

Layered env vars + OIDC for cloud auth (GitHub Actions)

EXAMPLE
# .github/workflows/deploy.yml
name: deploy

on:
  push:
    branches: [main]

permissions:
  id-token: write          # required for OIDC to AWS
  contents: read

env:
  # Repo-level defaults visible to every job
  APP_NAME: shop-api
  AWS_REGION: ap-southeast-2

jobs:
  build:
    runs-on: ubuntu-latest
    environment: production   # uses 'production' Environment secrets/vars + approvals

    env:
      # Job-level — wins over workflow-level
      NODE_ENV: production

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with: { node-version: '20' }

      - name: Install
        run: npm ci

      - name: Run tests with public env
        run: npm test
        env:
          # Step-level — wins over job-level
          CI: 'true'
          TEST_DB_URL: ${{ vars.TEST_DB_URL }}   # Variables (visible in logs)

      # OIDC to AWS — no static keys, short-lived credentials
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Deploy
        env:
          # Secrets are masked in logs and decrypted at use time
          STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }}
        run: ./scripts/deploy.sh

      - name: Print safe diagnostics
        run: |
          echo "App:    $APP_NAME"
          echo "Region: $AWS_REGION"
          # NEVER:  echo "$STRIPE_API_KEY"

# --- Equivalent shapes in other providers ---
# GitLab CI:   variables: at job/global; protected & masked flags per variable
# CircleCI:    Project Env Vars or Contexts; --env-file for local
# Jenkins:     credentials() binding inside withCredentials block

Why it matters

Move from static keys to OIDC wherever the target supports it (AWS, GCP, Azure, Vault, Cloudflare). Static secrets in CI are a long-lived liability that survive employee turnover and laptop theft; OIDC issues a token that expires before the job ends.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
environment:
    name: production
    url: https://app.example.com
# Requires reviewer approval to deploy; secrets are scoped to the env.
Try it Yourself »

Discussion

Loading…