安全なJenkins認証情報管理のベストプラクティス

Credentials Plugin、フォルダスコープ、withCredentials、RBAC、ローテーション、外部ボールトを使用してJenkinsのシークレットを安全に保存します。

安全なJenkins認証情報管理のベストプラクティス

Jenkinsジョブは、クラウドトークン、レジストリパスワード、デプロイキー、署名証明書、API認証情報など、本番環境に近いシークレットを必要とすることがよくあります。これらのシークレットがJenkinsfile、コンソールログ、またはジョブパラメータに漏洩すると、CI/CDシステムが侵害への直接的な経路となります。\n Credentials Pluginを使用し、認証情報のスコープを狭く保ち、必要なステップにのみ注入します。

基本:Jenkins Credentials Plugin

Credentials Pluginは、Jenkinsが機密データを保存するために使用する標準的なメカニズムです。これは、認証情報の集中管理された暗号化リポジトリを提供し、シークレットがビルドログ、ソース管理、または設定ファイルに公開されないようにします。

Jenkinsが認証情報を保存するとき、JENKINS_HOME/secrets以下のファイルを含むJenkinsコントローラ上のキーマテリアルを使用して暗号化します。コントローラのファイルシステムとJenkins設定への広範なアクセス権を持つ者は誰でもシークレットを回復できる可能性があるため、ファイルシステムと管理者アクセスは厳密に制御する必要があります。

主要な認証情報タイプ

利用可能な認証情報タイプを理解することは、安全な実装への第一歩です。保存するシークレットに最も正確にマッピングするタイプを選択してください:

  1. シークレットテキスト: APIトークン、アクセスキー、OAuthトークン、Webhookシークレットなど、汎用的な短いテキスト値に使用します。
  2. ユーザー名とパスワード: Mavenリポジトリ、プライベートレジストリ(Docker Hub、Artifactory)、または内部アプリケーションなどのサービスに対する認証に使用される標準的なペアです。
  3. 秘密鍵付きSSHユーザー名: リモートエージェントへのアクセス、プライベートGitリポジトリのクローン、またはリモートインフラストラクチャでのコマンド実行に不可欠です。秘密鍵は直接入力するか、パスとして提供するか、Jenkinsコントローラによって管理できます。
  4. シークレットファイル: キーストア、証明書(.pem.crt)、またはシークレットを含む設定ファイルなど、機密性の高いファイル全体をアップロードするために使用します。

ヒント: 可能な限り最も細かい認証情報タイプを常に使用してください。たとえば、APIキーのみが必要な場合は、ユーザー名とパスワードフィールドに無理に適合させようとするのではなく、シークレットテキストを使用してください。

最小権限の原則:認証情報のスコープ設定

認証情報スコープは、Jenkins環境内でそれらがアクセス可能な場所を決定します。ジョブに必要なアクセスのみを許可する最小権限の原則を適用することが重要です。

1. システムスコープ

システムスコープの認証情報(Jenkinsの管理 > 認証情報の管理 > Jenkins に保存)は、Jenkinsインスタンス上のすべてのジョブ、フォルダ、パイプラインでグローバルに利用可能です。

  • 使用法: システムスコープは、Jenkins全体の運用に必要なシークレット(グローバル設定プラグインで使用される認証情報や、すべてのエージェント接続に必要なシークレットなど)にのみ使用します。
  • 警告: システムスコープの使用を最小限に抑えてください。侵害されたジョブは、グローバルに利用可能なすべての認証情報にアクセスできる可能性があります。

2. フォルダスコープ

フォルダスコープの認証情報は、特定のフォルダ内(FolderプラグインまたはOrganizationフォルダを使用して作成)で定義されます。これらのシークレットは、そのフォルダおよびそのサブフォルダ内にあるジョブのみが表示および使用できます。

  • 推奨事項: 常にフォルダスコープを優先してください。 これによりアクセスが区分化され、1つのプロジェクトが侵害された場合の影響範囲が制限されます。

宣言的パイプラインへの安全な注入

パイプラインスクリプトに認証情報をハードコードしないでください。環境変数は、Jenkinsが狭いブロックに対して注入し、既知のシークレット値をログでマスクする場合にのみ許容されます。

宣言的パイプラインで認証情報にアクセスする安全な方法は、組み込みのwithCredentialsステップを使用することです。このステップは、指定された認証情報を、ブロックの実行中にのみ利用可能なスコープ付き環境変数にロードします。

例1:シークレットテキスト(APIトークン)の注入

この例では、シークレットテキスト認証情報(MY_API_TOKEN)を安全に取得し、その値を内部変数SECRET_TOKENに割り当てます。withCredentialsブロックが終了すると、SECRET_TOKENは自動的に環境から削除されます。

