Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aws-kms] Limit default KMS policy (allowAccountToAdmin) to ROOT only #8977

Closed
OlivierPT opened this issue Jul 9, 2020 · 7 comments · Fixed by #11918
Closed

[aws-kms] Limit default KMS policy (allowAccountToAdmin) to ROOT only #8977

OlivierPT opened this issue Jul 9, 2020 · 7 comments · Fixed by #11918
Assignees
Labels
@aws-cdk/aws-kms Related to AWS Key Management effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. p2

Comments

@OlivierPT
Copy link

OlivierPT commented Jul 9, 2020

[Not a Contribution]

Default KMS policy created with allowAccountToAdmin() function (trustAccountIdentities=false) is too large and allow all IAM entities to manage the Key.
At least, there should be an additionnal option to restrict it to ROOT only. Or restriction to ROOT only should be the default option.

Proposed solution is to add a condition in the statement as below:

{
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AccountID:root"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion",
                "kms:GenerateDataKey",
                "kms:TagResource",
                "kms:UntagResource"
            ],
            "Resource": "*",
            "Condition": {
                "ArnLike": {
                    "aws:PrincipalArn": "arn:aws:iam::AccountID:root"
                }
            }
        }

Reproduction Steps

Create a KMS key with default policy:

new kms.Key(this, 'KmsKey', {
      alias: 'kms-key',
      enableKeyRotation: true
    });

Error Log

No error produced by CDK

Environment

  • CDK CLI Version: 1.49.1
  • Module Version: aws-kms
  • Node.js Version: v12.13.1
  • OS: All
  • Language: all
@github-actions github-actions bot added the @aws-cdk/aws-kms Related to AWS Key Management label Jul 9, 2020
@SomayaB SomayaB added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jul 9, 2020
@SomayaB SomayaB assigned njlynch and unassigned skinny85 Jul 10, 2020
@njlynch
Copy link
Contributor

njlynch commented Jul 21, 2020

Thanks for filing this request.

We are consulting internally with the KMS team about the implications of this request to ensure we're modeling this properly, and understand the impacts, as we generally discourage root-user access where possible. We will update this issue once we have some more guidance.

@SomayaB SomayaB removed the needs-triage This issue or PR still needs to be triaged. label Jul 22, 2020
@njlynch
Copy link
Contributor

njlynch commented Jul 23, 2020

In the meantime, as a work-around, you can use escape hatches to alter the policy assigned to the default key. I quickly verified this generated the policy you referenced above:

const key = new Key(stack, 'MyKey');
const keyPolicyAsJson = ((key.node.defaultChild as CfnKey).keyPolicy as iam.PolicyDocument).toJSON();
keyPolicyAsJson.Statement[0].Condition = { ArnLike: { AWS: new iam.AccountRootPrincipal().arn } };
(key.node.defaultChild as CfnKey).keyPolicy = iam.PolicyDocument.fromJson(keyPolicyAsJson);

@OlivierPT
Copy link
Author

OlivierPT commented Jul 23, 2020

Hi,

Thank you for this tip. I will test it.
Regarding avoid root-user access, I fully agree. So maybe a possibility would be to be able to provide "admin role(s)" to the construct so we avoid to have the policy using :

