Skip to content

Commit

Permalink
feat: refactor / additional flag autoGenerateIamPermissions
Browse files Browse the repository at this point in the history
- remove CreationType (Single, Multi)
- replace with ResourceType (PARAMETER_MULTI) and move it to properties
   fixes: #1076
- add property 'autoGenerateIamPermissions'
   fixes: #1087
- add property 'role' for SopsSyncProvider
   fixes: #1087
- move resourceType from syncOptions to syncProperties, as it shouldn't be set by users
- move permissionhandling to own functions, to reduce cyclomatic compexity
  • Loading branch information
markussiebert committed Jan 13, 2025
1 parent 1e69765 commit b466435
Show file tree
Hide file tree
Showing 19 changed files with 428 additions and 344 deletions.
40 changes: 40 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[extend]
useDefault = true

[[rules]]
id = "generic-api-key"
# all the other attributes from the default rule are inherited

[[rules.allowlists]]
regexTarget = "line"
regexes = [
'''objectKey''',
'''S3Key''',
'''SopsAgeKey''',
'''s3Key''',
]

[[rules]]
id = "private-key"

[[rules.allowlists]]
regexTarget = "line"
regexes = [
'''(.*)OAdqlMznWINBDoyR\+PESgQJlUptwnh(.*)''',
]

[allowlist]
description = "global allow list"
paths = [
'''\.gitleaks\.toml''',
'''lambda/events/(.*?)json''',
'''lambda/__snapshots__/(.*?)snap''',
'''test-secrets/(.*?)(json|yaml|yml|env|binary)''',
'''test/(.*)\.integ\.snapshot/(.*?)json'''
]

regexTarget = "match"
regexes = [
'''AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3''',
]

