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
feat(secretsmanager): create secrets with specified values #18098
Conversation
Enables customers to supply their own secret value in the cases where an auto- generated value is not viable. The secret value is typed to highlight the inheret lack of safety with creating secret values via CloudFormation; if a plaintext secret is provided, this secret will be visible anywhere the CloudFormation template is, including the AWS Console, SDKs, and CLIs. An unsafe `fromUnsafePlaintext` method and slightly safer `fromToken` method are exposed to highlight the potential risks and hopefully encourage safe usage. The latter is intended to be used directly with a Ref or GetAtt call from another (Custom) Resource, such as storing the value of a User SecretAccessKey or storing a password generated from a custom resource. As an implementation detail, this API has been created using the new standard for experimental APIs, via suffixing with `Beta1`. This allow us to make breaking changes by deprecating the `Beta1` version and creating an improved `Beta2` version. I've chosen to do this in this case because this has been a relatively controversial feature to decide to implement, and the criteria for what makes a secret "safe" may evolve over time. I am open to feedback on whether this is necessitated. fixes #5810
/** | ||
* Creates a `SecretStringValueBeta1` from a plaintext value. | ||
* This approach is inherently unsafe, as the secret value will be visible in plaintext in the resulting | ||
* CloudFormation template, including in the AWS Console or APIs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will also be visible in the source code, which is also considered a bad practice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may also be visible in the source code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be visible, it may not:
const secretValue = SecretStringValueBeta1. fromUnsafePlaintext(os.env.MY_SECRET_NOT_STORED_IN_SOURCE);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, still worth mentioning
* This method throws if it determines the input is an unsafe plaintext string. | ||
* | ||
* For example: | ||
* // Creates a new IAM user, access and secret keys, and stores the secret access key in a Secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this be considered an example by Rosetta? (@rix0rrr)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe it will in this format; however, the same example (from the tests) should be picked up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe if you use backtick code blocks, Rosetta will pick it up and translate it:
```ts
/// Creates a new IAM...
bla
bla
```
* })); | ||
* | ||
* Note that the value being a Token does *not* guarantee safety. For example, a Lazy-evaluated string | ||
* (e.g., `Lazy.string({ produce: () => 'myInsecurePassword' }))`) is a Token, but as the output is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can technically check that (i.e resolve the token and see if it's eventually a Ref or a GetAtt). Resolution can be done inside a wrapping token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This is a bit complex and/or error-prone, however, which is why I opted for the simplest solution to start.
Simply checking for the presence of Ref
in the string doesn't guarantee it's a CloudFormation reference (e.g., passRef1234
). I can try to regex it, but then I have to account for nuances in formatting, especially as this Ref/GetAtt can be embedded inside an arbitrary JSON structure. Something like /{\s*"?\s*(Ref|Fn::GetAtt)\s*"?\s*:/m
might work. I worry about unintentionally blocking an edge case we haven't thought of this way. WDYT? Is it worth the ugly regex and potentially blocking something if we've missed vs protecting against people passing in a Lazy value?
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Enables customers to supply their own secret value in the cases where an auto- generated value is not viable. The secret value is typed to highlight the inheret lack of safety with creating secret values via CloudFormation; if a plaintext secret is provided, this secret will be visible anywhere the CloudFormation template is, including the AWS Console, SDKs, and CLIs. An unsafe `fromUnsafePlaintext` method and slightly safer `fromToken` method are exposed to highlight the potential risks and hopefully encourage safe usage. The latter is intended to be used directly with a Ref or GetAtt call from another (Custom) Resource, such as storing the value of a User SecretAccessKey or storing a password generated from a custom resource. As an implementation detail, this API has been created using the new standard for experimental APIs, via suffixing with `Beta1`. This allow us to make breaking changes by deprecating the `Beta1` version and creating an improved `Beta2` version. I've chosen to do this in this case because this has been a relatively controversial feature to decide to implement, and the criteria for what makes a secret "safe" may evolve over time. I am open to feedback on whether this is necessitated. fixes aws#5810 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Enables customers to supply their own secret value in the cases where an auto-
generated value is not viable. The secret value is typed to highlight the
inheret lack of safety with creating secret values via CloudFormation; if a
plaintext secret is provided, this secret will be visible anywhere the
CloudFormation template is, including the AWS Console, SDKs, and CLIs.
An unsafe
fromUnsafePlaintext
method and slightly saferfromToken
method areexposed to highlight the potential risks and hopefully encourage safe usage.
The latter is intended to be used directly with a Ref or GetAtt call from
another (Custom) Resource, such as storing the value of a User SecretAccessKey
or storing a password generated from a custom resource.
As an implementation detail, this API has been created using the new standard
for experimental APIs, via suffixing with
Beta1
. This allow us to makebreaking changes by deprecating the
Beta1
version and creating an improvedBeta2
version. I've chosen to do this in this case because this has been arelatively controversial feature to decide to implement, and the criteria for
what makes a secret "safe" may evolve over time. I am open to feedback on
whether this is necessitated.
fixes #5810
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license