Learn Secret Management - Integrating OpenBao in CI/CD Pipelines
Episode 13 of 21

Learn Secret Management - Integrating OpenBao in CI/CD Pipelines

Removing long-lived secrets from CI/CD: fetching temporary credentials via OIDC or AppRole in GitHub Actions, and the native GitLab CI integration with the secrets keyword in .gitlab-ci.yml.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 12 you connected OpenBao to Kubernetes via ServiceAccount auth and the sidecar injector. Episode 13 moves to the pipeline world: you will see how OpenBao keeps CI/CD free of permanent API keys, by fetching temporary credentials every time a pipeline runs. The two platforms covered are GitHub Actions and GitLab CI/CD.

The Long-Lived Secrets Problem in CI/CD

Often repositories store API keys in Repository Secrets or variables — those values persist for a long time, are shared across all jobs, and one leak has a big impact. Not to mention the annoying rotation: change one key, and all configurations must be changed along with it.

A better way is to eliminate those permanent credentials altogether. The pipeline only stores the information on how to fetch credentials, not the credentials themselves. When a job runs, the pipeline requests a temporary token from OpenBao, uses that token for the duration of the job, and then the token expires on its own.

AspectLong-Lived SecretsDynamic Secrets
Credential lifetimeMonths to yearsMinutes to hours
RotationManual and easy to missAutomatic via TTL
Leak impactVery largeLimited and soon expired

Integration with GitHub Actions

GitHub Actions has two ways to use OpenBao: OIDC for trust-based authentication between GitHub and OpenBao, or AppRole for a more classic approach.

OIDC Federation

With OIDC, GitHub issues a token containing claims about the repository, environment, and ref that runs the job. OpenBao accepts that token after verifying its signature. No secret needs to be stored in the repository at all — the pipeline's own identity is the credential.

AppRole as an Alternative

If OIDC is not yet possible, AppRole remains a legitimate choice. The job uses role_id and secret_id to log in; secret_id should be one-time-use and short-lived, so even if it leaks, the value is useless outside that pipeline.

Example Workflow

The hashicorp/vault-action action, known as vault-action, is compatible with OpenBao because their APIs are equivalent. Example workflow that fetches credentials before running a job:

GitHub Actions with OpenBao
name: deploy
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Ambil kredensial dari OpenBao
        uses: hashicorp/vault-action@v6
        with:
          url: https://bao.internal.example.com
          method: approle
          roleId: ${{ secrets.OPENBAO_ROLE_ID }}
          secretId: ${{ secrets.OPENBAO_SECRET_ID }}
          exportToken: true
          secrets: secret/data/app db_password | DB_PASSWORD
      - name: Jalankan deploy
        run: ./deploy.sh
        env:
          DB_PASSWORD: ${{ env.DB_PASSWORD }}

Note that only role_id and secret_id are stored in the repository, not the real database password. The actual value is fetched when the job runs and only lives within that job's environment. For OIDC, replace the with block with a method: jwt configuration plus a jwt_oidc_audience matching the OpenBao role.

Integration with GitLab CI/CD

GitLab offers a native integration via the secrets: keyword in .gitlab-ci.yml. The GitLab Runner contacts the OpenBao server, logs in according to the designated role, fetches the value, then injects it as an environment variable into the job.

The secrets Keyword Syntax

OpenBao integration in .gitlab-ci.yml
vault:
  variables:
    VAULT_SERVER_URL: https://bao.internal.example.com
    VAULT_AUTH_METHOD: approle
    VAULT_ROLE_ID: $OPENBAO_ROLE_ID
    VAULT_SECRET_ID: $OPENBAO_SECRET_ID
 
deploy:
  stage: deploy
  secrets:
    DB_PASSWORD:
      vault: secret/data/app/db_password@secret
  script:
    - ./deploy.sh

The VAULT_SERVER_URL, VAULT_AUTH_METHOD, VAULT_ROLE_ID, and VAULT_SECRET_ID variables tell the Runner where and how to log in. The secrets: keyword then maps the secret value to the DB_PASSWORD environment variable before the script runs.

Advantages of Native Integration

The advantage is that the integration happens at the Runner level — secrets are injected before the script runs, so the script itself does not need to know where the value came from. This also means secrets are not visible in the log output.

Note

CI/CD credentials are best fetched as dynamic secrets. For databases, use the database engine that issues a unique user with a TTL — not a static secret — so that role_id and secret_id are only the entrance, not the secret content itself.

GitHub Actions vs GitLab CI

AspectGitHub ActionsGitLab CI/CD
Mechanismhashicorp/vault-action actionNative secrets: keyword
AuthenticationOIDC or AppRoleOIDC, JWT, or AppRole
Secret injectionEnvironment variable on the stepEnvironment variable before the script
ConfigurationDone per action stepKeyword in .gitlab-ci.yml
Server configVia the action's with blockVAULT_SERVER_URL variable

Choose the platform that fits your ecosystem; the same principle applies: store only how to fetch credentials, let OpenBao issue the values when needed.

Conclusion

In this episode 13, you understood the danger of long-lived secrets in CI/CD, GitHub Actions integration via the hashicorp/vault-action action with OIDC or AppRole, and the native GitLab CI integration using the secrets: keyword in .gitlab-ci.yml.

Key takeaways:

  • The repository only stores credential-fetching information, not the credentials themselves.
  • Dynamic secrets use TTLs so pipeline credentials expire on their own.
  • OIDC eliminates stored secrets; AppRole remains useful as a fallback.
  • GitLab secrets: injects values before the script runs, without touching the logs.

In the next episode, episode 14, we automate infrastructure: integrating OpenBao with OpenTofu or Terraform and Ansible to fetch dynamic database credentials and PKI certificates during provisioning.

Learn Secret Management - Integrating OpenBao in CI/CD Pipelines | Learn Secret Management with OpenBao