performing-service-account-credential-rotation について
ディレクトリ、クラウド、アプリケーションにまたがるサービスアカウントの認証情報ローテーションを計画・実施するセキュリティスキルです。アカウント棚卸し、方式の選択、依存関係の調整、実施後の稼働確認を扱います。
主な機能
- 01サービスアカウントの棚卸しと依存関係の把握
- 02gMSA による自動パスワード管理
- 03クラウドアクセスキーのローテーション
- 04Vault によるデータベース認証情報のローテーション
- 05ローテーション後のヘルスチェック
活用シーン
- 01サービスアカウントの定期ローテーション計画
- 02認証情報漏えいへの対応
- 03ローテーション後のサービス継続性確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill performing-service-account-credential-rotationインストール後、Claude Code で/performing-service-account-credential-rotationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
サービスアカウントの認証情報をローテーションする
概要
サービスアカウントは、アプリケーション、デーモン、CI/CD パイプライン、自動化プロセスがシステムや API への認証に使用する、人間以外の ID です。これらのアカウントは高い権限を持つことが多く、認証情報(パスワード、API キー、証明書、トークン)は有効期間が長く、チーム間で共有されることも頻繁にあるため、攻撃者にとって格好の標的です。認証情報のローテーションとは、これらのシークレットを定期的に置き換え、新しい認証情報を依存するすべてのシステムに反映し、ローテーション後もサービスが継続していることを確認する体系的なプロセスです。
使用する場面
- サービスアカウントの認証情報のローテーションを伴うセキュリティ評価を実施する場合
- 関連するセキュリティインシデントに対するインシデント対応手順に従う場合
- 定期的なセキュリティテストや監査を実施する場合
- 実地テストを通じてセキュリティ制御を検証する場合
前提条件
- AD、クラウド、アプリケーション全体のサービスアカウントのインベントリ
- シークレット管理プラットフォーム(HashiCorp Vault、AWS Secrets Manager、Azure Key Vault、または CyberArk)
- サービスの依存関係マッピング(各サービスが使用する認証情報の把握)
- ローテーション期間に関する変更管理プロセス
- ローテーション後のサービスの健全性を監視する仕組み
基本概念
サービスアカウントの種類
| 種類 | プラットフォーム | 認証情報 | ローテーション方法 |
|---|---|---|---|
| Active Directory サービスアカウント | Windows/AD | パスワード | gMSA(自動)または PAM による管理 |
| AWS IAM ユーザー | AWS | アクセスキー/シークレットキー | AWS Secrets Manager のローテーション Lambda |
| GCP サービスアカウント | GCP | JSON キーファイル | IAM API によるキーのローテーション |
| Azure サービスプリンシパル | Azure | クライアントシークレット/証明書 | Key Vault + ローテーションポリシー |
| データベースサービスアカウント | SQL/Oracle/Postgres | パスワード | Vault の動的シークレット |
| API キー | SaaS アプリケーション | API トークン | アプリケーション固有の API |
グループ管理サービスアカウント(gMSA)
Windows の gMSA は、Active Directory によるパスワードの自動管理を提供します。
- AD が 30 日ごとにパスワードを自動でローテーションします
- パスワードは 240 バイトで、暗号学的にランダムです
- 複数のサーバーが同じ gMSA を同時に使用できます
- 管理者がパスワードを把握したり管理したりする必要はありません
- Windows サービスの手動ローテーションが不要になります
ローテーションアーキテクチャ
Secrets Manager / Vault
│
├── Rotation Trigger (schedule or on-demand)
│
├── Generate new credential
│
├── Update credential at source (AD, cloud IAM, database)
│
├── Update credential in all consumers:
│ ├── Application configuration
│ ├── CI/CD pipeline secrets
│ ├── Kubernetes secrets
│ └── Other dependent services
│
├── Verify service health
│ ├── Health check endpoints
│ ├── Authentication test
│ └── Functional smoke test
│
└── Revoke old credential (after grace period)
ワークフロー
ステップ 1:サービスアカウントを検出し、インベントリを作成する
すべてのサービスアカウントとその依存関係を列挙します。
# Active Directory: Find all service accounts
Get-ADServiceAccount -Filter * -Properties *
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName,PasswordLastSet,LastLogonDate
# Find accounts with passwords older than 90 days
$threshold = (Get-Date).AddDays(-90)
Get-ADUser -Filter {PasswordLastSet -lt $threshold -and Enabled -eq $true} -Properties PasswordLastSet,ServicePrincipalName |
Where-Object {$_.ServicePrincipalName} |
Select-Object Name, PasswordLastSet, ServicePrincipalName
ステップ 2:Windows サービスに gMSA を導入する
# Create KDS Root Key (one-time, domain-wide)
Add-KdsRootKey -EffectiveImmediately
# Create the gMSA account
New-ADServiceAccount -Name "svc-webapp-gmsa" `
-DNSHostName "svc-webapp-gmsa.corp.example.com" `
-PrincipalsAllowedToRetrieveManagedPassword "WebServerGroup" `
-KerberosEncryptionType AES128,AES256
# Install on target server
Install-ADServiceAccount -Identity "svc-webapp-gmsa"
# Test the account
Test-ADServiceAccount -Identity "svc-webapp-gmsa"
# Configure IIS Application Pool to use gMSA
# Set identity to: CORP\svc-webapp-gmsa$
ステップ 3:Secrets Manager を使用して AWS アクセスキーをローテーションする
import boto3
import json
def rotate_iam_access_key(secret_arn, iam_username):
"""Rotate an IAM user's access key via Secrets Manager."""
iam = boto3.client("iam")
sm = boto3.client("secretsmanager")
# Create new access key
new_key = iam.create_access_key(UserName=iam_username)
new_access_key = new_key["AccessKey"]["AccessKeyId"]
new_secret_key = new_key["AccessKey"]["SecretAccessKey"]
# Store new credentials in Secrets Manager
sm.put_secret_value(
SecretId=secret_arn,
SecretString=json.dumps({
"accessKeyId": new_access_key,
"secretAccessKey": new_secret_key,
"username": iam_username,
})
)
# List old access keys and deactivate them
keys = iam.list_access_keys(UserName=iam_username)
for key in keys["AccessKeyMetadata"]:
if key["AccessKeyId"] != new_access_key and key["Status"] == "Active":
iam.update_access_key(
UserName=iam_username,
AccessKeyId=key["AccessKeyId"],
Status="Inactive"
)
return {"new_key_id": new_access_key, "old_keys_deactivated": True}
ステップ 4:Vault を使用してデータベースの認証情報をローテーションする
import hvac
def configure_vault_database_rotation(vault_url, vault_token, db_config):
"""Configure HashiCorp Vault for automatic database credential rotation."""
client = hvac.Client(url=vault_url, token=vault_token)
# Enable database secrets engine
client.sys.enable_secrets_engine(
backend_type="database",
path="database"
)
# Configure database connection
client.secrets.database.configure(
name=db_config["name"],
plugin_name="postgresql-database-plugin",
connection_url=f"postgresql://{{{{username}}}}:{{{{password}}}}@"
f"{db_config['host']}:{db_config['port']}/{db_config['database']}",
allowed_roles=[db_config["role_name"]],
username=db_config["admin_user"],
password=db_config["admin_password"],
)
# Create a role for dynamic credentials
client.secrets.database.create_role(
name=db_config["role_name"],
db_name=db_config["name"],
creation_statements=[
"CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';",
f"GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \"{{{{name}}}}\";"
],
default_ttl="1h",
max_ttl="24h",
)
return {"status": "configured", "role": db_config["role_name"]}
ステップ 5:ローテーション後の検証
ローテーションのたびに、サービスが継続していることを確認します。
import requests
import time
def verify_service_health(service_endpoints, max_retries=3, delay=10):
"""Check that services are healthy after credential rotation."""
results = []
for endpoint in service_endpoints:
for attempt in range(max_retries):
try:
response = requests.get(
endpoint["health_url"],
timeout=10,
headers=endpoint.get("headers", {})
)
healthy = response.status_code == 200
results.append({
"service": endpoint["name"],
"status": "healthy" if healthy else f"unhealthy ({response.status_code})",
"attempt": attempt + 1,
})
if healthy:
break
except requests.RequestException as e:
results.append({
"service": endpoint["name"],
"status": f"error: {str(e)}",
"attempt": attempt + 1,
})
if attempt < max_retries - 1:
time.sleep(delay)
return results
検証チェックリスト
- 依存関係のマッピングを含む、サービスアカウントの完全なインベントリ
- 対象となるすべての Windows サービスアカウントに gMSA を導入済み
- シークレットマネージャー(AWS、GCP、Azure)を通じてクラウドのアクセスキーをローテーション済み
- データベースの認証情報を動的シークレット(Vault)またはローテーションポリシーで管理
- ローテーションスケジュールを定義済み(リスクレベルに応じて 30~90 日)
- ローテーション後のヘルスチェックを自動化済み
- ローテーション失敗時のアラートを設定済み
- 猶予期間後に古い認証情報を失効
- ローテーションイベントを記録し、監査可能な状態にする
- ロールバック手順を文書化し、テスト済み
参考資料
コメント
Markdown 対応