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

fix(secretsmanager): arnForPolicies evaluates to the partial ARN if accessed from a cross-env stack #26308

Merged
merged 7 commits into from
Jul 24, 2023

Conversation

gshpychka
Copy link
Contributor

@gshpychka gshpychka commented Jul 10, 2023

Currently, Secret.secretFullArn returns the partial ARN if the secret is referenced between cross-env stacks.
An obvious practical implication is that grant* methods will produce an incorrect ARN for the IAM policies, since a full ARN is required for cross-environment access.

This PR partially fixes the issue - I reimplemented arnForPolicies to be lazily evaluated. It checks if the value is being accessed across environments and adds -?????? to the ARN if it is.

Now, this does not solve the underlying issue of secretFullArn returning the partial ARN. While it should return undefined, we have to check how the prop is accessed (same environment or cross-env) before we know whether to return the ARN or undefined. If we use a Lazy here, it still cannot return undefined (only any as the closest thing).

So I don't think the underlying cause could be solved currently, that's why I opted for this partial fix that would address the most practical consequence of the bug.

This is a partial fix for #22468.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@gitpod-io
Copy link

gitpod-io bot commented Jul 10, 2023

@aws-cdk-automation aws-cdk-automation requested a review from a team July 10, 2023 16:54
@github-actions github-actions bot added repeat-contributor [Pilot] contributed between 3-5 PRs to the CDK bug This issue is a bug. effort/small Small work item – less than a day of effort p1 labels Jul 10, 2023
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed add Clarification Request to a comment.

@gshpychka
Copy link
Contributor Author

gshpychka commented Jul 10, 2023

Not sure how to go about an integration test - I've written one but then realized that the AWS account number has to be provided (and included in the snapshots) since the stacks have to be environment-specific - what is the process in this case?
Clarification Request

@gshpychka
Copy link
Contributor Author

Hm, the integ tests failed because

      {
       "Action": [
        "secretsmanager:DescribeSecret",
        "secretsmanager:GetSecretValue"
       ],
       "Effect": "Allow",
       "Principal": {
        "AWS": {
         "Fn::Join": [
          "",
          [
           "arn:",
           {
            "Ref": "AWS::Partition"
           },
           ":iam::",
           {
            "Ref": "AWS::AccountId"
           },
           ":root"
          ]
         ]
        },
        "Service": "ecs-tasks.amazonaws.com"
       },
       "Resource": {
        "Ref": "testsecretAttachment19AD251F"
       }
      }

changed to

      {
       "Action": [
        "secretsmanager:DescribeSecret",
        "secretsmanager:GetSecretValue"
       ],
       "Effect": "Allow",
       "Principal": {
        "AWS": {
         "Fn::Join": [
          "",
          [
           "arn:",
           {
            "Ref": "AWS::Partition"
           },
           ":iam::",
           {
            "Ref": "AWS::AccountId"
           },
           ":root"
          ]
         ]
        }
       },
       "Resource": {
        "Ref": "testsecretAttachment19AD251F"
       }
      },
      {
       "Action": [
        "secretsmanager:DescribeSecret",
        "secretsmanager:GetSecretValue"
       ],
       "Effect": "Allow",
       "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
       },
       "Resource": {
        "Ref": "testsecretAttachment19AD251F"
       }
      }

Any idea why this could be?

@mrgrain mrgrain closed this Jul 11, 2023
@mrgrain mrgrain reopened this Jul 11, 2023
@mrgrain
Copy link
Contributor

mrgrain commented Jul 11, 2023

(Sorry I accidentally closed this)

@mrgrain
Copy link
Contributor

mrgrain commented Jul 11, 2023

Hm, the integ tests failed because

Which test is this?

Any idea why this could be?

I suspect the policy deduplication mechanism (search for mergeStatements) doesn't think these are combinable anymore. Probably because it is now a lazy token object which are not going to be equal to each other.

@gshpychka
Copy link
Contributor Author

Which test is this?

