Skip to content

Commit

Permalink
fix: splitup the policy creation if too many parameters are created … (
Browse files Browse the repository at this point in the history
…#1050)

* feat: splitup the policy creation if too many parameters are created for one policy

Signed-off-by: lennartrommeiss <[email protected]>

* fix: create a function for improved readability

Signed-off-by: lennartrommeiss <[email protected]>

* feat: smaller returnData

Signed-off-by: lennartrommeiss <[email protected]>

* fix: no i in loop is needed

Signed-off-by: lennartrommeiss <[email protected]>

---------

Signed-off-by: lennartrommeiss <[email protected]>
  • Loading branch information
lenderom authored Oct 7, 2024
1 parent fe86b6b commit 356b997
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 41 deletions.
6 changes: 3 additions & 3 deletions API.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func (a AWS) syncSopsToSecretsmanager(ctx context.Context, event cfn.Event) (phy
keys := v.MapKeys()
keysOrder := func(i, j int) bool { return keys[i].Interface().(string) < keys[j].Interface().(string) }
sort.Slice(keys, keysOrder)
for i, key := range keys {
for _, key := range keys {
strKey := resourceProperties.ParameterKeyPrefix + key.String()
log.Printf("Parameter: " + strKey)
value := v.MapIndex(key).Interface()
Expand All @@ -311,8 +311,10 @@ func (a AWS) syncSopsToSecretsmanager(ctx context.Context, event cfn.Event) (phy
if err != nil {
return tempArn, nil, err
}
returnData[fmt.Sprintf("ParameterName[%v]", i)] = strKey
// A returnData map for each parameter is not created, because it would limit the number of possible parameters unnecessarily
}
returnData["Prefix"] = resourceProperties.ParameterKeyPrefix
returnData["Count"] = len(keys)
return tempArn, returnData, nil
} else {
log.Printf("Patching single string parameter")
Expand Down
4 changes: 2 additions & 2 deletions src/MultiStringParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface JSONObject {
}

export interface MultiStringParameterProps extends SopsStringParameterProps {
readonly keySeperator?: string;
readonly keySeparator?: string;
readonly keyPrefix?: string;
}

Expand Down Expand Up @@ -67,7 +67,7 @@ export class MultiStringParameter extends Construct {
region: this.stack.region,
};
this.keyPrefix = props.keyPrefix ?? '/';
this.keySeparator = props.keySeperator ?? '/';
this.keySeparator = props.keySeparator ?? '/';

const keys = this.parseFile(props.sopsFilePath!, this.keySeparator)
.filter((key) => !key.startsWith('sops'))
Expand Down
93 changes: 82 additions & 11 deletions src/SopsSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import {
CustomResource,
FileSystem,
} from 'aws-cdk-lib';
import { IGrantable, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import {
IGrantable,
IRole,
ManagedPolicy,
PolicyStatement,
} from 'aws-cdk-lib/aws-iam';
import { IKey, Key } from 'aws-cdk-lib/aws-kms';
import { SingletonFunction, Code, Runtime } from 'aws-cdk-lib/aws-lambda';
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
Expand Down Expand Up @@ -342,16 +347,9 @@ export class SopsSync extends Construct {
props.encryptionKey?.grantEncryptDecrypt(provider);
}
if (props.parameterNames) {
provider.addToRolePolicy(
new PolicyStatement({
actions: ['ssm:PutParameter'],
resources: props.parameterNames.map(
(param) =>
`arn:aws:ssm:${Stack.of(this).region}:${
Stack.of(this).account
}:parameter${param.startsWith('/') ? param : `/${param}`}`,
),
}),
this.createReducedParameterPolicy(
props.parameterNames,
provider.role,
);
props.encryptionKey?.grantEncryptDecrypt(provider);
}
Expand Down Expand Up @@ -429,4 +427,77 @@ export class SopsSync extends Construct {
});
this.versionId = cr.getAttString('VersionId');
}

private createReducedParameterPolicy(parameters: string[], role: IRole) {
// Avoid too large policies
// The maximum size of a managed policy is 6.144 bytes -> 1 character = 1 byte
const maxPolicyBytes = 6000; // Keep some bytes as a buffer
const arnPrefixBytes = 55; // Content for "arn:aws:ssm:ap-southeast-3:<accountnumer>:parameter/
let startAtParameter = 0;
let currentPolicyBytes = 300; // Reserve some byte space for basic stuff inside the policy
for (let i = 0; i < parameters.length; i += 1) {
if (
// Check if the current parameter would fit into the policy
arnPrefixBytes + parameters[i].length + currentPolicyBytes <
maxPolicyBytes
) {
// If so increase the byte counter
currentPolicyBytes =
arnPrefixBytes + parameters[i].length + currentPolicyBytes;
} else {
const parameterNamesChunk = parameters.slice(
startAtParameter,
i, //end of slice is not included
);
startAtParameter = i;
currentPolicyBytes = 300;
// Create the policy for the selected chunk
const putPolicy = new ManagedPolicy(
this,
`SopsSecretParameterProviderManagedPolicyParameterAccess${i}`,
{
description:
'Policy to grant parameter provider permissions to put parameter',
},
);
putPolicy.addStatements(
new PolicyStatement({
actions: ['ssm:PutParameter'],
resources: parameterNamesChunk.map(
(param) =>
`arn:aws:ssm:${Stack.of(this).region}:${
Stack.of(this).account
}:parameter${param.startsWith('/') ? param : `/${param}`}`,
),
}),
);
role.addManagedPolicy(putPolicy);
}
}
const parameterNamesChunk = parameters.slice(
startAtParameter,
parameters.length,
);
// Create the policy for the remaning elements
const putPolicy = new ManagedPolicy(
this,
`SopsSecretParameterProviderManagedPolicyParameterAccess${parameters.length}`,
{
description:
'Policy to grant parameter provider permissions to put parameter',
},
);
putPolicy.addStatements(
new PolicyStatement({
actions: ['ssm:PutParameter'],
resources: parameterNamesChunk.map(
(param) =>
`arn:aws:ssm:${Stack.of(this).region}:${
Stack.of(this).account
}:parameter${param.startsWith('/') ? param : `/${param}`}`,
),
}),
);
role.addManagedPolicy(putPolicy);
}
}
100 changes: 100 additions & 0 deletions test-secrets/yaml/sopsfile-parameters-large.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting1: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting2: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting3: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting4: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting5: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting6: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting7: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting8: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting9: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting10: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting11: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting12: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting13: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting14: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting15: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting16: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting17: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting18: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting19: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting20: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting21: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting22: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting23: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting24: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting25: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting26: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting27: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting28: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting29: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting30: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting31: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting32: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting33: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting34: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting35: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting36: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting37: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting38: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting39: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting40: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting41: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting42: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting43: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting44: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting45: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting46: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting47: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting48: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting49: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting50: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting51: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting52: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting53: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting54: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting55: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting56: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting57: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting58: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting59: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting60: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting61: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting62: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting63: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting64: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting65: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting66: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting67: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting68: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting69: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting70: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting71: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting72: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting73: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting74: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting75: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting76: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting77: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting78: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting79: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting80: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting81: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting82: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting83: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting84: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting85: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting86: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting87: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting88: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting89: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting90: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting91: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting92: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting93: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting94: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting95: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting96: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting97: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting98: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting99: value
DefineSomeExtraExtraLongNameForParameterWhichHaveAExtraExtraLongNameToTestPolicySplitting100: value
Loading

0 comments on commit 356b997

Please sign in to comment.