mcpField
P
performing-service-account-credential-rotation

performing-service-account-credential-rotation

github.com/mukul975安全35.2k64 次安装8 周前更新
代码仓库

关于 performing-service-account-credential-rotation

用于规划和执行服务账户凭证轮换的安全技能,覆盖目录、云和应用系统。内容包括账户盘点、轮换方式、依赖协调及轮换后的健康检查。

主要功能

  1. 01服务账户盘点与依赖映射
  2. 02gMSA 自动密码管理
  3. 03云访问密钥轮换
  4. 04Vault 数据库凭证轮换
  5. 05轮换后健康检查

适用场景

  1. 01安排服务账户的定期轮换
  2. 02应对凭证泄露事件
  3. 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 外,安装时一起下载的参考资料和脚本。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

详细介绍

执行服务账号凭据轮换

概述

服务账号是应用程序、守护进程、CI/CD 流水线和自动化流程用于向系统和 API 进行身份验证的非人类身份。这些账号通常拥有较高权限,其凭据(密码、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 服务账号GCPJSON 密钥文件通过 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