安全なシークレット管理と環境変数
Secrets Manager(Vault、AWS Secrets Manager)と実行時の環境変数注入を使用し、ソースコードへのシークレットのハードコードを避けます。
「安全なシークレット管理と環境変数」はCoddyKit上の無料Cloud & IT Cert Prepレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCloud & IT Cert Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Cloud & IT Cert Prepコースには全4レッスンが含まれています。
ハードコードされたシークレットの問題
ハードコードされたシークレット(ソースコードに直接埋め込まれたAPIキー、データベースパスワード、TLS秘密鍵、OAuthトークン)は、最も一般的で防止しやすいセキュリティ脆弱性の1つです。ソースコード内のシークレットは、削除した後もバージョン管理の履歴に残り、リポジトリへのアクセス権を持つすべての開発者から見える状態になり、リポジトリを誤って公開した際に頻繁に漏えいします。GitGuardianやtruffleHogなどのツールは、GitHubなどのプラットフォーム上で漏えいしたシークレットを継続的にスキャンします。
# DANGEROUS: hardcoded secret in source code
# db_password = 'P@ssw0rd#2026'
# api_key = 'sk-live-abc123xyz789'
# aws_secret = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
# These secrets are now:
# - In git history (even if later deleted)
# - Visible to all repo contributors
# - Potentially in CI/CD logs
# - Often leaked when repos go public accidentally環境変数:改善されるが十分ではない
環境変数を使用すると、ホストOSやコンテナオーケストレーターを通じて実行時にシークレットを注入できるため、ソースコードからシークレットを取り除けます。アプリケーションは、ハードコードされた値ではなくos.environ['DB_PASSWORD']を読み取ります。ハードコードよりは安全ですが、環境変数には弱点があります。プロセス一覧に表示され、子プロセスに継承され、クラッシュダンプやデバッグログに残ることが多く、ローテーションも手動で行う必要があります。開発環境には適していますが、本番環境のシークレット管理として単独で十分とはいえません。
# Environment variable pattern:
# In .env file (NEVER commit to git):
# DB_PASSWORD=P@ssw0rd#2026
# API_KEY=sk-live-abc123xyz789
# In .gitignore:
# .env
# *.env
# .env.*
# In application code:
# db_password = os.environ.get('DB_PASSWORD')
# api_key = os.environ.get('API_KEY')
# Risk: env vars visible in 'ps aux' output,
# inherited by child processes, appear in /proc/<pid>/environ専用のシークレットマネージャー
シークレットマネージャーは、シークレットの保存、ローテーション、アクセス監査を目的に構築されたシステムです。代表的なソリューションには、HashiCorp Vault(オープンソースおよびエンタープライズ)、AWS Secrets Manager、Azure Key Vault、Google Cloud Secret Managerがあります。アプリケーションは実行時にシークレットマネージャーへ認証し、シークレットを取得して使用します。シークレットがディスクや環境変数に保存されることはありません。すべてのアクセスがログに記録されるため、誰がどのシークレットにいつアクセスしたかを監査できます。
# HashiCorp Vault secret retrieval (conceptual):
# Application authenticates to Vault using:
# - AWS IAM role (in cloud environments)
# - Kubernetes service account token
# - AppRole credentials
# After authentication, retrieve secret:
# vault kv get -field=password secret/prod/database
# In application (Python SDK):
# client = hvac.Client(url='https://vault.company.com')
# client.auth.aws.iam_login(role='prod-app')
# secret = client.secrets.kv.read_secret('prod/database')
# db_password = secret['data']['password']シークレットの自動ローテーション
環境変数と比較したシークレットマネージャーの大きな利点は、自動ローテーションです。AWS Secrets Managerでは、アプリケーションを再デプロイすることなく、スケジュール(例:30日ごと)に従ってRDSデータベースのパスワードを自動的にローテーションできます。シークレットマネージャーはデータベースのパスワードと保存されたシークレットを同時に更新します。接続ごとにシークレットを取得するアプリケーションは、新しい認証情報を自動的に受け取ります。これにより、ローテーションされることのない「恒久的な」サービスアカウントパスワードを使用する一般的な慣行をなくせます。
# AWS Secrets Manager rotation configuration:
# Secret: prod/app-database-credentials
# Rotation: enabled
# Frequency: every 30 days
# Lambda function: SecretsManager-MyRDSRotation
# Rotation process:
# 1. Lambda creates new DB password
# 2. Updates secret in Secrets Manager
# 3. Updates password on RDS instance
# 4. Tests new credentials work
# 5. Deprecates old credentials
# Application: always calls GetSecretValue at runtime -> gets fresh value.gitignoreによる防御
コミットされたシークレットに対する最初の防御策は、シークレットを含む可能性のあるすべてのファイルを除外するよう適切に管理された.gitignore fileです。ただし、.gitignoreが防ぐのは今後のコミットだけであり、すでにコミットされたシークレットはgitの履歴に残ります。シークレットを誤ってコミットした場合は、直ちに漏えいしたものとして扱う必要があります。まずsecretをローテーションし、その後、必要に応じてgit filter-repoなどのツールを使って履歴を書き換えます(コンプライアンス上必要になる場合はありますが、シークレットがすでに抽出されている可能性があるため、これだけでは不十分です)。
# Recommended .gitignore entries for secret files:
# .env
# .env.*
# *.pem
# *.key
# *.p12
# *.pfx
# credentials.json
# service_account*.json
# secrets.yaml
# config/secrets.yml
# terraform.tfvars (may contain cloud credentials)
# .aws/credentials
# Pre-commit hook to scan for secrets before commit:
# pre-commit install
# hook: detect-secrets / gitleaks / truffleHogInfrastructure as Codeのシークレット
Infrastructure as Code(IaC)ファイル(Terraform、CloudFormation、Kubernetesマニフェスト)には、データベース接続文字列、環境変数宣言内のAPIキー、TLS証明書などのシークレットが頻繁に含まれます。これらのファイルはバージョン管理にコミットされることが多く、シークレット漏えいのリスクを生みます。解決策には、Vaultの動的シークレット(Vaultが各Terraform実行専用の短期認証情報を生成します)、Kubernetes Secrets(etcdに保存されるため、保存時の暗号化が必要です)、実行時にシークレットマネージャーからKubernetesへ同期するexternal-secrets-operatorがあります。
シークレットに対する最小権限の原則
各アプリケーションまたはサービスは、それぞれが明確に必要とするシークレットだけにアクセスする必要があります。これがシークレットに適用される最小権限の原則です。Webアプリケーションに必要なのはデータベースのパスワードであり、CAの秘密鍵ではありません。レポートジョブに必要なのは読み取り専用のデータベース認証情報であり、書き込み権限ではありません。シークレットマネージャーは、どのアイデンティティ(IAMロール、サービスアカウント、AppRole)がどのシークレットを読み取れるかを指定するアクセス ポリシーによってこれを適用し、監査のためにすべてのアクセスを記録します。
# Vault policy: web application can read DB password only
# policy name: web-app-policy
# path 'secret/prod/database' {
# capabilities = ['read']
# }
# path 'secret/prod/tls-certs/*' {
# capabilities = [] # DENY - app does not need TLS keys
# }
# This policy is assigned to the web app's AppRole.
# The reporting service gets a separate policy with
# only 'secret/prod/reporting-db-readonly' access.動的シークレット
動的シークレットは、特定の要求元に対してオンデマンドで生成され、自動的に有効期限が切れます。Vaultは、1時間有効で、その認証情報を要求した特定のサービスに関連付けられた一時的なデータベース認証情報を生成できます。有効期限が切れると、データベースによって認証情報が自動的に失効します。この方法では、攻撃者に盗まれる可能性のある長期間有効な固定認証情報が存在しません。攻撃者が動的認証情報を取得しても、すぐに期限切れとなり、監査ログでは要求元のアイデンティティに紐付けられます。
# Vault dynamic secrets: temporary DB credentials
# Application calls Vault to get a DB credential:
# vault read database/creds/web-app-role
#
# Vault response:
# username: v-web-app-x7k2m-1234567890 (unique, temporary)
# password: A1b2C3d4E5f6G7h8 (randomly generated)
# lease_duration: 1h (auto-expires)
#
# After 1 hour, Vault instructs DB to revoke this user.
# No static password ever exists for the attacker to steal.CI/CDパイプライン内のシークレット
CI/CDパイプラインでは、デプロイ用のクラウドプロバイダー認証情報、Dockerレジストリトークン、署名キーなどのシークレットが頻繁に必要になります。パイプラインのスクリプトや設定ファイルにシークレットを保存してはいけません。代わりに、パイプラインプラットフォーム組み込みのシークレットストア(GitHub Actions Secrets、GitLab CI Variables、Jenkins Credentials Store)を使用するか、マシンアイデンティティを使って実行時に一元管理されたVaultからシークレットを取得します。ビルド出力への誤った露出を防ぐため、ログではシークレット変数をマスク対象として設定してください。
# GitHub Actions: using secrets in pipeline
# secrets.yml in GitHub Settings -> Secrets (encrypted storage)
# Secret: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
# In .github/workflows/deploy.yml:
# env:
# AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
# AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Best practice: use OIDC federation instead
# GitHub -> AWS trust relationship via OIDC token
# -> No static AWS keys needed at allシークレットアクセスの監査
シークレットマネージャーは、すべてのシークレットアクセスイベントについて包括的な監査ログを提供します。どのアイデンティティがどのシークレットに、どのIPアドレスから、いつアクセスしたか、またアクセスが成功したか拒否されたかが記録されます。これらのログは、コンプライアンス(SOC 2、PCI-DSS)とインシデント対応に不可欠です。認証情報が漏えいした疑いがある場合、監査ログからその認証情報にアクセスしたシステムと時刻を確認できます。これにより、影響を受けた可能性のあるシステムを迅速に特定し、封じ込めの判断を下せます。
シークレット防止のためのPre-Commitフック
Pre-commitフックは、各gitコミットの確定前に自動実行されるスクリプトであり、シークレットがバージョン管理の履歴に入る前に検出できます。detect-secrets(Yelp)、GitLeaks、git-secrets(AWS)などのツールはPre-commitフックとして統合でき、ステージングされたファイルをスキャンして、APIキー、接続文字列、秘密鍵、JWTトークンに一致するパターンを検出します。シークレットが検出されるとコミットは拒否され、開発者には認証情報を削除するよう促されます。pre-commit frameworkを使うと、チーム間でフック設定を追加・共有しやすくなります。
# Installing detect-secrets as pre-commit hook:
# 1. Install: pip install detect-secrets
# 2. Create baseline: detect-secrets scan > .secrets.baseline
# 3. Add to .pre-commit-config.yaml:
# repos:
# - repo: https://github.com/Yelp/detect-secrets
# rev: v1.4.0
# hooks:
# - id: detect-secrets
# args: ['--baseline', '.secrets.baseline']
# 4. Install hooks: pre-commit install
# Now every commit attempt is scanned:
# git commit -m 'add config'
# -> detect-secrets runs
# -> if AWS key pattern found: COMMIT BLOCKED
# -> developer must remove secret and use secrets managerクイックチェック
このレッスンで扱ったCompTIA Security+(SY0-701)の概念について、理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、ソースコードにハードコードされたシークレットを排除し、VaultやAWS Secrets Managerなどのシークレットマネージャーに置き換えること、自動ローテーションによって、初回の侵害後も攻撃者に悪用される可能性がある長期間有効な認証情報を排除できること、そして動的シークレットと最小権限のアクセスポリシーによって、個々のシークレットが漏えいした場合の価値を最小限に抑えられることを学びました。次は、依存関係のセキュリティとソフトウェア構成分析について学びます。
よくある質問
「安全なシークレット管理と環境変数」レッスンは無料ですか?
はい。「安全なシークレット管理と環境変数」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Cloud & IT Cert Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Cloud & IT Cert Prepコースには全4レッスンが含まれています。
「安全なシークレット管理と環境変数」で何を学びますか?
Secrets Manager(Vault、AWS Secrets Manager)と実行時の環境変数注入を使用し、ソースコードへのシークレットのハードコードを避けます。 ブラウザで直接実行するハンズオンコードでCloud & IT Cert Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Cloud & IT Cert Prepを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのCloud & IT Cert Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「安全なシークレット管理と環境変数」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このCloud & IT Cert Prepレッスンでコードを書いて実行できますか?
はい。すべてのCloud & IT Cert Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。