1 change: 0 additions & 1 deletion lambda/events/event_create_s3_parameter_raw_simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"LogicalResourceId": "LogicalResourceId",
"ResourceProperties": {
"ResourceType": "PARAMETER",
"CreationType": "SINGLE",
"ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret",
"SopsS3File": {
"Bucket": "..",
Expand Down
3 changes: 1 addition & 2 deletions lambda/events/event_create_s3_parameter_yaml_complex.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"RequestType": "Create",
"LogicalResourceId": "LogicalResourceId",
"ResourceProperties": {
"ResourceType": "PARAMETER",
"CreationType": "MULTI",
"ResourceType": "PARAMETER_MULTI",
"ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret",
"SopsS3File": {
"Bucket": "..",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"RequestType": "Create",
"LogicalResourceId": "LogicalResourceId",
"ResourceProperties": {
"ResourceType": "PARAMETER",
"CreationType": "MULTI",
"ResourceType": "PARAMETER_MULTI",
"ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret",
"SopsS3File": {
"Bucket": "..",
Expand Down
63 changes: 30 additions & 33 deletions lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,44 +295,41 @@ func (a AWS) syncSopsToSecretsmanager(ctx context.Context, event cfn.Event) (phy
returnData["VersionStages"] = updateSecretResp.VersionStages
returnData["VersionId"] = *updateSecretResp.VersionId
return *updateSecretResp.ARN, returnData, nil
} else if resourceProperties.ResourceType == "PARAMETER" {
if resourceProperties.CreationType == "MULTI" && resourcePropertiesFlatten {
log.Printf("Patching multiple string parameters")
v := reflect.ValueOf(finalInterface)
returnData := make(map[string]interface{})
keys := v.MapKeys()
keysOrder := func(i, j int) bool { return keys[i].Interface().(string) < keys[j].Interface().(string) }
sort.Slice(keys, keysOrder)
for _, key := range keys {
strKey := resourceProperties.ParameterKeyPrefix + key.String()
log.Printf("Parameter: " + strKey)
value := v.MapIndex(key).Interface()
strValue, ok := value.(string)
if !ok {
return tempArn, nil, nil
}

_, err := a.updateSSMParameter(strKey, []byte(strValue), resourceProperties.EncryptionKey)
if err != nil {
return tempArn, nil, err
}
// A returnData map for each parameter is not created, because it would limit the number of possible parameters unnecessarily
} else if resourceProperties.ResourceType == "PARAMETER_MULTI" {
log.Printf("Patching multiple string parameters")
v := reflect.ValueOf(finalInterface)
returnData := make(map[string]interface{})
keys := v.MapKeys()
keysOrder := func(i, j int) bool { return keys[i].Interface().(string) < keys[j].Interface().(string) }
sort.Slice(keys, keysOrder)
for _, key := range keys {
strKey := resourceProperties.ParameterKeyPrefix + key.String()
log.Printf("Parameter: " + strKey)
value := v.MapIndex(key).Interface()
strValue, ok := value.(string)
if !ok {
return tempArn, nil, nil

Check warning on line 311 in lambda/main.go

View check run for this annotation

Codecov / codecov/patch

lambda/main.go#L311

Added line #L311 was not covered by tests
}
returnData["Prefix"] = resourceProperties.ParameterKeyPrefix
returnData["Count"] = len(keys)
return tempArn, returnData, nil
} else {
log.Printf("Patching single string parameter")
response, err := a.updateSSMParameter(resourceProperties.ParameterName, decryptedContent, resourceProperties.EncryptionKey)
_, err := a.updateSSMParameter(strKey, []byte(strValue), resourceProperties.EncryptionKey)
if err != nil {
return tempArn, nil, err
}
returnData := make(map[string]interface{})
returnData["ParameterName"] = resourceProperties.ParameterName
returnData["Version"] = response.Version
returnData["Tier"] = response.Tier
return tempArn, returnData, nil
// 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 if resourceProperties.ResourceType == "PARAMETER" {
log.Printf("Patching single string parameter")
response, err := a.updateSSMParameter(resourceProperties.ParameterName, decryptedContent, resourceProperties.EncryptionKey)
if err != nil {
return tempArn, nil, err
}

Check warning on line 327 in lambda/main.go

View check run for this annotation

Codecov / codecov/patch

lambda/main.go#L326-L327

Added lines #L326 - L327 were not covered by tests
returnData := make(map[string]interface{})
returnData["ParameterName"] = resourceProperties.ParameterName
returnData["Version"] = response.Version
returnData["Tier"] = response.Tier
return tempArn, returnData, nil
} else {
// Should never happen ...
return tempArn, nil, errors.New("Neither SecretARN nor ParameterName is provided")
Expand Down
10 changes: 2 additions & 8 deletions src/MultiStringParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ import { ResourceEnvironment, Stack } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import * as YAML from 'yaml';
import { SopsStringParameterProps } from './SopsStringParameter';
import {
CreationType,
ResourceType,
SopsSync,
SopsSyncOptions,
} from './SopsSync';
import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync';

interface JSONObject {
[key: string]: any;
Expand Down Expand Up @@ -83,8 +78,7 @@ export class MultiStringParameter extends Construct {

this.sync = new SopsSync(this, 'SopsSync', {
encryptionKey: this.encryptionKey,
resourceType: ResourceType.PARAMETER,
creationType: CreationType.MULTI,
resourceType: ResourceType.PARAMETER_MULTI,
flatten: true,
flattenSeparator: this.keySeparator,
parameterKeyPrefix: this.keyPrefix,
Expand Down
8 changes: 1 addition & 7 deletions src/SopsSecret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@ import {
Stack,
} from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import {
CreationType,
ResourceType,
SopsSync,
SopsSyncOptions,
} from './SopsSync';
import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync';

/**
* The configuration options of the SopsSecret
Expand Down Expand Up @@ -63,7 +58,6 @@ export class SopsSecret extends Construct implements ISecret {
this.sync = new SopsSync(this, 'SopsSync', {
secret: this.secret,
resourceType: ResourceType.SECRET,
creationType: CreationType.SINGLE,
flattenSeparator: '.',
...(props as SopsSyncOptions),
});
Expand Down
5 changes: 3 additions & 2 deletions src/SopsStringParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from 'aws-cdk-lib/aws-ssm';
import { RemovalPolicy, ResourceEnvironment, Stack } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import { SopsSync, SopsSyncOptions } from './SopsSync';
import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync';

/**
* The configuration options of the StringParameter
Expand Down Expand Up @@ -58,7 +58,8 @@ export class SopsStringParameter extends Construct implements IStringParameter {

this.sync = new SopsSync(this, 'SopsSync', {
encryptionKey: this.parameter.encryptionKey,
parameterName: this.parameter.parameterName,
parameterNames: [this.parameter.parameterName],
resourceType: ResourceType.PARAMETER,
...(props as SopsSyncOptions),
});
}
Expand Down
Loading

0 comments on commit b466435

Please sign in to comment.