Skip to content

Commit d5ff408

Browse files
Merge pull request #39 from vamshi-stepsecurity/exempt-pining-images
exempt images
2 parents a0fe488 + 5691f51 commit d5ff408

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

docs/resources/policy_driven_pr.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ resource "stepsecurity_policy_driven_pr" "org_level_all" {
4242
restrict_github_token_permissions = false
4343
secure_docker_file = false
4444
actions_to_exempt_while_pinning = ["actions/checkout", "actions/setup-node"]
45+
images_to_exempt_while_pinning = ["amazon*"]
4546
}
4647
}
4748
@@ -63,6 +64,8 @@ resource "stepsecurity_policy_driven_pr" "repo_level_config" {
6364
secure_docker_file = true
6465
actions_to_exempt_while_pinning = ["actions/checkout", "actions/setup-node"]
6566
actions_to_replace_with_step_security_actions = ["EnricoMi/publish-unit-test-result-action"]
67+
images_to_exempt_while_pinning = ["amazon*"]
68+
6669
# v2-only features (requires policy-driven PR v2 to be enabled)
6770
update_precommit_file = ["eslint"]
6871
package_ecosystem = [
@@ -169,6 +172,7 @@ Optional:
169172
- `create_issue` (Boolean) Create an issue when a finding is detected.
170173
- `create_pr` (Boolean) Create a PR when a finding is detected.
171174
- `harden_github_hosted_runner` (Boolean) When enabled, this creates a PR/issue to install security agent on the GitHub-hosted runner to prevent exfiltration of credentials, monitor the build process, and detect compromised dependencies.
175+
- `images_to_exempt_while_pinning` (List of String) List of Docker images to exempt while pinning images to SHA. When exempted, the image will not be pinned to SHA.
172176
- `package_ecosystem` (Attributes List) List of package ecosystems to enable for dependency updates. (see [below for nested schema](#nestedatt--auto_remediation_options--package_ecosystem))
173177
- `pin_actions_to_sha` (Boolean) When enabled, this creates a PR/issue to pin actions to SHA. GitHub's Security Hardening guide recommends pinning actions to full length commit for third party actions.
174178
- `restrict_github_token_permissions` (Boolean) When enabled, this creates a PR/issue to restrict GitHub token permissions. GitHub's Security Hardening guide recommends restricting permissions to the minimum required

examples/resources/stepsecurity_policy_driven_pr/resource.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ resource "stepsecurity_policy_driven_pr" "org_level_all" {
2828
restrict_github_token_permissions = false
2929
secure_docker_file = false
3030
actions_to_exempt_while_pinning = ["actions/checkout", "actions/setup-node"]
31+
images_to_exempt_while_pinning = ["amazon*"]
3132
}
3233
}
3334

@@ -49,6 +50,8 @@ resource "stepsecurity_policy_driven_pr" "repo_level_config" {
4950
secure_docker_file = true
5051
actions_to_exempt_while_pinning = ["actions/checkout", "actions/setup-node"]
5152
actions_to_replace_with_step_security_actions = ["EnricoMi/publish-unit-test-result-action"]
53+
images_to_exempt_while_pinning = ["amazon*"]
54+
5255
# v2-only features (requires policy-driven PR v2 to be enabled)
5356
update_precommit_file = ["eslint"]
5457
package_ecosystem = [

internal/provider/resource_policy_driven_pr.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,18 @@ func (r *policyDrivenPRResource) Schema(_ context.Context, _ resource.SchemaRequ
138138
),
139139
),
140140
},
141+
"images_to_exempt_while_pinning": schema.ListAttribute{
142+
ElementType: types.StringType,
143+
Optional: true,
144+
Computed: true,
145+
Description: "List of Docker images to exempt while pinning images to SHA. When exempted, the image will not be pinned to SHA.",
146+
Default: listdefault.StaticValue(
147+
types.ListValueMust(
148+
types.StringType,
149+
[]attr.Value{},
150+
),
151+
),
152+
},
141153
"actions_to_replace_with_step_security_actions": schema.ListAttribute{
142154
ElementType: types.StringType,
143155
Optional: true,
@@ -290,6 +302,12 @@ func (r *policyDrivenPRResource) ImportState(ctx context.Context, req resource.I
290302
}
291303
exemptList, _ := types.ListValueFrom(ctx, types.StringType, exemptElements)
292304

305+
exemptImagesElements := make([]types.String, len(policy.AutoRemdiationOptions.ImagesToExemptWhilePinning))
306+
for i, image := range policy.AutoRemdiationOptions.ImagesToExemptWhilePinning {
307+
exemptImagesElements[i] = types.StringValue(image)
308+
}
309+
exemptImagesList, _ := types.ListValueFrom(ctx, types.StringType, exemptImagesElements)
310+
293311
replaceElements := make([]types.String, len(policy.AutoRemdiationOptions.ActionsToReplaceWithStepSecurityActions))
294312
for i, action := range policy.AutoRemdiationOptions.ActionsToReplaceWithStepSecurityActions {
295313
replaceElements[i] = types.StringValue(action)
@@ -370,6 +388,7 @@ func (r *policyDrivenPRResource) ImportState(ctx context.Context, req resource.I
370388
"restrict_github_token_permissions": types.BoolType,
371389
"secure_docker_file": types.BoolType,
372390
"actions_to_exempt_while_pinning": types.ListType{ElemType: types.StringType},
391+
"images_to_exempt_while_pinning": types.ListType{ElemType: types.StringType},
373392
"actions_to_replace_with_step_security_actions": types.ListType{ElemType: types.StringType},
374393
"update_precommit_file": types.ListType{ElemType: types.StringType},
375394
"package_ecosystem": types.ListType{
@@ -392,6 +411,7 @@ func (r *policyDrivenPRResource) ImportState(ctx context.Context, req resource.I
392411
"restrict_github_token_permissions": types.BoolValue(policy.AutoRemdiationOptions.RestrictGitHubTokenPermissions),
393412
"secure_docker_file": types.BoolValue(policy.AutoRemdiationOptions.SecureDockerFile),
394413
"actions_to_exempt_while_pinning": exemptList,
414+
"images_to_exempt_while_pinning": exemptImagesList,
395415
"actions_to_replace_with_step_security_actions": replaceList,
396416
"update_precommit_file": updatePrecommitFileList,
397417
"package_ecosystem": packageEcosystemList,
@@ -428,6 +448,7 @@ type autoRemdiationOptionsModel struct {
428448
RestrictGitHubTokenPermissions types.Bool `tfsdk:"restrict_github_token_permissions"`
429449
SecureDockerFile types.Bool `tfsdk:"secure_docker_file"`
430450
ActionsToExemptWhilePinning types.List `tfsdk:"actions_to_exempt_while_pinning"`
451+
ImagesToExemptWhilePinning types.List `tfsdk:"images_to_exempt_while_pinning"`
431452
ActionsToReplaceWithStepSecurityActions types.List `tfsdk:"actions_to_replace_with_step_security_actions"`
432453
UpdatePrecommitFile types.List `tfsdk:"update_precommit_file"`
433454
PackageEcosystem types.List `tfsdk:"package_ecosystem"`
@@ -683,6 +704,15 @@ func (r *policyDrivenPRResource) Create(ctx context.Context, req resource.Create
683704
}
684705
}
685706

707+
var imagesToExempt []string
708+
if !options.ImagesToExemptWhilePinning.IsNull() {
709+
elements := options.ImagesToExemptWhilePinning.Elements()
710+
imagesToExempt = make([]string, len(elements))
711+
for i, elem := range elements {
712+
imagesToExempt[i] = elem.(types.String).ValueString()
713+
}
714+
}
715+
686716
var actionsToReplace []string
687717
if !options.ActionsToReplaceWithStepSecurityActions.IsNull() {
688718
elements := options.ActionsToReplaceWithStepSecurityActions.Elements()
@@ -744,6 +774,7 @@ func (r *policyDrivenPRResource) Create(ctx context.Context, req resource.Create
744774
RestrictGitHubTokenPermissions: options.RestrictGitHubTokenPermissions.ValueBool(),
745775
SecureDockerFile: options.SecureDockerFile.ValueBool(),
746776
ActionsToExemptWhilePinning: actionsToExempt,
777+
ImagesToExemptWhilePinning: imagesToExempt,
747778
ActionsToReplaceWithStepSecurityActions: actionsToReplace,
748779
UpdatePrecommitFile: updatePrecommitFile,
749780
PackageEcosystem: packageEcosystem,
@@ -971,6 +1002,19 @@ func (r *policyDrivenPRResource) Read(ctx context.Context, req resource.ReadRequ
9711002
tflog.Info(ctx, "Preserving actions_to_exempt_while_pinning from state")
9721003
}
9731004

1005+
if len(stepSecurityPolicy.AutoRemdiationOptions.ImagesToExemptWhilePinning) == 0 &&
1006+
!currentStateOptions.ImagesToExemptWhilePinning.IsNull() &&
1007+
len(currentStateOptions.ImagesToExemptWhilePinning.Elements()) > 0 {
1008+
elements := currentStateOptions.ImagesToExemptWhilePinning.Elements()
1009+
for _, elem := range elements {
1010+
stepSecurityPolicy.AutoRemdiationOptions.ImagesToExemptWhilePinning = append(
1011+
stepSecurityPolicy.AutoRemdiationOptions.ImagesToExemptWhilePinning,
1012+
elem.(types.String).ValueString(),
1013+
)
1014+
}
1015+
tflog.Info(ctx, "Preserving images_to_exempt_while_pinning from state")
1016+
}
1017+
9741018
if len(stepSecurityPolicy.AutoRemdiationOptions.ActionsToReplaceWithStepSecurityActions) == 0 &&
9751019
!currentStateOptions.ActionsToReplaceWithStepSecurityActions.IsNull() &&
9761020
len(currentStateOptions.ActionsToReplaceWithStepSecurityActions.Elements()) > 0 {
@@ -1120,6 +1164,15 @@ func (r *policyDrivenPRResource) Update(ctx context.Context, req resource.Update
11201164
}
11211165
}
11221166

1167+
var imagesToExempt []string
1168+
if !planOptions.ImagesToExemptWhilePinning.IsNull() {
1169+
elements := planOptions.ImagesToExemptWhilePinning.Elements()
1170+
imagesToExempt = make([]string, len(elements))
1171+
for i, elem := range elements {
1172+
imagesToExempt[i] = elem.(types.String).ValueString()
1173+
}
1174+
}
1175+
11231176
var actionsToReplace []string
11241177
if !planOptions.ActionsToReplaceWithStepSecurityActions.IsNull() {
11251178
elements := planOptions.ActionsToReplaceWithStepSecurityActions.Elements()
@@ -1182,6 +1235,7 @@ func (r *policyDrivenPRResource) Update(ctx context.Context, req resource.Update
11821235
RestrictGitHubTokenPermissions: planOptions.RestrictGitHubTokenPermissions.ValueBool(),
11831236
SecureDockerFile: planOptions.SecureDockerFile.ValueBool(),
11841237
ActionsToExemptWhilePinning: actionsToExempt,
1238+
ImagesToExemptWhilePinning: imagesToExempt,
11851239
ActionsToReplaceWithStepSecurityActions: actionsToReplace,
11861240
UpdatePrecommitFile: updatePrecommitFilePlan,
11871241
PackageEcosystem: packageEcosystemPlan,
@@ -1315,6 +1369,12 @@ func (r *policyDrivenPRResource) updatePolicyDrivenPRState(ctx context.Context,
13151369
}
13161370
exemptList, _ := types.ListValueFrom(ctx, types.StringType, exemptElements)
13171371

1372+
exemptImagesElements := make([]types.String, len(stepSecurityPolicy.AutoRemdiationOptions.ImagesToExemptWhilePinning))
1373+
for i, image := range stepSecurityPolicy.AutoRemdiationOptions.ImagesToExemptWhilePinning {
1374+
exemptImagesElements[i] = types.StringValue(image)
1375+
}
1376+
exemptImagesList, _ := types.ListValueFrom(ctx, types.StringType, exemptImagesElements)
1377+
13181378
replaceElements := make([]types.String, len(stepSecurityPolicy.AutoRemdiationOptions.ActionsToReplaceWithStepSecurityActions))
13191379
for i, action := range stepSecurityPolicy.AutoRemdiationOptions.ActionsToReplaceWithStepSecurityActions {
13201380
replaceElements[i] = types.StringValue(action)
@@ -1396,6 +1456,7 @@ func (r *policyDrivenPRResource) updatePolicyDrivenPRState(ctx context.Context,
13961456
"restrict_github_token_permissions": types.BoolType,
13971457
"secure_docker_file": types.BoolType,
13981458
"actions_to_exempt_while_pinning": types.ListType{ElemType: types.StringType},
1459+
"images_to_exempt_while_pinning": types.ListType{ElemType: types.StringType},
13991460
"actions_to_replace_with_step_security_actions": types.ListType{ElemType: types.StringType},
14001461
"update_precommit_file": types.ListType{ElemType: types.StringType},
14011462
"package_ecosystem": types.ListType{
@@ -1418,6 +1479,7 @@ func (r *policyDrivenPRResource) updatePolicyDrivenPRState(ctx context.Context,
14181479
"restrict_github_token_permissions": types.BoolValue(stepSecurityPolicy.AutoRemdiationOptions.RestrictGitHubTokenPermissions),
14191480
"secure_docker_file": types.BoolValue(stepSecurityPolicy.AutoRemdiationOptions.SecureDockerFile),
14201481
"actions_to_exempt_while_pinning": exemptList,
1482+
"images_to_exempt_while_pinning": exemptImagesList,
14211483
"actions_to_replace_with_step_security_actions": replaceList,
14221484
"update_precommit_file": updatePrecommitFileList,
14231485
"package_ecosystem": packageEcosystemList,

internal/stepsecurity-api/gh-policy-driven-prs.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type AutoRemdiationOptions struct {
3030
RestrictGitHubTokenPermissions bool `json:"restrict_github_token_permissions"`
3131
SecureDockerFile bool `json:"secure_docker_file"`
3232
ActionsToExemptWhilePinning []string `json:"actions_to_exempt_while_pinning"`
33+
ImagesToExemptWhilePinning []string `json:"images_to_exempt_while_pinning"`
3334
ActionsToReplaceWithStepSecurityActions []string `json:"actions_to_replace_with_step_security_actions"`
3435
UpdatePrecommitFile []string `json:"update_precommit_file,omitempty"`
3536
PackageEcosystem []DependabotConfig `json:"package_ecosystem,omitempty"`
@@ -63,6 +64,7 @@ type controlSettings struct {
6364
ApplyIssuePRConfigForAllRepos *bool `json:"apply_issue_pr_config_for_all_repos,omitempty"`
6465
ApplyIssuePRConfigForAllReposFilter *ApplyIssuePRConfigForAllReposFilter `json:"apply_issue_pr_config_for_all_repos_filter,omitempty"`
6566
ActionCommitMap map[string]string `json:"action_commit_map"`
67+
ExemptedImages []string `json:"exempted_images,omitempty"`
6668
}
6769

6870
type ApplyIssuePRConfigForAllReposFilter struct {
@@ -181,6 +183,7 @@ func (c *APIClient) CreatePolicyDrivenPRPolicy(ctx context.Context, createReques
181183
PackageEcosystem: createRequest.AutoRemdiationOptions.PackageEcosystem,
182184
AddWorkflows: createRequest.AutoRemdiationOptions.AddWorkflows,
183185
ActionCommitMap: createRequest.AutoRemdiationOptions.ActionCommitMap,
186+
ExemptedImages: createRequest.AutoRemdiationOptions.ImagesToExemptWhilePinning,
184187
ApplyIssuePRConfigForAllRepos: &applyToAllRepos,
185188
ApplyIssuePRConfigForAllReposFilter: &createRequest.SelectedReposFilter,
186189
}
@@ -377,6 +380,7 @@ func (c *APIClient) GetPolicyDrivenPRPolicy(ctx context.Context, owner string, r
377380
RestrictGitHubTokenPermissions: enabledTokenPermissions,
378381
SecureDockerFile: enabledSecureDocker,
379382
ActionsToExemptWhilePinning: selectedConfig.ControlSettings.ExemptedActions,
383+
ImagesToExemptWhilePinning: selectedConfig.ControlSettings.ExemptedImages,
380384
ActionsToReplaceWithStepSecurityActions: actionsToReplace,
381385
UpdatePrecommitFile: updatePrecommitFiles,
382386
PackageEcosystem: selectedConfig.ControlSettings.PackageEcosystem,
@@ -520,6 +524,7 @@ func (c *APIClient) DiscoverPolicyDrivenPRConfig(ctx context.Context, owner stri
520524
RestrictGitHubTokenPermissions: enabledTokenPermissions,
521525
SecureDockerFile: enabledSecureDocker,
522526
ActionsToExemptWhilePinning: selectedConfig.ControlSettings.ExemptedActions,
527+
ImagesToExemptWhilePinning: selectedConfig.ControlSettings.ExemptedImages,
523528
ActionsToReplaceWithStepSecurityActions: actionsToReplace,
524529
UpdatePrecommitFile: updatePrecommitFiles,
525530
PackageEcosystem: selectedConfig.ControlSettings.PackageEcosystem,

0 commit comments

Comments
 (0)