如何获取AWS组织中特定账号关联的所有SCP策略(含继承自定义策略)?
问题分析与解决方法
核心问题
list_policies_for_target API仅返回直接附加到指定目标(账号或OU)的SCP,不会自动返回从父OU继承的策略。另外,你可能因为以下原因看不到自定义SCP:
- 调用API的IAM身份权限不足,无法读取所有SCP
- 结果存在分页,当前代码只获取了第一页数据
- 自定义SCP是附加在父OU上,而非直接绑定到目标账号
解决步骤
1. 确认权限要求
确保你的IAM身份(或SAML角色)拥有以下Organizations权限:
organizations:ListPoliciesForTargetorganizations:ListParents(用于遍历父OU层级)organizations:ListRoots(如果需要从根节点开始遍历)
2. 处理分页结果
AWS API返回结果可能分页,当前代码只获取了第一页,需要通过分页器循环获取所有数据:
session = boto3.Session(profile_name='saml') org_client = session.client('organizations', region_name='us-east-1') def get_all_direct_scps(target_id): scps = [] paginator = org_client.get_paginator('list_policies_for_target') # 遍历所有分页结果 for page in paginator.paginate(TargetId=target_id, Filter='SERVICE_CONTROL_POLICY'): scps.extend(page['Policies']) return scps # 调用示例 direct_scps = get_all_direct_scps('xxxxxxxxxxxx') print(direct_scps)
3. 遍历父OU获取继承的SCP
要拿到账号继承的所有SCP,需要递归遍历账号的所有父OU(包括根节点),收集每个节点直接附加的SCP:
def get_all_inherited_scps(account_id): org_client = session.client('organizations', region_name='us-east-1') all_scps = [] current_target = account_id # 循环遍历所有父节点(OU和根) while True: # 获取当前节点的直接SCP paginator = org_client.get_paginator('list_policies_for_target') for page in paginator.paginate(TargetId=current_target, Filter='SERVICE_CONTROL_POLICY'): all_scps.extend(page['Policies']) # 获取父节点,无父节点时终止循环 parents = org_client.list_parents(ChildId=current_target)['Parents'] if not parents: break current_target = parents[0]['Id'] # 去重,避免同一策略被多个节点重复附加 unique_scps = {scp['Id']: scp for scp in all_scps}.values() return list(unique_scps) # 调用示例 all_scps = get_all_inherited_scps('xxxxxxxxxxxx') for scp in all_scps: print(f"策略名称: {scp['Name']}, 是否托管: {scp['AwsManaged']}")
4. 验证目标ID正确性
确认传入的TargetId是正确的12位账号ID,而非OU或根节点ID。如果要查看OU的SCP,需传入对应的OU ID。
额外检查
- 自定义SCP必须附加到账号/OU/根节点才会生效,仅创建未绑定的SCP不会被API返回
- 检查SCP状态是否为
ENABLED,禁用的SCP不会被纳入返回结果
内容的提问来源于stack exchange,提问作者Rio
相关产品推荐
相关产品推荐

