本文目录导读:

针对自动化脚本清理未使用角色,需根据不同的系统环境(如数据库、云平台、应用系统)采用不同的策略,以下是几种常见场景的自动化清理方案:
数据库(以 PostgreSQL / MySQL 为例)
场景:数据库中存在大量已创建但未被任何用户、API或应用引用的角色/用户。
自动化脚本思路:
# Python 示例:连接数据库并清理未被授权的角色
import psycopg2
import os
def clean_unused_roles(conn):
cursor = conn.cursor()
# 1. 查找没有被授予任何权限的角色(排除系统角色)
cursor.execute("""
SELECT rolname FROM pg_roles
WHERE rolname NOT IN ('postgres', 'pg_signal_backend', 'pg_read_all_data', 'pg_write_all_data')
AND NOT EXISTS (
SELECT 1 FROM pg_auth_members WHERE member = pg_roles.oid
)
AND NOT EXISTS (
SELECT 1 FROM pg_shdepend WHERE refobjid = pg_roles.oid AND deptype = 'a'
)
""")
unused_roles = cursor.fetchall()
# 2. 删除这些角色
for (role_name,) in unused_roles:
cursor.execute(f"DROP ROLE IF EXISTS {role_name}")
print(f"Dropped unused role: {role_name}")
conn.commit()
# 使用方式(需在安全窗口运行)
# clean_unused_roles(connect_db())
适用条件:需要数据库管理员权限,且确认这些角色确实未被任何连接或对象依赖。
AWS IAM 角色清理(云平台)
场景:AWS 账户中积累了未附加到任何服务、实例或用户的角色。
自动化方案(使用 AWS CLI + bash):
#!/bin/bash
# 获取所有IAM角色
aws iam list-roles --query "Roles[?RoleName!='AWSServiceRoleForSupport'].RoleName" --output text | while read role; do
# 检查角色是否附加了任何实例配置文件
instance_profiles=$(aws iam list-instance-profiles-for-role --role-name "$role" --query "InstanceProfiles" --output text 2>/dev/null)
# 检查角色是否被任何服务信任策略引用
trust_policy=$(aws iam get-role --role-name "$role" --query "Role.AssumeRolePolicyDocument" --output json 2>/dev/null)
if [ -z "$instance_profiles" ] && echo "$trust_policy" | grep -q "Service:.*lambda\|Service:.*ec2\|Service:.*ecs"; then
# 等待24小时后再次确认(避免误删)
echo "Role $role might be unused. Skipping automatic deletion."
else
# 删除完全无关联的角色
aws iam delete-role --role-name "$role" 2>/dev/null
echo "Deleted IAM role: $role"
fi
done
关键点:
- 必须同时检查信任关系和附加的实体。
- 建议增加人工确认步骤(如将疑似未使用角色输出到审计日志,超过30天无变化才自动删除)。
应用系统(如 Django 或自建权限系统)
场景:系统中定义了多种角色,但部分角色在数据库的用户表中从未被分配。
自动化清理脚本(Python + SQLAlchemy):
from sqlalchemy import create_engine, text
from datetime import datetime, timedelta
def clean_app_roles(engine, dry_run=True):
with engine.connect() as conn:
# 1. 查找未被任何用户分配的角色
query = text("""
SELECT r.id, r.name
FROM roles r
LEFT JOIN user_roles ur ON r.id = ur.role_id
WHERE ur.user_id IS NULL
AND r.created_at < :threshold
""")
threshold = datetime.utcnow() - timedelta(days=30) # 超过30天未分配的角色
unused_roles = conn.execute(query, {"threshold": threshold}).fetchall()
if dry_run:
print("未使用角色(模拟运行,不会删除):")
for role in unused_roles:
print(f" ID: {role.id}, Name: {role.name}")
else:
for role in unused_roles:
conn.execute(text("DELETE FROM role_permissions WHERE role_id = :rid"), {"rid": role.id})
conn.execute(text("DELETE FROM roles WHERE id = :rid"), {"rid": role.id})
print(f"Deleted role: {role.name}")
conn.commit()
建议:
- 始终提供
dry_run=True参数,先在测试环境验证。 - 记录删除的角色到日志表,以备回滚。
通用安全自动化脚本设计原则
无论是哪种场景,清理未使用角色的脚本都应该包含以下机制:
| 机制 | 说明 |
|---|---|
| 依赖检查 | 确认该角色没有被任何ACL、策略或数据库对象引用 |
| 多重确认 | 分两步执行:第一天标记(设置过期标签),第二天删除(防止误删) |
| 日志记录 | 每次操作写入审计日志,包含角色名、操作时间、执行者 |
| 回滚能力 | 保留被删除角色的权限快照,必要时重建 |
| 黑名单 | 明确禁止删除内置角色(如 postgres、root、admin) |
| 通知机制 | 删除前通知相关系统负责人(通过邮件或SLACK) |
推荐执行策略
最佳实践是采用“两步走”方案:
-
扫描并标记(安全阶段)
- 脚本每天运行,找出“疑似未使用”的角色。
- 将这些角色加入 待清理队列,并发送通知给管理员。
-
延迟删除(确认阶段)
- 等待 7~30 天(根据角色重要程度)。
- 再次验证这些角色仍然未使用。
- 正式执行删除,并记录日志。
示例脚本框架(调度用 crontab 每天运行):
# 每天凌晨的扫描任务
def daily_scan():
unused = find_unused_roles()
for role in unused:
if role.last_seen is None or role.last_seen < (now - 7days):
mark_for_deletion(role)
notify_admin(role)
elif role.is_marked_for_deletion():
if role.marked_time < (now - 7days):
delete_role(role)
- 数据库、云平台、应用系统需要不同的检查逻辑。
- 核心是依赖分析(角色是否被引用)+ 时间缓冲(避免误删)。
- 始终配置 dry_run 模式和日志记录。
- 对于关键系统,更安全的做法是只标记+提示,由人工确认后再触发删除。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播