Principal:` { "AWS": "arn:aws:iam::AccountID:root" }

@njlynch
Copy link
Contributor

njlynch commented Aug 4, 2020

@OlivierPT,

How has the work-around worked out for you?

I think there are potentially two follow-ups here:

  1. Make it easier for customers to specify key admins to be added to the key admin policy. In line with best practices, this would be in addition to, not instead of, the account root as key admin. Restricting access to the key in this case is done via IAM policies -- same as most other services. This would be the recommended way to add new key admins to the policy.

  2. Provide users who have a custom key policy with the option of "opting out" of the default key policy. This would allow restricting key admin to only specific users or roles, with the acknowledgement that if those users or roles are removed, the key is effectively locked and cannot be administered without contacting support.

It sounds like for your use case, #2 (or the workaround already provided) is what you need. Can you confirm something like that would suit your needs? I am picturing a new boolean for KeyProps (e.g., KeyProps.excludeDefaultKeyPolicy) that can be specified along with a policy (KeyProps.policy) that would just take the provided policy as-is without adding any of the "default" admin policies.

@njlynch njlynch added effort/small Small work item – less than a day of effort p2 labels Aug 4, 2020
@OlivierPT
Copy link
Author

Hello @njlynch,

Your proposition for the workaround worked fine for us. We didn't implement it exactly as you proposed but we were able to use the escape hatches solution to get what we wanted. That was a great proposition since we were not aware of this capacity with CDK.

Regarding the follow-up you proposed. They look good indeed and I think they would allow us to implement our need in a more standard way. To be sure, that would be interesting to see exactly what would be the generated policies... mainly for the proposal (1). But I think that with the combination of the 2 proposals, it will match.

Thank you,

@0xjjoyy
Copy link

0xjjoyy commented Dec 1, 2020

Make it easier for customers to specify key admins to be added to the key admin policy. In line with best practices, this would be in addition to, not instead of, the account root as key admin. Restricting access to the key in this case is done via IAM policies -- same as most other services. This would be the recommended way to add new key admins to the policy.

It would help with a lot of use cases if the CDK should considers allowing users to customize the entirety of their key policy. Particularly when the documentation states that the default can be overriden, though doesn't infact override the default policy.

#10575

https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_kms/Key.html

policy (Optional[PolicyDocument]) – Custom policy document to attach to the KMS key. Default: - A policy document with permissions for the account root to administer the key will be created.

njlynch added a commit that referenced this issue Dec 7, 2020
… (under feature flag)

In #5575, a new flag (`trustAccountIdentities`) was introduced which -- when set
-- changes the default key policy from a custom key admin policy to one that
grants all access to the key to the root account user. This key policy matches
the default policy when a key is created via the KMS APIs or console.

For backwards-compatibility reasons, the default for `trustAccountIdentities`
had to be set to `false`. Without the flag explicitly set, the default key
policy is one that (a) doesn't match the KMS-recommended admin policy and (b)
doesn't explicitly enable IAM principal policies to acccess the key. This means
that all usage operations (e.g., Encrypt, GenerateDataKey) must be added to both
the key policy and to the principal policy.

This change introduces a new feature flag to flip the default behavior of the
`trustAccountIdentities` flag, so new keys created will have the sane defaults
matching the KMS recommended best practices.

As a related change, this feature flag also changes the behavior when a user
passes in `policy` when creating a Key. Without the feature flag set, the policy
is always appended to the default key policy. With the feature flag set, the
policy will *override* the default key policy, enabling users to opt-out of the
default key policy to introduce a more restrictive policy if desired. This also
matches the KMS API behavior, where a policy provided by the user will override
the defaults.

Marking this PR as `requires-two-approvers` to ensure this PR gets an
appropriately-critical review.

BREAKING CHANGE: change the default value of trustAccountIdentities to true,
which will result in the key getting the KMS-recommended default key
policy. This is enabled through the '@aws-cdk/aws-kms:defaultKeyPolicies'
feature flag.

fixes #8977
fixes #10575
fixes #11309
njlynch added a commit that referenced this issue Dec 7, 2020
… (under feature flag)

In #5575, a new flag (`trustAccountIdentities`) was introduced which -- when set
-- changes the default key policy from a custom key admin policy to one that
grants all access to the key to the root account user. This key policy matches
the default policy when a key is created via the KMS APIs or console.

For backwards-compatibility reasons, the default for `trustAccountIdentities`
had to be set to `false`. Without the flag explicitly set, the default key
policy is one that (a) doesn't match the KMS-recommended admin policy and (b)
doesn't explicitly enable IAM principal policies to acccess the key. This means
that all usage operations (e.g., Encrypt, GenerateDataKey) must be added to both
the key policy and to the principal policy.

This change introduces a new feature flag to flip the default behavior of the
`trustAccountIdentities` flag, so new keys created will have the sane defaults
matching the KMS recommended best practices.

As a related change, this feature flag also changes the behavior when a user
passes in `policy` when creating a Key. Without the feature flag set, the policy
is always appended to the default key policy. With the feature flag set, the
policy will *override* the default key policy, enabling users to opt-out of the
default key policy to introduce a more restrictive policy if desired. This also
matches the KMS API behavior, where a policy provided by the user will override
the defaults.

Marking this PR as `requires-two-approvers` to ensure this PR gets an
appropriately-critical review.

BREAKING CHANGE: change the default value of trustAccountIdentities to true,
which will result in the key getting the KMS-recommended default key
policy. This is enabled through the '@aws-cdk/aws-kms:defaultKeyPolicies'
feature flag.

fixes #8977
fixes #10575
fixes #11309
@mergify mergify bot closed this as completed in #11918 Dec 9, 2020
mergify bot pushed a commit that referenced this issue Dec 9, 2020
… (under feature flag) (#11918)

In #5575, a new flag (`trustAccountIdentities`) was introduced which -- when set
-- changes the default key policy from a custom key admin policy to one that
grants all access to the key to the root account user. This key policy matches
the default policy when a key is created via the KMS APIs or console.

For backwards-compatibility reasons, the default for `trustAccountIdentities`
had to be set to `false`. Without the flag explicitly set, the default key
policy is one that (a) doesn't match the KMS-recommended admin policy and (b)
doesn't explicitly enable IAM principal policies to acccess the key. This means
that all usage operations (e.g., Encrypt, GenerateDataKey) must be added to both
the key policy and to the principal policy.

This change introduces a new feature flag to flip the default behavior of the
`trustAccountIdentities` flag, so new keys created will have the sane defaults
matching the KMS recommended best practices.

As a related change, this feature flag also changes the behavior when a user
passes in `policy` when creating a Key. Without the feature flag set, the policy
is always appended to the default key policy. With the feature flag set, the
policy will *override* the default key policy, enabling users to opt-out of the
default key policy to introduce a more restrictive policy if desired. This also
matches the KMS API behavior, where a policy provided by the user will override
the defaults.

Marking this PR as `requires-two-approvers` to ensure this PR gets an
appropriately-critical review.

BREAKING CHANGE: change the default value of trustAccountIdentities to true,
which will result in the key getting the KMS-recommended default key
policy. This is enabled through the '@aws-cdk/aws-kms:defaultKeyPolicies'
feature flag.

fixes #8977
fixes #10575
fixes #11309

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

github-actions bot commented Dec 9, 2020

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

flochaz pushed a commit to flochaz/aws-cdk that referenced this issue Jan 5, 2021
… (under feature flag) (aws#11918)

In aws#5575, a new flag (`trustAccountIdentities`) was introduced which -- when set
-- changes the default key policy from a custom key admin policy to one that
grants all access to the key to the root account user. This key policy matches
the default policy when a key is created via the KMS APIs or console.

For backwards-compatibility reasons, the default for `trustAccountIdentities`
had to be set to `false`. Without the flag explicitly set, the default key
policy is one that (a) doesn't match the KMS-recommended admin policy and (b)
doesn't explicitly enable IAM principal policies to acccess the key. This means
that all usage operations (e.g., Encrypt, GenerateDataKey) must be added to both
the key policy and to the principal policy.

This change introduces a new feature flag to flip the default behavior of the
`trustAccountIdentities` flag, so new keys created will have the sane defaults
matching the KMS recommended best practices.

As a related change, this feature flag also changes the behavior when a user
passes in `policy` when creating a Key. Without the feature flag set, the policy
is always appended to the default key policy. With the feature flag set, the
policy will *override* the default key policy, enabling users to opt-out of the
default key policy to introduce a more restrictive policy if desired. This also
matches the KMS API behavior, where a policy provided by the user will override
the defaults.

Marking this PR as `requires-two-approvers` to ensure this PR gets an
appropriately-critical review.

BREAKING CHANGE: change the default value of trustAccountIdentities to true,
which will result in the key getting the KMS-recommended default key
policy. This is enabled through the '@aws-cdk/aws-kms:defaultKeyPolicies'
feature flag.

fixes aws#8977
fixes aws#10575
fixes aws#11309

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-kms Related to AWS Key Management effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. p2
Projects
None yet
5 participants