pipeline {
    agent any
    stages {
        stage('Deploy via API') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'MY_API_TOKEN', variable: 'SECRET_TOKEN')]) {
                        sh "echo 'Calling external API...'"
                        sh '''
                            curl -X POST \
                              -H "Authorization: Bearer $SECRET_TOKEN" \
                              https://api.mycorp.com/deploy
                        '''
                    }
                }
            }
        }
    }
}

例2:ユーザー名とパスワードの注入

ユーザー名とパスワードの認証情報を使用する場合、withCredentialsステップはシークレットを2つの変数に分割します。1つはユーザー名用、もう1つはパスワード用で、通常は_USR_PSW(またはカスタム名)が接尾辞として付加されます。

pipeline {
    agent any
    stages {
        stage('Login to Registry') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'DOCKER_REGISTRY_CRED', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
                    sh '''
                        printf '%s' "$DOCKER_PASS" | docker login \
                          --username "$DOCKER_USER" \
                          --password-stdin my.registry.com
                    '''
                }
            }
        }
    }
}

セキュリティ警告:ログ抑制

Jenkinsは既知の認証情報値をビルドログでマスクしようとしますが、マスキングは注意深いスクリプトの代わりにはなりません。シークレットを印刷したり、コマンドラインでパスワードを渡したり、シークレット使用時にシェルトレース(set -x)を実行したりしないでください。

高度なセキュリティ統合

セキュリティ要件の高い環境では、ローカルのJenkinsマスターキーのみに依存することは不十分な場合がよくあります。外部シークレット管理システムとの統合により、関心事の分離、集中監査、および強化された暗号化機能が提供されます。

外部認証情報ストア

一般的な統合は次のとおりです:

  • HashiCorp Vault: Vaultプラグインを使用すると、Jenkinsは実行時にVaultから動的にシークレットを要求できます。つまり、シークレットはJenkinsコントローラに永続的に保存されることはなく、実行フェーズ中にのみメモリに一時的に存在します。
  • AWS Secrets Manager/Azure Key Vault: クラウドネイティブプラグインを使用すると、パイプラインはIAMロールまたはサービスプリンシパルを使用してこれらのサービスから直接シークレットを取得できるため、静的認証情報の露出を最小限に抑えられます。

外部ストアを使用することは、セキュリティのベストプラクティスに沿っています:

  1. ストレージの分離: シークレットインフラストラクチャがCI/CDサーバーから切り離されます。
  2. 動的アクセス: 手動でJenkins設定を更新することなく、シークレットを頻繁にローテーションできます。
  3. 監査の強化: すべてのシークレットアクセス試行が外部ボールトシステム内に記録されます。

ロールベースのアクセス制御(RBAC)

RBACプラグイン(ロールベースの認可戦略など)を実装すると、管理者はジョブを実行できるユーザーだけでなく、特定の認証情報を設定および表示できるユーザーも制御できます。

  • 信頼できるユーザーのみがパイプラインで認証情報をバインドできるように、ジョブ設定権限を制限します。
  • システムレベルの認証情報を変更または作成する機能を、セキュリティ管理者またはプラットフォーム管理者の少数のグループに制限します。

認証情報管理のベストプラクティス

プラクティス 説明 セキュリティ上の利点
フォルダスコープを使用 認証情報へのアクセスを、それらを必要とする特定のジョブ/フォルダに制限します。 露出と影響範囲を制限します。
ハードコーディングを避ける Jenkinsfile、ビルドスクリプット、またはソース管理にシークレットを決して配置しないでください。 ソースコードの脆弱性を排除します。
withCredentialsを使用 公式のJenkins APIを使用して、パイプラインステップにシークレットを安全に注入します。 自動ログ編集と環境クリーンアップを保証します。
外部ボールトを統合 エンタープライズデプロイメントには、Vault、AWS Secrets Manager、またはAzure Key Vaultを使用します。 ストレージを切り離し、動的ローテーションを可能にします。
RBACを適用 認証情報を設定、表示、使用できるユーザーを制限するために、認可プラグインを使用します。 ユーザー間で最小権限の原則を強制します。
定期的なローテーション APIキーとパスワードを定期的にローテーションします(理想的には外部ボールトを介して自動化)。 侵害されたシークレットが悪用される時間枠を最小限に抑えます。
コントローラを保護 master.keyを保護するために、Jenkinsコントローラに厳格なファイルシステム権限を設定します。 コア暗号化メカニズムを保護します。

Jenkins認証情報を本番環境のシークレットとして扱ってください。スコープを厳密に設定し、短時間だけバインドし、定期的にローテーションし、コントローラへのアクセスをそれらのシークレットを回復できる人に限定してください。