用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/killvxk/cybersecurity-skills-zh --skill performing-service-account-credential-rotation命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | performing-service-account-credential-rotation |
| description | 跨 Active Directory、云平台和应用程序数据库自动化服务账户凭据轮换,消除陈旧密钥并降低泄露风险。 |
| domain | cybersecurity |
| subdomain | identity-access-management |
| tags | ["service-accounts","credential-rotation","secrets-management","pam","automation","vault"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
服务账户是应用程序、守护进程、CI/CD 流水线和自动化流程用于向系统和 API 认证的非人类身份。这些账户通常具有较高权限,其凭据(密码、API 密钥、证书、令牌)往往长期有效且在团队间共享,使其成为攻击者的主要目标。凭据轮换是按计划系统性替换这些密钥、将新凭据传播到所有依赖系统,并在轮换后验证服务连续性的流程。
| 类型 | 平台 | 凭据 | 轮换方法 |
|---|---|---|---|
| Active Directory 服务账户 | Windows/AD | 密码 | gMSA(自动)或 PAM 管理 |
| AWS IAM 用户 | AWS | 访问密钥/Secret 密钥 | AWS Secrets Manager 轮换 Lambda |
| GCP 服务账户 | GCP | JSON 密钥文件 | 通过 IAM API 进行密钥轮换 |
| Azure 服务主体 | Azure | 客户端密钥/证书 | Key Vault + 轮换策略 |
| 数据库服务账户 | SQL/Oracle/Postgres | 密码 | Vault 动态密钥 |
| API 密钥 | SaaS 应用程序 | API 令牌 | 应用特定 API |
Windows gMSA 由 Active Directory 提供自动密码管理:
密钥管理器 / Vault
│
├── 轮换触发(计划或按需)
│
├── 生成新凭据
│
├── 在源系统更新凭据(AD、云 IAM、数据库)
│
├── 在所有消费方更新凭据:
│ ├── 应用程序配置
│ ├── CI/CD 流水线密钥
│ ├── Kubernetes 密钥
│ └── 其他依赖服务
│
├── 验证服务健康:
│ ├── 健康检查端点
│ ├── 认证测试
│ └── 功能冒烟测试
│
└── 撤销旧凭据(宽限期后)
枚举所有服务账户及其依赖关系:
# Active Directory:查找所有服务账户
Get-ADServiceAccount -Filter * -Properties *
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName,PasswordLastSet,LastLogonDate
# 查找密码超过 90 天的账户
$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
# 创建 KDS 根密钥(一次性,全域范围)
Add-KdsRootKey -EffectiveImmediately
# 创建 gMSA 账户
New-ADServiceAccount -Name "svc-webapp-gmsa" `
-DNSHostName "svc-webapp-gmsa.corp.example.com" `
-PrincipalsAllowedToRetrieveManagedPassword "WebServerGroup" `
-KerberosEncryptionType AES128,AES256
# 在目标服务器上安装
Install-ADServiceAccount -Identity "svc-webapp-gmsa"
# 测试账户
Test-ADServiceAccount -Identity "svc-webapp-gmsa"
# 配置 IIS 应用程序池使用 gMSA
# 将标识设置为:CORP\svc-webapp-gmsa$
import boto3
import json
def rotate_iam_access_key(secret_arn, iam_username):
"""通过 Secrets Manager 轮换 IAM 用户的访问密钥。"""
iam = boto3.client("iam")
sm = boto3.client("secretsmanager")
# 创建新访问密钥
new_key = iam.create_access_key(UserName=iam_username)
new_access_key = new_key["AccessKey"]["AccessKeyId"]
new_secret_key = new_key["AccessKey"]["SecretAccessKey"]
# 在 Secrets Manager 中存储新凭据
sm.put_secret_value(
SecretId=secret_arn,
SecretString=json.dumps({
"accessKeyId": new_access_key,
"secretAccessKey": new_secret_key,
"username": iam_username,
})
)
# 列出旧访问密钥并停用
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}
import hvac
def configure_vault_database_rotation(vault_url, vault_token, db_config):
"""配置 HashiCorp Vault 实现数据库凭据自动轮换。"""
client = hvac.Client(url=vault_url, token=vault_token)
# 启用数据库密钥引擎
client.sys.enable_secrets_engine(
backend_type="database",
path="database"
)
# 配置数据库连接
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"],
)
# 创建动态凭据角色
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"]}
每次轮换后,验证服务连续性:
import requests
import time
def verify_service_health(service_endpoints, max_retries=3, delay=10):
"""检查凭据轮换后服务是否正常。"""
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