自动化脚本如何清理未使用角色

wen 实用脚本 5

本文目录导读:

自动化脚本如何清理未使用角色

  1. 数据库(以 PostgreSQL / MySQL 为例)
  2. AWS IAM 角色清理(云平台)
  3. 应用系统(如 Django 或自建权限系统)
  4. 通用安全自动化脚本设计原则
  5. 推荐执行策略

针对自动化脚本清理未使用角色,需根据不同的系统环境(如数据库、云平台、应用系统)采用不同的策略,以下是几种常见场景的自动化清理方案:

数据库(以 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、策略或数据库对象引用
多重确认 分两步执行:第一天标记(设置过期标签),第二天删除(防止误删)
日志记录 每次操作写入审计日志,包含角色名、操作时间、执行者
回滚能力 保留被删除角色的权限快照,必要时重建
黑名单 明确禁止删除内置角色(如 postgresrootadmin
通知机制 删除前通知相关系统负责人(通过邮件或SLACK)

推荐执行策略

最佳实践是采用“两步走”方案

  1. 扫描并标记(安全阶段)

    • 脚本每天运行,找出“疑似未使用”的角色。
    • 将这些角色加入 待清理队列,并发送通知给管理员。
  2. 延迟删除(确认阶段)

    • 等待 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 模式和日志记录
  • 对于关键系统,更安全的做法是只标记+提示,由人工确认后再触发删除。

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