It is aws-rds/test/integ.serverless-cluster-secret-rotation-custom-names and aws-rds/test/integ.serverless-cluster-secret-rotation

This would make it a breaing change, though.

Regarding an integration test for the fix itself - I'm not really comfortable with making it exempt, but not sure how a env-specific integ test can possibly be implemented.

@aws-cdk-automation aws-cdk-automation added the pr/reviewer-clarification-requested The contributor has requested clarification on feedback, a failing build, or a failing PR Linter run label Jul 11, 2023
@mrgrain mrgrain added effort/medium Medium work item – several days of effort and removed effort/small Small work item – less than a day of effort labels Jul 11, 2023
@mrgrain
Copy link
Contributor

mrgrain commented Jul 11, 2023

Which test is this?

It is aws-rds/test/integ.serverless-cluster-secret-rotation-custom-names and aws-rds/test/integ.serverless-cluster-secret-rotation

This would make it a breaing change, though.

Regarding an integration test for the fix itself - I'm not really comfortable with making it exempt, but not sure how a env-specific integ test can possibly be implemented.

Back to square one then.

Currently, Secret.secretFullArn returns the partial ARN if the secret is referenced between cross-env stacks.

Have you figured out why this happens?

@gshpychka
Copy link
Contributor Author

gshpychka commented Jul 11, 2023

Have you figured out why this happens?

I believe it's because the default implementation of secretFullArn defined in BaseSecret returns this.secretArn and that doesn't change when a secret is used across envs. It seems that this is only overridden in .fromSecret* methods.And secretArn uses Resource.getResourceArnAttribute which in across-env case returns a formatted ARN and ref otherwise.

@gshpychka
Copy link
Contributor Author

Have you figured out why this happens?

I believe it's because the default implementation of secretFullArn defined in BaseSecret returns this.secretArn and that doesn't change when a secret is used across envs. It seems that this is only overridden in .fromSecret* methods.And secretArn uses Resource.getResourceArnAttribute which in across-env case returns a formatted ARN and ref otherwise.

We could change secretFullArn to use a custom function instead of Resource.getResourceArnAttribute and return something else in case of cross-env access, but what do we return?

@mrgrain
Copy link
Contributor

mrgrain commented Jul 12, 2023

We could change secretFullArn to use a custom function instead of Resource.getResourceArnAttribute and return something else in case of cross-env access, but what do we return?

Hm, so I guess that makes secretFullArn broken whenever we have a cross stack reference. CR would be one way, could we also deal with this special case using import/exports or a SSM parameter? For both we should have some code doing something similar already.

@gshpychka
Copy link
Contributor Author

Hm, so I guess that makes secretFullArn broken whenever we have a cross stack reference.

No, it works fine with cross-stack references if in the same environment (using Cfn imports under the hood). The relevant logic for cross-stack references is implemented elsewhere.

@mrgrain
Copy link
Contributor

mrgrain commented Jul 13, 2023

No, it works fine with cross-stack references if in the same environment (using Cfn imports under the hood). The relevant logic for cross-stack references is implemented elsewhere.

Yeah, but could we use the same/similar logic for cross-env?

@gshpychka
Copy link
Contributor Author

gshpychka commented Jul 13, 2023

No, it works fine with cross-stack references if in the same environment (using Cfn imports under the hood). The relevant logic for cross-stack references is implemented elsewhere.

Yeah, but could we use the same/similar logic for cross-env?

Well, Cfn imports don't work cross-env. The cross-env logic is just "resolve the references at synth time".

