如何用脚本批量管理API密钥?

wen 实用脚本 2

本文目录导读:

如何用脚本批量管理API密钥?

  1. 核心管理逻辑(通用)
  2. 使用 Bash 脚本(适用于 Linux / macOS + AWS/Azure/GCP CLI)
  3. 使用 Python 脚本(更灵活,支持多平台)
  4. 使用 PowerShell(适用于 Azure / 微软生态)
  5. 安全注意事项(非常重要)
  6. 扩展:管理大量不同服务的 API 密钥(配置文件驱动)
  7. 总结建议

批量管理API密钥通常涉及创建、轮换、撤销和审计等操作,以下提供几种主流脚本方案(Bash/Python/PowerShell),涵盖通用逻辑与安全最佳实践。


核心管理逻辑(通用)

在写脚本前,需明确管理范畴:

  1. 存储:密钥应加密存储(如 HashiCorp Vault、AWS Secrets Manager、或加密文件)。
  2. 操作:批量创建、启用/禁用、轮换、删除。
  3. 审计:记录谁在何时对哪个密钥做了什么。

使用 Bash 脚本(适用于 Linux / macOS + AWS/Azure/GCP CLI)

以下示例基于 AWS CLI 批量管理 IAM 用户的访问密钥(Access Key)。

#!/bin/bash
# 批量禁用所有 IAM 用户的活跃密钥(示例:安全巡检)
set -euo pipefail
AWS_PROFILE="your-profile"
echo "获取所有 IAM 用户..."
users=$(aws iam list-users --profile "$AWS_PROFILE" --query 'Users[*].UserName' --output text)
for user in $users; do
    echo "检查用户: $user"
    keys=$(aws iam list-access-keys --user-name "$user" --profile "$AWS_PROFILE" --query 'AccessKeyMetadata[?Status==`Active`].AccessKeyId' --output text)
    if [ -n "$keys" ]; then
        for key in $keys; do
            echo "禁用密钥: $key (用户: $user)"
            aws iam update-access-key --user-name "$user" --access-key-id "$key" --status Inactive --profile "$AWS_PROFILE"
        done
    else
        echo "用户 $user 无活跃密钥"
    fi
done
echo "完成。"

说明

  • AWS_PROFILE 替换为实际环境。
  • 可扩展为:批量创建密钥、导出密钥 CSV、批量删除未使用密钥。
  • 安全提示:禁用密钥前务必备份或确认替代密钥可用,否则会导致服务中断。

使用 Python 脚本(更灵活,支持多平台)

适用于任何 REST API 或 SDK(如 GitHub、Stripe、Slack 等)。

#!/usr/bin/env python3
"""
批量轮换(Rotate)API密钥示例:假设所有密钥存储在 AWS Secrets Manager 中。
"""
import boto3
import json
import secrets
import string
from botocore.exceptions import ClientError
def generate_secure_key(length=32):
    """生成安全的随机密钥"""
    alphabet = string.ascii_letters + string.digits
    return ''.join(secrets.choice(alphabet) for _ in range(length))
def rotate_all_secrets(region='us-east-1'):
    """批量更新 AWS Secrets Manager 中的密钥"""
    client = boto3.client('secretsmanager', region_name=region)
    paginator = client.get_paginator('list_secrets')
    for page in paginator.paginate():
        for secret in page['SecretList']:
            name = secret['Name']
            # 跳过非 API 密钥的 secret(可根据命名规则过滤)
            if not name.endswith('_api_key'):
                continue
            try:
                old_value = client.get_secret_value(SecretId=name)['SecretString']
                new_value = generate_secure_key()
                # 更新密钥(注意:这不会通知下游系统,需额外步骤)
                client.update_secret(
                    SecretId=name,
                    SecretString=new_value
                )
                print(f"轮换成功: {name}")
                # (可选)记录旧密钥到审计日志文件
                with open(f'rotated_{name}.log', 'w') as f:
                    f.write(f"Old key: {old_value}\nNew key: {new_value}\n")
            except ClientError as e:
                print(f"失败 {name}: {e}")
if __name__ == '__main__':
    rotate_all_secrets()

说明

  • 脚本假设密钥已存储在 AWS Secrets Manager 中,且命名包含 _api_key 后缀。
  • 生成新密钥后,需通知下游系统(如通过 webhook 或重启服务)以加载新密钥。
  • 安全最佳实践:轮换后应保留旧密钥一段时间(灰度切换),确保无服务依赖于旧密钥。

使用 PowerShell(适用于 Azure / 微软生态)

批量管理 Azure Key Vault 中的密钥:

# 批量更新 Azure Key Vault 中所有包含 "API" 的密钥
param(
    [string]$VaultName = "my-keyvault"
)
Connect-AzAccount
$secrets = Get-AzKeyVaultSecret -VaultName $VaultName | Where-Object {$_.Name -match "API"}
foreach ($secret in $secrets) {
    $oldValue = (Get-AzKeyVaultSecret -VaultName $VaultName -Name $secret.Name).SecretValueText
    $newValue = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 32 | ForEach-Object { [char]$_ })
    # 更新密钥
    $secureString = ConvertTo-SecureString $newValue -AsPlainText -Force
    Set-AzKeyVaultSecret -VaultName $VaultName -Name $secret.Name -SecretValue $secureString
    Write-Host "已轮换密钥: $($secret.Name)"
    # 记录旧值(务必谨慎处理日志安全性)
    # Add-Content -Path "secret_rotation.log" -Value "$(Get-Date) - $($secret.Name) - Old: $oldValue"
}

安全注意事项(非常重要)

  1. 最小化硬编码
    不要在脚本中明文传递密钥,使用环境变量、托管机密存储或 IAM 角色挂载。
  2. 日志脱敏
    控制台输出或日志文件里不要打印具体密钥值(尤其旧密钥),只输出 Success / Failed
  3. 认证权限
    脚本使用的令牌/账号应仅具备所需的最小权限(如只读+轮换,无删除权限)。
  4. 幂等性与重试
    批量操作用幂等设计(如 update-if-exists 而非 create),避免重复创建导致混乱。
  5. 测试环境先行
    先在测试 vault / 测试用户组运行,确认逻辑无误再推至生产。
  6. 通知与回滚计划
    密钥更换可能导致业务中断,脚本需记录 old_value 以便回滚,并提前通知下游调用方。

扩展:管理大量不同服务的 API 密钥(配置文件驱动)

如果密钥来源多样(如 GitHub + Stripe + SendGrid),建议用 YAML/JSON 配置文件驱动脚本:

# keys_config.yaml
services:
  - name: "github"
    type: "oauth"
    endpoint: "https://api.github.com/user/keys"
    auth_header: "Authorization: token {KEY}"
  - name: "stripe"
    type: "secret_key"
    endpoint: "https://api.stripe.com/v1/..."
    auth_header: "Bearer {KEY}"

脚本解析配置文件,对每个服务调用对应的 API 执行创建/撤销/轮换,这样一套脚本可管理任意数量的 API 提供商。


总结建议

  • 小规模(< 10 个密钥):Shell 脚本 + 加密文件。
  • 中规模(10-100 个密钥):Python + 托管 Secrets Manager(AWS/Azure/GCP)。
  • 大规模或跨云:考虑使用 Terraform、Ansible 或专门工具(如 Vault 的批量操作插件)。

选择哪种方案取决于你的基础设施、安全合规要求和团队技术栈,如果需要针对特定平台(如 Kubernetes Secrets、GitHub Actions Secrets)的详细脚本,可以进一步提供。

抱歉,评论功能暂时关闭!