Skip to content

Commit ea39fbd

Browse files
authored
revert(secretsmanager): Specify secret value at creation (#9610)
This reverts commit 07fedff. Further team discussion deemed this feature too dangerous to support within the CDK. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 908dd69 commit ea39fbd

File tree

4 files changed

+7
-99
lines changed

4 files changed

+7
-99
lines changed

packages/@aws-cdk/aws-secretsmanager/README.md

+6-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
## AWS Secrets Manager Construct Library
2-
32
<!--BEGIN STABILITY BANNER-->
43
---
54

@@ -15,35 +14,15 @@ import * as secretsmanager from '@aws-cdk/aws-secretsmanager';
1514
```
1615

1716
### Create a new Secret in a Stack
18-
1917
In order to have SecretsManager generate a new secret value automatically,
2018
you can get started with the following:
2119

22-
```ts
23-
// Default secret
24-
const secret = new secretsmanager.Secret(this, 'Secret');
25-
26-
// Using the default secret
27-
new iam.User(this, 'User', {
28-
password: secret.secretValue,
29-
});
30-
31-
// Templated secret
32-
const templatedSecret = new secretsmanager.Secret(this, 'TemplatedSecret', {
33-
generateSecretString: {
34-
secretStringTemplate: JSON.stringify({ username: 'user' }),
35-
generateStringKey: 'password',
36-
},
37-
});
38-
39-
// Using the templated secret
40-
new iam.User(this, 'OtherUser', {
41-
userName: templatedSecret.secretValueFromJson('username').toString(),
42-
password: templatedSecret.secretValueFromJson('password'),
43-
});
44-
```
20+
[example of creating a secret](test/integ.secret.lit.ts)
4521

46-
[see also this example of creating a secret](test/integ.secret.lit.ts)
22+
The `Secret` construct does not allow specifying the `SecretString` property
23+
of the `AWS::SecretsManager::Secret` resource (as this will almost always
24+
lead to the secret being surfaced in plain text and possibly committed to
25+
your source control).
4726

4827
If you need to use a pre-existing secret, the recommended way is to manually
4928
provision the secret in *AWS SecretsManager* and use the `Secret.fromSecretArn`
@@ -64,7 +43,7 @@ A secret can set `RemovalPolicy`. If it set to `RETAIN`, that removing a secret
6443

6544
### Grant permission to use the secret to a role
6645

67-
You must grant permission to a resource for that resource to be allowed to
46+
You must grant permission to a resource for that resource to be allowed to
6847
use a secret. This can be achieved with the `Secret.grantRead` and/or `Secret.grantUpdate`
6948
method, depending on your need:
7049

@@ -76,22 +55,18 @@ secret.grantWrite(role);
7655
```
7756

7857
If, as in the following example, your secret was created with a KMS key:
79-
8058
```ts
8159
const key = new kms.Key(stack, 'KMS');
8260
const secret = new secretsmanager.Secret(stack, 'Secret', { encryptionKey: key });
8361
secret.grantRead(role);
8462
secret.grantWrite(role);
8563
```
86-
8764
then `Secret.grantRead` and `Secret.grantWrite` will also grant the role the
8865
relevant encrypt and decrypt permissions to the KMS key through the
8966
SecretsManager service principal.
9067

9168
### Rotating a Secret with a custom Lambda function
92-
9369
A rotation schedule can be added to a Secret using a custom Lambda function:
94-
9570
```ts
9671
const fn = new lambda.Function(...);
9772
const secret = new secretsmanager.Secret(this, 'Secret');
@@ -101,13 +76,10 @@ secret.addRotationSchedule('RotationSchedule', {
10176
automaticallyAfter: Duration.days(15)
10277
});
10378
```
104-
10579
See [Overview of the Lambda Rotation Function](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-lambda-function-overview.html) on how to implement a Lambda Rotation Function.
10680

10781
### Rotating database credentials
108-
10982
Define a `SecretRotation` to rotate database credentials:
110-
11183
```ts
11284
new SecretRotation(this, 'SecretRotation', {
11385
application: SecretRotationApplication.MYSQL_ROTATION_SINGLE_USER, // MySQL single user scheme
@@ -118,7 +90,6 @@ new SecretRotation(this, 'SecretRotation', {
11890
```
11991

12092
The secret must be a JSON string with the following format:
121-
12293
```json
12394
{
12495
"engine": "<required: database engine>",
@@ -132,7 +103,6 @@ The secret must be a JSON string with the following format:
132103
```
133104

134105
For the multi user scheme, a `masterSecret` must be specified:
135-
136106
```ts
137107
new SecretRotation(stack, 'SecretRotation', {
138108
application: SecretRotationApplication.MYSQL_ROTATION_MULTI_USER,

packages/@aws-cdk/aws-secretsmanager/lib/secret.ts

+1-26
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,6 @@ export interface SecretProps {
103103
*/
104104
readonly secretName?: string;
105105

106-
/**
107-
* Secret value (WARNING).
108-
*
109-
* **WARNING:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value.
110-
* The secret string -- if provided -- will be included in the output of the cdk as part of synthesis,
111-
* and will appear in the CloudFormation template in the console*.
112-
*
113-
* Specifies text data that you want to encrypt and store in this new version of the secret.
114-
* May be a simple string value, or a string representation of a JSON structure.
115-
*
116-
* Only one of `secretString` and `generateSecretString` can be provided.
117-
*
118-
* @default - SecretsManager generates a new secret value.
119-
*/
120-
readonly secretString?: string;
121-
122106
/**
123107
* Policy to apply when the secret is removed from this stack.
124108
*
@@ -282,26 +266,17 @@ export class Secret extends SecretBase {
282266
throw new Error('`secretStringTemplate` and `generateStringKey` must be specified together.');
283267
}
284268

285-
if (props.generateSecretString && props.secretString) {
286-
throw new Error('Cannot specify both `generateSecretString` and `secretString`.');
287-
}
288-
289269
const resource = new secretsmanager.CfnSecret(this, 'Resource', {
290270
description: props.description,
291271
kmsKeyId: props.encryptionKey && props.encryptionKey.keyArn,
292-
generateSecretString: props.generateSecretString || (props.secretString ? undefined : {}),
272+
generateSecretString: props.generateSecretString || {},
293273
name: this.physicalName,
294-
secretString: props.secretString,
295274
});
296275

297276
if (props.removalPolicy) {
298277
resource.applyRemovalPolicy(props.removalPolicy);
299278
}
300279

301-
if (props.secretString) {
302-
this.node.addWarning('Using a `secretString` value which will be visible in plaintext in the CloudFormation template and cdk output.');
303-
}
304-
305280
this.secretArn = this.getResourceArnAttribute(resource.ref, {
306281
service: 'secretsmanager',
307282
resource: 'secret',

packages/@aws-cdk/aws-secretsmanager/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
"license": "Apache-2.0",
6565
"devDependencies": {
6666
"@aws-cdk/assert": "0.0.0",
67-
"@aws-cdk/cloud-assembly-schema": "0.0.0",
6867
"@types/nodeunit": "^0.0.31",
6968
"cdk-build-tools": "0.0.0",
7069
"cdk-integ-tools": "0.0.0",

packages/@aws-cdk/aws-secretsmanager/test/test.secret.ts

-36
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/a
22
import * as iam from '@aws-cdk/aws-iam';
33
import * as kms from '@aws-cdk/aws-kms';
44
import * as lambda from '@aws-cdk/aws-lambda';
5-
import * as cxschema from '@aws-cdk/cloud-assembly-schema';
65
import * as cdk from '@aws-cdk/core';
76
import { Test } from 'nodeunit';
87
import * as secretsmanager from '../lib';
@@ -575,41 +574,6 @@ export = {
575574
test.done();
576575
},
577576

578-
'can provide a secret value directly'(test: Test) {
579-
// GIVEN
580-
const stack = new cdk.Stack();
581-
582-
// WHEN
583-
const secret = new secretsmanager.Secret(stack, 'Secret', {
584-
secretString: 'mynotsosecretvalue',
585-
});
586-
587-
// THEN
588-
expect(stack).to(haveResource('AWS::SecretsManager::Secret', {
589-
SecretString: 'mynotsosecretvalue',
590-
}));
591-
592-
test.equals(secret.node.metadata[0].type, cxschema.ArtifactMetadataEntryType.WARN);
593-
test.equals(secret.node.metadata[0].data, 'Using a `secretString` value which will be visible in plaintext in the CloudFormation template and cdk output.');
594-
595-
test.done();
596-
},
597-
598-
'throws when specifying secretString and generateStringKey'(test: Test) {
599-
// GIVEN
600-
const stack = new cdk.Stack();
601-
602-
// THEN
603-
test.throws(() => new secretsmanager.Secret(stack, 'Secret', {
604-
generateSecretString: {
605-
excludeCharacters: '@',
606-
},
607-
secretString: 'myexistingsecret',
608-
}), /Cannot specify both `generateSecretString` and `secretString`./);
609-
610-
test.done();
611-
},
612-
613577
'equivalence of SecretValue and Secret.fromSecretAttributes'(test: Test) {
614578
// GIVEN
615579
const stack = new cdk.Stack();

0 commit comments

Comments
 (0)