为何定义Secrets策略访问时通配符资源失效?
问题
我有如下Terraform策略(使用jsonencode({}),已精简代码),允许访问所有Secrets:
{ Action = [ "secretsmanager:DescribeSecret", "secretsmanager:List*", "secretsmanager:Get*" ] Effect = "Allow", Resource = [ "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id_dev}:*", ] }
该策略运行正常,但当我尝试限制Resource范围时,未达到预期效果:
{ Action = [ "secretsmanager:DescribeSecret", "secretsmanager:List*", "secretsmanager:Get*" ] Effect = "Allow", Resource = [ "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id_dev}:dev/AWS_*", "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id_dev}:dev/MAIL_*", // .. etc ] }
原本认为该策略应允许访问dev/AWS_KEY、dev/AWS_SECRET、dev/AWS_WHATEVER及MAIL_*系列的Secrets,但实际并非如此,请问遗漏了什么?
原因与解决方法
List类动作不支持资源ARN限制:Secrets Manager的
List*类操作(如ListSecrets)是账户级别的全局操作,这类动作的权限检查不依赖具体的资源ARN,即使你在Resource字段中指定了前缀,这些List动作也无法正确过滤出目标密钥。拆分策略并使用条件过滤:需要将策略拆分为两个独立的Statement,分别处理不同类型的动作:
- 针对
List*动作:使用Resource = "*",通过Condition中的secretsmanager:Name条件来匹配密钥名称前缀。 - 针对
DescribeSecret、Get*等资源级动作:保留原有的资源ARN前缀限制即可。
- 针对
修正后的Terraform策略示例:
jsonencode({ Version = "2012-10-17" Statement = [ # 处理List类动作,通过条件过滤密钥名称前缀 { Action = ["secretsmanager:List*"] Effect = "Allow" Resource = "*" Condition = { StringLike = { "secretsmanager:Name" = [ "dev/AWS_*", "dev/MAIL_*" ] } } }, # 处理资源级动作,用ARN前缀限制 { Action = [ "secretsmanager:DescribeSecret", "secretsmanager:Get*" ] Effect = "Allow" Resource = [ "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id_dev}:dev/AWS_*", "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id_dev}:dev/MAIL_*" ] } ] })
内容的提问来源于stack exchange,提问作者tftd
相关产品推荐
相关产品推荐

