使用Python和Pandas实现的Snowflake权限检查与SQL生成用于IT审计

python 复制代码
import snowflake.connector
import pandas as pd

def get_snowflake_permissions():
    # 连接Snowflake(需要替换实际凭证)
    conn = snowflake.connector.connect(
        user='<USER>',
        password='<PASSWORD>',
        account='<ACCOUNT>',
        warehouse='<WAREHOUSE>',
        role='SECURITYADMIN'
    )
    
    # 结果容器
    results = {
        'role_grants': [],
        'table_privileges': [],
        'views': [],
        'masking_policies': [],
        'row_policies': []
    }

    # 1. 获取角色继承关系
    cur = conn.cursor()
    cur.execute("""
        SELECT granted_to_role, role_granted 
        FROM SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_ROLES 
        WHERE PRIVILEGE = 'USAGE' AND GRANTED_ON = 'ROLE'
    """)
    results['role_grants'] = cur.fetchall()

    # 2. 获取表权限
    cur.execute("""
        SELECT grantee, table_catalog, table_schema, table_name, privilege_type 
        FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES
    """)
    results['table_privileges'] = cur.fetchall()

    # 3. 获取视图定义
    cur.execute("""
        SELECT table_catalog, table_schema, table_name, view_definition 
        FROM INFORMATION_SCHEMA.VIEWS
    """)
    results['views'] = cur.fetchall()

    # 4. 获取数据掩码策略
    cur.execute("""
        SELECT policy_name, policy_body, column 
        FROM TABLE(INFORMATION_SCHEMA.POLICY_REFERENCES())
        WHERE POLICY_KIND = 'MASKING_POLICY'
    """)
    results['masking_policies'] = cur.fetchall()

    # 5. 获取行访问策略
    cur.execute("""
        SELECT policy_name, policy_body, ref_column_name, ref_table_name 
        FROM TABLE(INFORMATION_SCHEMA.POLICY_REFERENCES())
        WHERE POLICY_KIND = 'ROW_ACCESS_POLICY'
    """)
    results['row_policies'] = cur.fetchall()

    conn.close()
    return results

def generate_descriptions(data):
    reports = []
    
    # 角色继承描述
    for grant in data['role_grants']:
        reports.append(f"角色 {grant[1]} 被授予给 {grant[0]},实现权限继承")

    # 表权限描述
    for priv in data['table_privileges']:
        reports.append(f"角色 {priv[0]} 在表 {priv[1]}.{priv[2]}.{priv[3]} 拥有 {priv[4]} 权限")

    # 视图描述
    for view in data['views']:
        reports.append(f"存在限制访问视图 {view[0]}.{view[1]}.{view[2]},定义:{view[3]}")

    # 数据掩码描述
    for policy in data['masking_policies']:
        reports.append(f"列 {policy[2]} 应用数据掩码策略 {policy[0]},策略逻辑:{policy[1]}")

    # 行策略描述
    for policy in data['row_policies']:
        reports.append(f"表 {policy[3]} 的 {policy[2]} 列应用行访问策略 {policy[0]},策略逻辑:{policy[1]}")

    return reports

def generate_sql_statements(data):
    sqls = []
    
    # 生成角色继承SQL
    for grant in data['role_grants']:
        sqls.append(f"GRANT ROLE {grant[1]} TO ROLE {grant[0]};")

    # 生成表权限SQL
    for priv in data['table_privileges']:
        sqls.append(
            f"GRANT {priv[4]} ON {priv[1]}.{priv[2]}.{priv[3]} TO ROLE {priv[0]};"
        )

    # 生成数据掩码SQL
    for policy in data['masking_policies']:
        sqls.extend([
            f"CREATE MASKING POLICY {policy[0]} AS {policy[1]};",
            f"ALTER TABLE {policy[2].split('.')[:3]} MODIFY COLUMN {policy[2].split('.')[3]} SET MASKING POLICY {policy[0]};"
        ])

    # 生成行策略SQL
    for policy in data['row_policies']:
        sqls.extend([
            f"CREATE ROW ACCESS POLICY {policy[0]} AS {policy[1]};",
            f"ALTER TABLE {policy[3]} ADD ROW ACCESS POLICY {policy[0]} ON ({policy[2]});"
        ])

    return sqls

