更新日:2026年8月7日

11分で読めます

GitLab Secrets ManagerがESO、Terraform、APIに対応

スタック全体の認証情報管理をシンプルに。GitLab Secrets Managerは External Secrets Operator(ESO)、Terraform、Secrets Manager APIに対応し、CI/CD以外の ワークフローからもシークレットを安全に取得できます。

CI/CDにはCI/CD用、KubernetesにはKubernetes用、Terraformにはまた別のシークレットストア。こうした分散した状態は、決して珍しくありません。ただ、増え続ける管理対象のツール、そしてアクセス制御の整合性を取り続ける負担。何か問題が起きたときには、ばらばらの監査証跡を突き合わせるところから始めることになります。

GitLab Secrets Managerが、External Secrets Operator(ESO)とTerraformに対応しました。CI/CDパイプラインの外側でも、安全にシークレットを取得できるようになります。OpenBaoを基盤とするGitLab Secrets Managerは、ソフトウェアデリバリーチェーン全体でシークレットの信頼できる唯一の情報源となる存在。1つのシークレットストアを、次のすべての用途で共有できます。

  • ESOを経由したKubernetesワークロード
  • TerraformまたはOpenTofuの実行
  • OpenBaoまたはVault CLI
  • GitLabのCI/CDジョブ(バージョン19.0以降)
  • Secrets Manager APIを利用した外部の自動化処理

Kubernetes:External Secrets Operator

ESOは、Vaultプロバイダーを介してGitLab Secrets Managerからシークレットを同期します。流れはシンプルです。クラスター内のワークロードが有効期間の短いJSON Web Token(JWT)を保持し、ESOがそれを使ってOpenBaoに認証。取得したシークレットは、Kubernetes Secretへ書き込まれます。

External Secrets Operator

SecretStoreは、「どこからシークレットを取得し、どう認証するか」をESOに伝えるためのリソースです。GitLab Secrets ManagerはVault互換のKV v2 APIを公開しているため、設定にはVaultプロバイダーを指定します。namespaceフィールドが対応するのはGitLabの階層(Organization、グループ、プロジェクト)で、このストアから参照できるシークレットの範囲を決めるもの。認証に使うのは、GitLabが発行しKubernetes Secretに格納したJWTです。secretRefから参照します。

      apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: gitlab-secrets-manager
  namespace: my-app
spec:
  provider:
    vault:
      server: https://secrets.gitlab.com      # provider.vault.server
      path: secrets/kv                        # provider.vault.path
      version: v2
      namespace: org_5/group_42/project_99    # provider.vault.namespace
      auth:
        jwt:
          path: api_jwt/cel                   # provider.vault.auth.jwt.path
          role: all_api                       # provider.vault.auth.jwt.role
          secretRef:
            name: gitlab-access-token         # Kubernetes secret holding the minted token
            key: token

    

ExternalSecretで定義するのは、「どのシークレットを取得し、どこに配置するか」です。先ほど作成したSecretStoreを参照し、リモートのシークレットをKubernetes Secretへマッピングします。あとはワークロードから、マウントまたは環境変数として参照するだけ。

ターゲットとなるシークレット(synced-secret)を作成し、管理するのはESOです。refreshIntervalで指定した間隔ごとにGitLabから再取得するため、値をローテーションしても再デプロイは不要。data配下の各エントリは、リモートのシークレット1つをターゲット側のキー1つに対応付けます。remoteRef.keyがGitLab Secrets Manager上のパス、propertyがそのシークレット内のフィールド、secretKeyがKubernetes側での格納先キーです。

      apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: my-secret
  namespace: my-app
spec:
  refreshInterval: 45m
  secretStoreRef:
    name: gitlab-secrets-manager
    kind: SecretStore
  target:
    name: synced-secret
  data:
    - secretKey: value
      remoteRef:
        key: explicit/<secret_name>           # <secrets_path>/<secret_name>
        property: value

    

GitLab Secrets ManagerとESOを実際に組み合わせる手順は、チュートリアルで紹介しています。

Infrastructure as Code:TerraformとOpenTofu

Terraformのstateや.tfvarsファイルは、認証情報の流出経路になりやすい場所です。シークレットがそのままディスクに書き出されたり、気づかないうちにバージョン管理へコミットされたりするためです。回避策となるのが、GitLabのシークレットをデータソースとして読み込む方法。planやapplyの実行時に発行したJWTで認証します。Terraformから直接参照する形にすれば、.tfvarsファイルにもCI/CD変数にも認証情報を残さずに済みます。

      data "external" "gitlab_secrets_token" {
  program = ["bash", "${path.module}/scripts/mint_token.sh"]

  query = {
    project_id = var.gitlab_project_id
  }
}