What do you think we should be focusing on (I'm getting a bit lost in the discussion)?
Do you think the IAM policy merging change could be acceptable? Because whatever we do, seems that there's no way around this.

@gshpychka
Copy link
Contributor Author

Yeah, but could we use the same/similar logic for cross-env?

To make sure we're on the same page - detecting that it's a cross-env reference is not the issue - that's easy. Returning a correct arnForPolicies in this case is easy as well - this PR does that.

We can have secretFullArn return a Lazy as well - and then we can implement the reference with a CR.

But the issue with merging in IAM policies would still be there in both of these cases, as far as I understand.

@mrgrain
Copy link
Contributor

mrgrain commented Jul 13, 2023

Yeah, but could we use the same/similar logic for cross-env?

To make sure we're on the same page - detecting that it's a cross-env reference is not the issue - that's easy. Returning a correct arnForPolicies in this case is easy as well - this PR does that.

We can have secretFullArn return a Lazy as well - and then we can implement the reference with a CR.

But the issue with merging in IAM policies would still be there in both of these cases, as far as I understand.

I'm with you now. Having arnForPolicies a Lazy is probably okay then. I'll need to set aside a bit to look into the merging code if there is a way around it.

@mrgrain
Copy link
Contributor

mrgrain commented Jul 21, 2023

@gshpychka I can't figure out how to push to your branch.

Nervermind. Figured it out.

@mrgrain mrgrain added pr-linter/exempt-integ-test The PR linter will not require integ test changes and removed pr/reviewer-clarification-requested The contributor has requested clarification on feedback, a failing build, or a failing PR Linter run labels Jul 21, 2023
@aws-cdk-automation aws-cdk-automation dismissed their stale review July 21, 2023 17:01

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@mrgrain mrgrain marked this pull request as ready for review July 24, 2023 22:38
@mergify
Copy link
Contributor

mergify bot commented Jul 24, 2023

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: d043a29
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit 0e808d8 into aws:main Jul 24, 2023
5 checks passed
@mergify
Copy link
Contributor

mergify bot commented Jul 24, 2023

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

bmoffatt pushed a commit to bmoffatt/aws-cdk that referenced this pull request Jul 29, 2023
… accessed from a cross-env stack (aws#26308)

Currently, `Secret.secretFullArn` returns the partial ARN if the secret is referenced between cross-env stacks.
An obvious practical implication is that `grant*` methods will produce an incorrect ARN for the IAM policies, since a full ARN is required for cross-environment access.

This PR partially fixes the issue - I reimplemented `arnForPolicies` to be lazily evaluated. It checks if the value is being accessed across environments and adds `-??????` to the ARN if it is.

Now, this does not solve the underlying issue of `secretFullArn` returning the partial ARN. While it should return undefined, we have to check how the prop is accessed (same environment or cross-env) before we know whether to return the ARN or `undefined`. If we use a `Lazy` here, it still cannot return `undefined` (only `any` as the closest thing).

So I don't think the underlying cause could be solved currently, that's why I opted for this partial fix that would address the most practical consequence of the bug.
 
This is a partial fix for aws#22468.

----

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

rv2673 commented Aug 18, 2023

@gshpychka @mrgrain This unfortunately break my app.
However secrets Constructs created through fromSecretCompleteArn, that are used cross region, break completely with this change, since it is treating them as a partialArn.

I believe this is because the condition !this.secretFullArn is used in or condition and is never reached since the cross region condition is short circuiting before secretFullArn is actually checked. So even if full arn is filled it is treated as partialArn.

So either the if block should only be entered if fullArn is undefined and cross-region or arnForPolicies should be overriden in class returned fromSecretAttributes.

This is a nice fix for secrets created(not imported) cross-region which would reduce some complexity in my apps since it has this case too.

@mrgrain
Copy link
Contributor

mrgrain commented Aug 18, 2023

@rv2673 Thanks for letting us know! Would you mind creating a new issue for this and include a code sample for the reproduction. Thank you.

@rv2673
Copy link
Contributor

rv2673 commented Aug 18, 2023

@rv2673 Thanks for letting us know! Would you mind creating a new issue for this and include a code sample for the reproduction. Thank you.

Done #26811

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. effort/medium Medium work item – several days of effort p1 pr-linter/exempt-integ-test The PR linter will not require integ test changes repeat-contributor [Pilot] contributed between 3-5 PRs to the CDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants