DevOps

CI/CD Secrets Management: Securing GitHub Actions & GitLab CI

How to securely manage secrets in GitHub Actions, GitLab CI, and Jenkins. Prevent credential exposure in CI/CD pipelines.

OM Salunke
February 25, 2026
9 min read
Keywords:
ci cd secrets managementgithub secrets managementgithub actions secretsgitlab ci secretsjenkins secrets management

CI/CD Secrets Management: Securing GitHub Actions & GitLab CI

Your CI/CD pipeline is the nervous system of your application. If secrets leak here, your entire infrastructure is compromised.

Yet many teams handle secrets carelessly in GitHub Actions, GitLab CI, and Jenkins.

The CI/CD Secrets Problem

When you push code, your CI/CD pipeline springs into action:

  1. Clone repository
  2. Install dependencies
  3. Run tests
  4. Build application
  5. Deploy to production

At each step, secrets are needed. And at each step, they're exposed to logs, artifacts, and environment variables.

GitHub Actions Secrets: The Right Way

Creating Secrets in GitHub

  1. Go to Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Add your secret (API_KEY, DATABASE_PASSWORD, etc.)

Accessing Secrets in Workflows

name: Deploy

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Deploy to production
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          API_KEY: ${{ secrets.API_KEY }}
        run: npm run deploy

Never Log Secrets

āœ… Good:

- name: Connect to database
  env:
    PASSWORD: ${{ secrets.DB_PASSWORD }}
  run: npm run migrate  # Password not logged

āŒ Bad:

- name: Test
  run: echo "Password is: ${{ secrets.DB_PASSWORD }}"  # 🚨 EXPOSED

GitHub Actions Best Practices

  1. Use organization secrets for shared secrets
  2. Rotate secrets every 30 days
  3. Audit secret access logs
  4. Mask secret values in logs automatically (GitHub does this)
  5. Limit branch access to production secrets

GitLab CI Secrets

GitLab calls them "CI/CD Variables":

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - export DATABASE_URL=$DB_URL
    - npm run deploy
  only:
    - main

Jenkins Secrets

In Jenkins, use the Credentials Plugin:

pipeline {
  agent any
  
  environment {
    API_KEY = credentials('api-key-prod')
  }
  
  stages {
    stage('Deploy') {
      steps {
        sh '''
          export API_KEY=${API_KEY}
          npm run deploy
        '''
      }
    }
  }
}

Advanced: Integration with XtraSecurity

For enterprise CI/CD, integrate XtraSecurity:

name: Deploy with XtraSecurity

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Fetch secrets
        run: |
          npm install @xtrasecurity/sdk
          node fetch-secrets.js
      
      - name: Deploy
        run: npm run deploy

Common CI/CD Secret Mistakes

āŒ Storing secrets in code āŒ Committing .env files āŒ Using weak credentials āŒ No secret rotation āŒ Storing secrets in artifacts āŒ No audit logs

Conclusion

CI/CD pipelines should never expose secrets in logs, artifacts, or environment variables.

About the Author

OM Salunke is a security engineer with expertise in DevOps, cloud infrastructure, and secrets management. He has helped enterprise teams secure their infrastructure on AWS, Google Cloud, and Azure.