Skip to content

Commit 92af268

Browse files
authored
fix: checking CdkBootstrapVersion when the SSM parameter is encrypted (#1025)
When using a custom bootstrap template, users may choose to store the bootstrap version in a `SecureString` SSM parameter instead the default `String` type. The CDK CLI currently doesn't request decryption, causing it to fail when reading such parameters. While the parameter contains no sensitive data, overly aggressively configured checkers might flag the parameter. This PR resolves #955, at least in most cases. It should now be possible to use a custom bootstrap template and encrypt the CDK Bootstrap version parameter. The change adds `WithDecryption: true` to the SSM `getParameter` call. The flag is safe to always set because it's ignored for unencrypted parameters. When using AWS Managed Keys, SSM already has the necessary decryption permissions by default via Key policy. Otherwise it is up to the user to ensure sufficient decryption permissions. --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
1 parent 647111e commit 92af268

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

packages/@aws-cdk/toolkit-lib/lib/api/environment/environment-resources.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,14 @@ export class EnvironmentResources {
142142
const ssm = this.sdk.ssm();
143143

144144
try {
145-
const result = await ssm.getParameter({ Name: parameterName });
145+
const result = await ssm.getParameter({
146+
Name: parameterName,
147+
// A custom template might use a SecureString for this, so we request the decrypted parameter.
148+
// The flag is safe to set, since it will be ignored for unencrypted parameters.
149+
// It is still up to user to ensure that all roles have sufficient permissions,
150+
// however when using AWS Managed Keys, SSM is granted decryption permissions by default.
151+
WithDecryption: true,
152+
});
146153

147154
const asNumber = parseInt(`${result.Parameter?.Value}`, 10);
148155
if (isNaN(asNumber)) {

packages/@aws-cdk/toolkit-lib/lib/context-providers/ssm-parameters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class SSMContextProviderPlugin implements ContextProviderPlugin {
3636
}
3737

3838
/**
39-
* Gets the value of an SSM Parameter, while not throwin if the parameter does not exist.
39+
* Gets the value of an SSM Parameter, while not thrown if the parameter does not exist.
4040
* @param account - the account in which the SSM Parameter is expected to be.
4141
* @param region - the region in which the SSM Parameter is expected to be.
4242
* @param parameterName - the name of the SSM Parameter

packages/@aws-cdk/toolkit-lib/test/api/environment/environment-resources.test.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ test('failure to read SSM parameter results in exception passthrough for existin
8080
await expect(envResources().validateVersion(99, '/abc')).rejects.toThrow(/Computer says no/);
8181
});
8282

83-
describe('validateversion without bootstrap stack', () => {
83+
describe('validate version without bootstrap stack', () => {
8484
beforeEach(() => {
8585
mockToolkitInfo(ToolkitInfo.bootstrapStackNotFoundInfo('TestBootstrapStack'));
8686
});
@@ -156,4 +156,20 @@ describe('validateversion without bootstrap stack', () => {
156156
// WHEN
157157
await expect(envResources().validateVersion(8, '/abc')).rejects.toThrow(/Has the environment been bootstrapped?/);
158158
});
159+
160+
test('SSM parameter is requested with decryption enabled', async () => {
161+
// GIVEN
162+
mockSSMClient.on(GetParameterCommand).resolves({
163+
Parameter: { Value: '10' },
164+
});
165+
166+
// WHEN
167+
await envResources().versionFromSsmParameter('/abc');
168+
169+
// THEN
170+
expect(mockSSMClient.commandCalls(GetParameterCommand)[0].args[0].input).toEqual({
171+
Name: '/abc',
172+
WithDecryption: true,
173+
});
174+
});
159175
});

0 commit comments

Comments
 (0)