セキュアなJenkins認証情報管理のためのベストプラクティス
Jenkinsは継続的インテグレーションおよび継続的デリバリー(CI/CD)の中枢神経系として機能し、本番データベース、クラウドAPI、アーティファクトリポジトリ、セキュアなインフラストラクチャなどの機密性の高いリソースへのアクセスを必要とすることがよくあります。これらの操作に必要な秘密情報(パスワード、APIキー、プライベートSSHキー)を適切に管理することは、デプロイメントパイプラインのセキュリティと整合性を維持するために不可欠です。
パイプラインスクリプトに直接秘密情報をハードコーディングしたり、プレーンテキストで保存したりするような不適切な認証情報管理は、重大なセキュリティ脆弱性となります。このガイドでは、組み込みのJenkins Credentials Pluginを活用し、高度なセキュリティ制御を統合して、機密データが保護された状態を確保するための不可欠な戦略とアーキテクチャのベストプラクティスについて詳しく説明します。
基礎:Jenkins Credentials Plugin
Credentials Pluginは、Jenkinsが機密データを保存するために使用する標準的なメカニズムです。これは、認証情報を一元化された暗号化されたリポジトリとして提供し、秘密情報がビルドログ、ソースコントロール、または設定ファイルに公開されないようにします。
Jenkinsが認証情報を保存する際、Java Cryptography Extension(JCE)を使用して暗号化されます。この暗号化は、Jenkinsコントローラーに保存されている一意のmaster.keyファイルに紐付けられています。このアーキテクチャは、コントローラーファイルシステムへのアクセスが厳密に制御されなければならないことを意味します。
主要な認証情報タイプ
利用可能な認証情報タイプを理解することは、セキュアな実装への第一歩です。保存する秘密情報に最も正確にマッピングされるタイプを選択してください。
- Secret Text: APIトークン、アクセストークン、OAuthトークン、またはWebhookシークレットなどの汎用的な短いテキスト値に使用されます。
- Username and Password: Mavenリポジトリ、プライベートレジストリ(Docker Hub、Artifactory)、または内部アプリケーションなどのサービスに対する認証に使用される標準的なペアです。
- SSH Username with Private Key: リモートエージェントへのアクセス、プライベートGitリポジトリのクローン、またはリモートインフラストラクチャ上でのコマンド実行に不可欠です。プライベートキーは直接入力するか、パスとして提供するか、Jenkinsコントローラーで管理できます。
- Secret File: キーストア、証明書(
.pem、.crt)、または秘密情報を含む設定ファイルなど、機密性の高いファイル全体をアップロードするために使用されます。
ヒント: 常に可能な限り最も詳細な認証情報タイプを使用してください。たとえば、APIキーのみが必要な場合は、Username and Passwordフィールドに合わせようとするのではなく、Secret Textを使用してください。
最小権限の原則:認証情報のスコープ設定
認証情報のスコープは、Jenkins環境内でどこからアクセス可能かを決定します。最小権限の原則(ジョブに必要なアクセスのみを付与する)を適用することが重要です。
1. システムスコープ
システムスコープの認証情報(Manage Jenkins > Manage Credentials > Jenkinsの下に保存)は、Jenkinsインスタンス上のすべてのジョブ、フォルダー、およびパイプラインでグローバルに利用可能です。
- 使用法: グローバル設定プラグインが使用する認証情報や、すべてのエージェント接続に必要な秘密情報など、Jenkinsの操作全体で必要な秘密情報にのみシステムスコープを使用してください。
- 警告: システムスコープの使用は最小限にしてください。侵害されたジョブは、グローバルに利用可能なすべての秘密情報にアクセスできる可能性があります。
2. フォルダー(フォルダ)スコープ
フォルダー(フォルダ)スコープの認証情報は、特定のフォルダー(Folder pluginまたはOrganization foldersを使用して作成)内に定義されます。これらの秘密情報は、そのフォルダーおよびそのサブフォルダーに存在するジョブによってのみ表示され、使用できます。
- 推奨: 常にフォルダー(フォルダ)スコープを優先してください。 これにより、アクセスが区画化され、1つのプロジェクトが侵害された場合の被害範囲が制限されます。
Declarative Pipelineへのセキュアな注入
パイプラインスクリプトに認証情報をハードコーディングしたり、標準の環境変数を使用したりすることは、環境変数がログやシェルコマンドで容易に公開される可能性があるため、厳禁です。
Declarative Pipelineで認証情報に安全にアクセスするメソッドは、組み込みのwithCredentialsステップを使用することです。このステップは、指定された認証情報を、ブロックの実行中のみ利用可能なスコープ付き環境変数にロードします。
例1:Secret Text(APIトークン)の注入
この例では、Secret Text認証情報(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"
}
// 変数はこのブロックの外では利用できない
sh 'echo "Attempting to access token: ${SECRET_TOKEN}"'
// ^ これはnullまたは以前の環境値を出力します(意図しない公開を防ぐため)。
}
}
}
}
}
例2:Username and Passwordの注入
Username and Password認証情報を使用する場合、withCredentialsステップは秘密情報を2つの変数に分割します。通常は_USRと_PSW(またはカスタム名)でサフィックス付けされます。
pipeline {
agent any
stages {
stage('Login to Registry') {
steps {
withCredentials([usernamePassword(credentialsId: 'DOCKER_REGISTRY_CRED', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} my.registry.com"
}
}
}
}
}
セキュリティ警告:ログの抑制
Jenkinsは、標準のビルドログから認証情報値を自動的に抑制しようとします。ただし、これは単純な文字列マッチングに依存しています。
echoを使用して認証情報変数の値を出力しないでください。 デバッグのために変数内容を知る必要がある場合は、withCredentialsステップで提供されるマスクされた形式を使用し、問題解決後すぐにデバッグ出力を削除してください。
高度なセキュリティ統合
高セキュリティ環境では、ローカルのJenkinsマスターキーのみに依存することはしばしば不十分です。外部の秘密情報管理システムとの統合は、関心の分離、一元化された監査、および強化された暗号化機能を提供します。
外部認証情報ストア
一般的な統合には以下が含まれます。
- HashiCorp Vault: Vault Pluginを使用すると、Jenkinsは実行時にVaultから動的に秘密情報を要求できます。これは、秘密情報がJenkinsコントローラーに永続的に保存されず、実行フェーズ中にメモリに一時的にのみ保存されることを意味します。
- AWS Secrets Manager/Azure Key Vault: クラウドネイティブプラグインにより、パイプラインはIAMロールまたはサービスプリンシパルを使用してこれらのサービスから直接秘密情報を取得でき、静的認証情報の公開を最小限に抑えます。
外部ストアの使用は、以下の方法でセキュリティベストプラクティスに準拠します。
- ストレージの分離: 秘密情報インフラストラクチャはCI/CDサーバーから分離されます。
- 動的アクセス: 秘密情報は、Jenkinsの設定を手動で更新することなく、頻繁にローテーションできます。
- 強化された監査: すべての秘密情報アクセス試行は、外部Vaultシステム内に記録されます。
ロールベースアクセス制御(RBAC)
RBACプラグイン(Role-based Authorization Strategyなど)を実装すると、管理者はジョブを実行できるユーザーだけでなく、特定の認証情報を設定および表示できるユーザーも制御できます。
- 認証情報を使用する権限を付与するロールを定義します(例:
Job.UseCredentials)。 - システムレベルの認証情報を変更または作成する機能を、少数のセキュリティまたはプラットフォーム管理者に制限します。
認証情報管理ベストプラクティスの概要
| プラクティス | 説明 | セキュリティ上の利点 |
|---|---|---|
| フォルダー(フォルダ)スコープの使用 | 認証情報へのアクセスを、それらを必要とする特定のジョブ/フォルダーに制限します。 | 公開範囲と被害範囲を制限します。 |
| ハードコーディングの回避 | Jenkinsfile、ビルドスクリプト、またはソースコントロールに秘密情報を配置しないでください。 |
ソースコードの脆弱性を排除します。 |
withCredentialsの使用 |
公式Jenkins APIを使用して、パイプラインステップに秘密情報を安全に注入します。 | 自動ログのマスク処理と環境のクリーンアップを保証します。 |
| 外部Vaultの統合 | エンタープライズデプロイメントにはVault、AWS Secrets Manager、またはAzure Key Vaultを使用します。 | ストレージを分離し、動的なローテーションを可能にします。 |
| RBACの適用 | 認証情報の設定、表示、使用を制限する権限プラグインを使用します。 | ユーザー間の最小権限の原則を強制します。 |
| 定期的なローテーション | APIキーとパスワードを定期的にローテーションします(理想的には外部Vaultを介して自動化)。 | 侵害された秘密情報が悪用される可能性のある時間枠を最小限に抑えます。 |
| コントローラーの保護 | master.keyを保護するために、Jenkinsコントローラー上のファイルシステム権限を厳密に設定します。 |
コア暗号化メカニズムを保護します。 |
これらのベストプラクティスに従うことで、Jenkinsを潜在的なセキュリティの弱点から堅牢でセキュアな自動化エンジンに変え、CI/CDライフサイクル全体で機密データが責任を持って扱われることを保証します。