mountHouli
mountHouli

Reputation: 131

Other AWS User is (Incorrectly) Able to Access My AWS SecretsManager Secret Value, That's Encrypted With My AWS KMS CMK

I'm using my AWS KMS CMK to encrypt and AWS SecretsManager Secret, but my coworker can see the secret value!!

Any idea why?

Technical Details:

I'm using AWS SAM CLI to deploy this.

Here's my AWS SAM template:

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Parameters:
  SecretValue:
    Type: String
  KmsCmkId: 
    Type: String

Resources:
  MySecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      SecretString:
        Ref: SecretValue
      KmsKeyId: !Ref KmsCmkId

I build and deploy it with this:

sam build ; sam deploy --guided --parameter-overrides SecretValue=ABC KmsCmkId=REDACTED

My Debugging To-Date:

{
    "Id": "key-consolepolicy-3",
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::REDACTED:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::REDACTED:user/MY_COWORKER"
                ]
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::REDACTED:user/ME"
            },
            "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::REDACTED:user/ME"
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

Upvotes: 1

Views: 912

Answers (1)

mountHouli
mountHouli

Reputation: 131

Thanks so much to @JohnRotenstein for pointing me in the right direction, with his reply to my question, above!

Solution Background 1

As John asked, above when I say above that my coworker "is an admin" on our account, what I mean is that his IAM user account has AWS Managed Policy Administrator Access which gives "Full Access" to (as far as I know) everything or just about everything in AWS (including KMS!!).

Solution Background 2

Indeed, in my question above, my key policy (which is the default key policy) includes this statement:

{
    "Sid": "Enable IAM User Permissions",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::REDACTED:root"
    },
    "Action": "kms:*",
    "Resource": "*"
},

And per @JohnRotenstein 's comments and these AWS docs, this policy statement allows IAM policies to access and use this key--if those policies specify the right permissions.

Thus (as far as I can tell), this would allow quite a number of folks (anyone who can edit IAM policies on my company's account) the ability to give themself a policy that allows them to do whatever they want with my KMS key! (which is not safe!)

I need to clamp this down. (solution below!)

Solution Background 3

In the "default KMS key policy" (which I posted in my question above), you'll see that key administrators can kms:Put*. Allows them to kms:PutKeyPolicy, which would allow them to change the policy to give themselves (or anyone) kms:Decrypt, which would allow them to decrypt my Secrets Manager secret and get the secret value!

I need to clamp this down as well...

The Solution

The key policy below:

  • Ensures only my Lambda function can (via the policy statement I give to the IAM role that executes the Lambda function) use an IAM policy to use this key, and they can only do kms:Decrypt

  • Allows only the key user (me) to do encryption and decryption operations (except the Lambda function, of course; see above)

  • Though key administrators can't use my key to encrypt or decrypt things (or kms:PutKeyPolicy), they can do all admin tasks, such as deleting the KMS key or its grants.

{
  "Id": "mount-houlis-secure-kms-key-policy",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Allow use of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": THE_ARN_OF_THE_IAM_USER_WHO_OWNS_THE_SECRET____WHICH_IS_ME
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey",
        "kms:GetKeyPolicy",
        "kms:PutKeyPolicy"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Admins",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          ARNS_OF_VARIOUS,
          KEY_ADMINISTRATORS,
          AND_ME
        ]
      },
      "Action": [
        "kms:CancelKeyDeletion",
        "kms:CreateAlias",
        "kms:DeleteAlias",
        "kms:DescribeKey",
        "kms:DisableKey",
        "kms:DisableKeyRotation",
        "kms:EnableKey",
        "kms:EnableKeyRotation",
        "kms:GetKeyPolicy",
        "kms:GetKeyRotationStatus",
        "kms:ListGrants",
        "kms:ListKeyPolicies",
        "kms:ListResourceTags",
        "kms:ListRetirableGrants",
        "kms:RetireGrant",
        "kms:RevokeGrant",
        "kms:ScheduleKeyDeletion",
        "kms:TagResource",
        "kms:UntagResource",
        "kms:UpdateAlias",
        "kms:UpdateKeyDescription"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow Lambda function to do Action secretsmanager:GetSecretValue",
      "Effect": "Allow",
      "Principal": {
        "AWS": ARN_OF_THE_ROLE_THAT_YOUR_LAMBDA_FUNCTION_EXECUTES_AS____SHOULD_BE_arn:aws:iam::ACCOUNT_NUMBER:role/your-lambda-function-role-name
      },
      "Action": "kms:Decrypt",
      "Resource": "*"
    }
  ]
}

Upvotes: 1

Related Questions