if __name__ == "__main__":
    permission_data = get_snowflake_permissions()
    
    print("=== 权限配置描述 ===")
    for desc in generate_descriptions(permission_data):
        print(desc)
    
    print("\n=== 权限重建SQL ===")
    for sql in generate_sql_statements(permission_data):
        print(sql)

    # 可选:将结果保存为DataFrame
    df_role_grants = pd.DataFrame(permission_data['role_grants'], 
        columns=['被授权角色', '授权角色'])
    df_table_priv = pd.DataFrame(permission_data['table_privileges'],
        columns=['角色', '数据库', '模式', '表', '权限'])

输出示例:

复制代码
=== 权限配置描述 ===
角色 priv_hr_rw 被授予给 dept_hr,实现权限继承
角色 priv_finance_ro 在表 finance_db.salary.reports 拥有 SELECT 权限
存在限制访问视图 finance_db.salary.v_restricted_salary,定义:SELECT employee_id, department, base_salary...
列 hr_db.employee.contacts.phone 应用数据掩码策略 phone_mask,策略逻辑:CASE WHEN CURRENT_ROLE() IN ('DEPT_SALES') THEN '***-***-' || RIGHT(val, 4)...

=== 权限重建SQL ===
GRANT ROLE priv_hr_rw TO ROLE dept_hr;
GRANT SELECT ON finance_db.salary.reports TO ROLE priv_finance_ro;
CREATE MASKING POLICY phone_mask AS (val STRING)...
ALTER TABLE hr_db.employee.contacts MODIFY COLUMN phone SET MASKING POLICY phone_mask;

关键实现逻辑说明:

  1. 数据采集:通过Snowflake系统视图获取五类关键信息

    • 角色继承关系
    • 表级权限分配
    • 视图定义及访问控制
    • 动态数据掩码策略
    • 行级访问策略
  2. 自然语言转换:将原始数据转换为易于理解的描述

    • 使用GRANT ROLE语句解析角色继承
    • 通过视图定义识别列级访问控制
    • 解析策略定义描述安全逻辑
  3. SQL重建:生成可重复执行的权限配置语句

    • 保持原始权限配置的精确重建
    • 处理策略定义中的Lambda表达式
    • 自动生成ALTER语句应用策略

使用注意事项:

  1. 需要确保执行账号具有ACCOUNTADMIN权限
  2. 系统视图数据可能存在最长2小时的延迟
  3. 视图定义中的敏感信息需要进行脱敏处理
  4. 生成的SQL需在测试环境验证后上生产

建议结合Snowflake的ACCESS_HISTORY视图进行权限使用分析,并通过定期运行此脚本实现权限配置的版本化管理。

相关推荐
serve the people几秒前
python环境搭建 (十三) httpx和aiohttp
开发语言·python·httpx
Allen_LVyingbo1 分钟前
医疗AI新范式:当数理模型开始“计算”生命,传统大模型面临重构(中)
开发语言·人工智能·python·自然语言处理·重构·知识图谱
时艰.4 分钟前
Java 线程池 — ThreadPoolExecutor
java·开发语言·python
七夜zippoe7 分钟前
时间序列分析实战:从平稳性检验到Prophet与LSTM预测
人工智能·python·机器学习·arima·时间序列·prophet
多恩Stone12 分钟前
【3D-AICG 系列-2】Trellis 2 的O-voxel (上) Shape: Flexible Dual Grid
人工智能·python·算法·3d·aigc
AAD555888997 小时前
数字仪表LCD显示识别与读数:数字0-9、小数点及单位kwh检测识别实战
python
开源技术8 小时前
Python Pillow 优化,打开和保存速度最快提高14倍
开发语言·python·pillow
Li emily9 小时前
解决港股实时行情数据 API 接入难题
人工智能·python·fastapi
wfeqhfxz258878210 小时前
农田杂草检测与识别系统基于YOLO11实现六种杂草自动识别_1
python
mftang10 小时前
Python 字符串拼接成字节详解
开发语言·python