provider "vault" {
  address   = data.external.gitlab_secrets_token.result.server
  namespace = data.external.gitlab_secrets_token.result.namespace

  auth_login_jwt {
    mount = data.external.gitlab_secrets_token.result.auth_path
    role  = data.external.gitlab_secrets_token.result.role
    jwt   = data.external.gitlab_secrets_token.result.jwt
  }
}

data "vault_kv_secret_v2" "my_secret" {
  mount = data.external.gitlab_secrets_token.result.mount
  name  = "${data.external.gitlab_secrets_token.result.secrets_path}/<secret_name>"
}

output "secret_value" {
  value     = data.vault_kv_secret_v2.my_secret.data["value"]
  sensitive = true
}

    

Terraformでシークレットを読み取る方法は、ドキュメントで詳しく解説しています。

コマンドライン:OpenBaoまたはVault CLI

すべてのワークフローがAPIを直接呼び出すわけではありません。Vault互換のツールを前提にスクリプトを組んでいるチームなら、OpenBaoまたはVault CLIがそのまま使えます。手順はVaultから読み取るときと同じ。GitLab Secrets Managerのシークレットをそのまま取得できます。

      export VAULT_ADDR="<server>"
export VAULT_NAMESPACE="<namespace>"

# Exchange the minted JWT for an OpenBao token, then export it.
vault write "auth/<auth_jwt_path>/login" role=<role> jwt=<token>
export VAULT_TOKEN="<client_token>"

# Read the secret value.
vault kv get -mount=<path> "<secrets_path>/<secret_name>"

    

Secrets Manager APIを使うケース

GitLab CI/CD、Kubernetes、Terraformのどれにも当てはまらない自動化には、Secrets Manager APIという選択肢があります。認証情報をハードコーディングしたり、変数ファイルを別途用意したりしなくても、任意の外部システムからSecrets Managerのシークレットを取得できます。

      # Request JWT token using Service Account
RESPONSE=$(curl --silent --request POST \
  --header "PRIVATE-TOKEN: <your_access_token>" \
  --url "https://gitlab.example.com/api/v4/projects/<project_id>/secrets_manager/access_token")

SERVER=$(echo "$RESPONSE" | jq --raw-output .provider.vault.server)
NAMESPACE=$(echo "$RESPONSE" | jq --raw-output .provider.vault.namespace)
MOUNT=$(echo "$RESPONSE" | jq --raw-output .provider.vault.path)
SECRETS_PATH=$(echo "$RESPONSE" | jq --raw-output .provider.vault.secrets_path)
AUTH_PATH=$(echo "$RESPONSE" | jq --raw-output .provider.vault.auth.jwt.path)
ROLE=$(echo "$RESPONSE" | jq --raw-output .provider.vault.auth.jwt.role)
JWT=$(echo "$RESPONSE" | jq --raw-output .provider.vault.auth.jwt.token)

# Exchange the JWT for a short-lived OpenBao token.
VAULT_TOKEN=$(curl --silent --request POST \
  --header "X-Vault-Namespace: $NAMESPACE" \
  --data "{\"role\":\"$ROLE\",\"jwt\":\"$JWT\"}" \
  "$SERVER/v1/auth/$AUTH_PATH/login" | jq --raw-output .auth.client_token)

# Read the secret value.
curl --silent \
  --header "X-Vault-Token: $VAULT_TOKEN" \
  --header "X-Vault-Namespace: $NAMESPACE" \
  "$SERVER/v1/$MOUNT/data/$SECRETS_PATH/<secret_name>"

    

始めるには

GitLab Secrets Managerは、PremiumおよびUltimateのお客様向けにパブリックベータとして提供中です。ESO、Terraform、APIによるシークレットへのアクセスに対応しているのは、現時点でGitLab.comとGitLab Self-Managed。GitLab Dedicatedへの対応も近日中を予定しています。

ベータ期間中は無料でご利用いただけます。一般提供の開始後は、GitLabクレジットによる課金対象の有料機能となる予定。課金が始まる前にはオプトインが必要で、事前にご案内します。

まずはドキュメントをご覧ください。足りない点やご要望があれば、こちらのイシューへお寄せください。一般提供に向けて、フィードバックを集めています。

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成してあなたの声を届けましょう。

フィードバックを共有する

今すぐ開発をスピードアップ

DevSecOpsに特化したインテリジェントオーケストレーションプラットフォームで実現できることをご確認ください。