How do I get AWS cross-account KMS keys to work?

2019-06-06 07:04发布

I'm trying to set up cross-account access to allow for an external account to use my KMS key to decrypt data from an S3 bucket. I have the key, policies, roles set up with what I believe is the correct grants but I can't describe the key from the external account. Hoping to get some input as to what I'm doing wrong.

Account 111: Key with policy grant to root of external account (999)

{
  "Version": "2012-10-17",
  "Id": "key-consolepolicy-3",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow use of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::999:root"
        ]
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow attachment of persistent resources",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::999:root"
        ]
      },
      "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "kms:GrantIsForAWSResource": "true"
        }
      }
    }
  ]
}

Role in account 999 with the policy attached granting access to key from 111:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:RevokeGrant",
                "kms:CreateGrant",
                "kms:ListGrants"
            ],
            "Resource": "arn:aws:kms:us-west-2:111:key/abc-def"
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": true
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:DescribeKey"
            ],
            "Resource": "arn:aws:kms:us-west-2:111:key/abc-def"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "kms:GenerateDataKey",
                "kms:ReEncryptTo",
                "kms:ReEncryptFrom"
            ],
            "Resource": "*"
        }
    ]
}

Yet when I assume the role in 999 using aws-shell:

aws> kms describe-key --key-id=abc-def

An error occurred (NotFoundException) when calling the DescribeKey operation: Key 'arn:aws:kms:us-west-2:999:key/abc-def' does not exist

2条回答
老娘就宠你
2楼-- · 2019-06-06 07:35

Pay special attention to the key policy conditions if everything seems to be normal. For ex a policy like below seems to be giving access to AccountA to use the key.

    {
        "Sid": "Allow use of the key for SSM only",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::AccountA:root"
        },
        "Action": [
            "kms:Encrypt",
            "kms:Decrypt",
            "kms:ReEncrypt*",
            "kms:GenerateDataKey*"
        ],
        "Resource": "*",
        "Condition": {
            "StringLike": {
                "kms:ViaService": [
                    "ssm.*.amazonaws.com",
                    "autoscaling.*.amazonaws.com"
                ]
            }
        }
    },
    {
        "Sid": "Allow reading of key metadata",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::AccountA:root"
        },
        "Action": "kms:DescribeKey",
        "Resource": "*"
    },
    {
        "Sid": "Allow attachment of persistent resources",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::AccountA:root"
        },
        "Action": [
            "kms:CreateGrant",
            "kms:ListGrants",
            "kms:RevokeGrant"
        ],
        "Resource": "*"
    }

However if you check the condition more carefully you will see the use of the Key is restricted to certain services with "viaService" condition.

You can also use a kms:ViaService condition key to deny permission to use a CMK when the request comes from particular services.

More info AWS Doc Reference.

In this case the key is restricted to ec2 and auto-scaling. If you execute "aws kms describe-key" from and ec2 instance you would be able to see a response coming, but you wouldn't be able to use it for other services like AWS Secret Manager etc. In other words the following command will fail from the same ec2 instance.

aws secretsmanager create-secret --name MyTestSecret \
--description "My test database secret created with the CLI" \
--kms-key-id arn:aws:kms:GIVEN_KEY_ID
查看更多
够拽才男人
3楼-- · 2019-06-06 07:40

Your key, role and policies are set up correctly. When you call describe-key on a Customer Master Key (CMK) that is on a different AWS account, you have to specify the key ARN or alias ARN in the value of the key-id parameter.

From the official docs:

To perform this operation on a CMK in a different AWS account, specify the key ARN or alias ARN in the value of the KeyId parameter.

That said, if you do something like below, it will work:

aws> kms describe-key --key-id=arn:aws:kms:us-west-2:111:key/abc-def
查看更多
登录 后发表回答