具有多个条件的AWS IAM策略语法错误

fic*_*tat 0 amazon-web-services amazon-iam

我的政策不适用于AWS.JSONlint说我有一个有效的json.有一个语法问题,但我没有看到它.

此策略包含以下错误:策略不符合身份和访问管理(IAM)策略语法.有关IAM策略语法的更多信息,请参阅AWS IAM策略.

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": "ec2:*",
        "Resource": "*",
        "Condition": {
             "StringEquals": {"ec2:ResourceTag/sf_env": "dev",
             "StringEquals": {"ec2:Region": "us-west-2"
            }
          }
       }
    },
    {
        "Effect": "Allow",
        "Action": "rds:*",
        "Resource": "*",
        "Condition": {
          "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
          "StringEquals": { "ec2:Region": "us-west-2"
            }
          }
       }
    },
    {
        "Sid": "AllowHealthCheckOnly",
        "Effect": "Allow",
        "Action": "elasticloadbalancing:Describe*",
        "Resource": "*",
        "Condition": {
            "StringEquals":{ "ec2:ResourceTag/sf_env": "dev",
            "StringEquals":{ "ec2:Region": "us-west-2"
          }
       }
    }
    },
    {
        "Sid": "ConfigureHealthCheckOnly",
        "Effect": "Allow",
        "Action": "elasticloadbalancing:ConfigureHealthCheck",
        "Resource": "arn:aws:elasticloadbalancing:us-west-2:xxxxxxxxxxxx:loadbalancer/instance1",
        "Condition": {
            "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
            "StringEquals": { "ec2:Region": "us-west-2"
            }
          }
       }
    },
    {
        "Sid": "FullElasticCacheManagedPolicyPermissions",
        "Effect": "Allow",
        "Action": [
            "elasticache:*",
            "ec2:DescribeAvailibilityZones",
            "ec2:DescribeVpcs",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeSeucrityGroups",
            "cloudwatch:GetMetricStatistics",
            "cloudwatch:DescribeAlarms",
            "sns:ListTopics",
            "sns:ListSubscriptions"
        ],
        "Resource": "*",
        "Condition": {
            "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
            "StringEquals": { "ec2:Region": "us-west-2"
            }
          }
       }
    }
]
Run Code Online (Sandbox Code Playgroud)

}

Mic*_*bot 6

JSONLint说你有语法上有效的JSON,你做...但问题是你成功编码的数据......没有语义意义.

只看你的最后一个条件,你写道:

    "Condition": {
        "StringEquals": { "ec2:ResourceTag/sf_env": "dev",
        "StringEquals": { "ec2:Region": "us-west-2"
        }
      }
   }
Run Code Online (Sandbox Code Playgroud)

请注意:由于以下是从较大的JSON对象中提取的键/值片段,因此您必须将其中的每一个嵌套在一个额外的外部{大括号中,}以便JSONLint对其进行解析,实际上它是一个有效的JSON表示,在没有周围结构的情况下自行评估.我在测试创建示例时将这些添加到JSONLint输入中,并将它们从输出中删除,希望为了清楚起见.

JSONLint重新格式化上面的内容,以显示您正在进行的通信:

"Condition": {
            "StringEquals": {
                "ec2:ResourceTag/sf_env": "dev",
                "StringEquals": {
                    "ec2:Region": "us-west-2"
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

JSON的优势在于其简单的结构和约束:它有{对象}(键/值对,其中键是一个字符串,而值恰好是这句话中任何地方提到的任何类型的东西之一)... [数组](列表)值...)"字符串"...数字(未引用)...布尔(truefalse,未引用)...和null(null,未引用).

StringEquals正如你所表达的那样,上面是一个有两个键的对象ec2:ResourceTag/sf_env(它有一个字符串作为它的值)......和StringEquals(第二个外观,它有另一个嵌套对象作为它的值).

显然,这不是您的意图,但它是对您提供的内容的正确解释.

请注意,缩进完全是可选的,但JSONLint的输出格式以有意义的方式使用缩进.注意到如何"ec2:ResourceTag/sf_env"以及"ec2:Region"在(使用非JSON的术语)"兄弟姐妹"(在数据结构的同级别),不同的缩进你的红旗,一切都没有得到很好的.

纠正大括号的位置,你可能打算写一些更像这样的东西:

"Condition": {
    "StringEquals": { "ec2:ResourceTag/sf_env": "dev" },
    "StringEquals": { "ec2:Region": "us-west-2" }
}
Run Code Online (Sandbox Code Playgroud)

这看起来更合理,虽然它几乎肯定是不正确的,因为反序列化的工作方式:现在你StringEquals在同一个对象中有两个键,虽然JSON标准似乎没有禁止这个,但行为最多是未定义,并且反序列化的许多或大多数库会将上述内容解释为:

"Condition": {
    "StringEquals": {
        "ec2:Region": "us-west-2"
    }
}
Run Code Online (Sandbox Code Playgroud)

以后的键及其值可以合理地预期取代相同的早期键及其值.

这就是JSONLint如何解释它.在JSON对象中,单个键只能拥有一个值 - 记住"值"意味着一个对象,数组,字符串,数字,布尔值或空值.当存在多个值时,它必须在内部结构内正确嵌套.

那么,什么是正确的表示?

"Condition": {
    "StringEquals": {
        "ec2:ResourceTag/sf_env": ["dev"],
        "ec2:Region": ["us-west-2"]
    }
}
Run Code Online (Sandbox Code Playgroud)

作为值的对象Condition有一个键StringEquals,其值是具有两个键的对象,ec2:ResourceTag/sf_env并且ec2:Region; 这些键中的每一个都具有一个或多个字符串的数组作为其值.

因此,如果需要,当值显示在我显示的数组中时,您不仅可以使用多个StringEquals测试,每个测试也可以匹配多个值中的任何一个.例如,["dev","prod"]代替["dev"]将匹配dev或者prod.

如果每个只有一个值,IAM似乎只支持使用字符串而不是数组,例如"dev"替换["dev"](也是有效的JSON),但我观察到的文档示例往往会显示出来,如上所述,如{ key1: [ "list" ], key2: ["list"] }. ..等等,如果你现在以这种方式格式化,如果你想在以后允许更多可能的值,它会更加直观.


小智 5

我最近遇到了这个问题。以下是构建它的方法:

    "Condition": {
      "ForAllValues:StringEquals": { 
        "ec2:ResourceTag/sf_env": "dev",
        "ec2:Region": "us-west-2"
      }
    }
Run Code Online (Sandbox Code Playgroud)


fic*_*tat -2

JSON 中不能有两个 StringEqual。我使用 StringLike 作为解决方法。这篇文章帮助我解决了这个问题。我的策略现在具有正确的 AWS 语法!

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": "ec2:*",
        "Resource": "*",
        "Condition": {
             "StringEquals": {
             "ec2:ResourceTag/sf_env": "dev"
             },
             "StringLike": {"ec2:Region": "us-west-2"
          }
        }     
    },
    {
        "Effect": "Allow",
        "Action": "rds:*",
        "Resource": "*",
        "Condition": {
          "StringEquals": { 
              "ec2:ResourceTag/sf_env": "dev"
          },
          "StringLike": { 
              "ec2:Region": "us-west-2"
            }
          }
    },
    {
        "Sid": "AllowHealthCheckOnly",
        "Effect": "Allow",
        "Action": "elasticloadbalancing:Describe*",
        "Resource": "*",
        "Condition": {
            "StringEquals":{ 
                "ec2:ResourceTag/sf_env": "dev"
        }, 
            "StringLike":{ 
                "ec2:Region": "us-west-2"
          }
       }
    },
    {
        "Sid": "ConfigureHealthCheckOnly",
        "Effect": "Allow",
        "Action": "elasticloadbalancing:ConfigureHealthCheck",
        "Resource": "arn:aws:elasticloadbalancing:us-west-2:xxxxxxxxxxxx:loadbalancer/instance1",
        "Condition": {
            "StringEquals": { 
                "ec2:ResourceTag/sf_env": "dev"
          },
             "StringLike": { "ec2:Region": "us-west-2"
           }
        }
    },
    {
        "Sid": "FullElasticCacheManagedPolicyPermissions",
        "Effect": "Allow",
        "Action": [
            "elasticache:*",
            "ec2:DescribeAvailibilityZones",
            "ec2:DescribeVpcs",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeSeucrityGroups",
            "cloudwatch:GetMetricStatistics",
            "cloudwatch:DescribeAlarms",
            "sns:ListTopics",
            "sns:ListSubscriptions"
        ],
        "Resource": "*",
        "Condition": {
            "StringEquals": {
                 "ec2:ResourceTag/sf_env": "dev"
            },
            "StringLike": { "ec2:Region": "us-west-2"
            }
          }
    }
]
Run Code Online (Sandbox Code Playgroud)

}