aws / aws/aws-cdk

(secretsmanager): Partial ARN used in policies and `secretFullArn` evaluates to the partial ARN when Secret used across environments

Open
#22,468 7 comments 7 reactions 0 assignees View on GitHub
@aws-cdk/aws-secretsmanager bug effort/small p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the bug

When a `Secret` is created and then passed to a cross-env stack (provided the secret has a specified physical name), its internal `arnForPolicies` is its partial ARN without the 6-character suffix. This is wrong, as the generated policies from e.g. `grantRead` cannot use the partial ARN as is - they have to append `-??????` to it.

### Expected Behavior

When doing `Secret.grantRead` in a cross-environment stack, the resulting CF template contains the partial ARN of the secret followed by `-??????`.

### Current Behavior

The partial ARN is used as is.

### Reproduction Steps

Here's a simple Python app:

```python
import os
import aws_cdk as cdk
from aws_cdk import aws_iam as iam, aws_secretsmanager as sm, aws_ssm as ssm

app = cdk.App()

root_env = cdk.Environment(
account=os.environ["CDK_DEFAULT_ACCOUNT"], region="us-east-1"
)
cross_region_env = cdk.Environment(
account=os.environ["CDK_DEFAULT_ACCOUNT"], region="us-west-2"
)

producer_stack = cdk.Stack(app, "producer", env=root_env)
consumer_stack = cdk.Stack(app, "consumer", env=cross_region_env)

secret = sm.Secret(producer_stack, "secret", secret_name="MySecret")
role = iam.Role(consumer_stack, "role", assumed_by=iam.ServicePrincipal("foo"))

secret.grant_read(role)

ssm.StringParameter(consumer_stack, "parameter", string_value=secret.secret_full_arn)

app.synth()
```

Relevant excerpts of the synthed template of the consumer:

```json
"roleDefaultPolicy7C980EBA": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetSecretValue"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":secretsmanager:us-east-1:574067550520:secret:MySecret"
]
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "roleDefaultPolicy7C980EBA",
```

The value of `secretFullArn` evaluates to the partial ARN, which is probably related.
```json
"parameter76C24FC7": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Type": "String",
"Value": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":secretsmanager:us-east-1:574067550520:secret:MySecret"
]
]
}
},
"Metadata": {
"aws:cdk:path": "consumer/parameter/Resource"
}
}
},
```

### Possible Solution

_No response_

### Additional Information/Context

In addition, the secret's `secretFullArn` prop evaluates to the partial ARN at synth time (in the consumer stack, that is).

### CDK CLI Version

2.45.0

### Framework Version

_No response_

### Node.js Version

18.9.0

### OS

Linux

### Language

Python

### Language Version

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

The issue names Secret.grant_read and secret_full_arn as the entry points; start by tracing how the producer secret is represented in the consumer stack and how the synthesized policy and resource values are formed. Done means the reproduced consumer template appends -?????? for policy use and secret_full_arn resolves to the full ARN.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python, typescript
Domain
cloud, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
39/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.