Skip to content

Conversation

@joejstuart
Copy link
Contributor

@joejstuart joejstuart commented Jan 15, 2026

User description

Add PolicySpec and ComponentName fields to the Rego input JSON (input.json) to enable Rego policies to evaluate volatile configuration rules and generate image-scoped warnings.

https://issues.redhat.com/browse/EC-1615


PR Type

Enhancement


Description

  • Add PolicySpec field to Input struct for Rego policy evaluation

  • Add ComponentName field to Input struct for component-scoped warnings

  • Store policy specification in ApplicationSnapshotImage during construction

  • Add test cases for new ComponentName and PolicySpec serialization


Diagram Walkthrough

flowchart LR
  Policy["Policy object"] -- "p.Spec()" --> ASI["ApplicationSnapshotImage"]
  ASI -- "policySpec field" --> Input["Input struct"]
  Component["SnapshotComponent"] -- "component.Name" --> Input
  Input -- "JSON serialization" --> RegoInput["Rego input.json"]
Loading

File Walkthrough

Relevant files
Enhancement
application_snapshot_image.go
Add PolicySpec and ComponentName to Input struct                 

internal/evaluation_target/application_snapshot_image/application_snapshot_image.go

  • Import ecc package for EnterpriseContractPolicySpec type
  • Add policySpec field to ApplicationSnapshotImage struct
  • Store policy specification via p.Spec() in NewApplicationSnapshotImage
    constructor
  • Add ComponentName and PolicySpec fields to Input struct with JSON tags
  • Populate new fields from component and policySpec in WriteInputFile
    method
+15/-7   
Tests
application_snapshot_image_test.go
Add tests for ComponentName and PolicySpec fields               

internal/evaluation_target/application_snapshot_image/application_snapshot_image_test.go

  • Import ecc package for EnterpriseContractPolicySpec type
  • Add test case for component_name field serialization
  • Add test case for policy_spec with volatile config including
    include/exclude rules
  • Test volatile criteria with effectiveOn, effectiveUntil, and
    imageDigest fields
+44/-0   

Add policySpec field to ApplicationSnapshotImage struct and store p.Spec()
in the constructor. This is the foundation for exposing the policy
configuration to Rego policies.

- Add ecc import for EnterpriseContractPolicySpec type
- Add policySpec field to ApplicationSnapshotImage struct
- Store p.Spec() in NewApplicationSnapshotImage constructor

Refs: https://issues.redhat.com/browse/EC-1615
Add ComponentName field to the Input struct for Rego policy evaluation.
This enables Rego policies to scope volatile config warnings to specific
components.

- Add ComponentName field to Input struct with json tag
- Populate ComponentName from a.component.Name in WriteInputFile

Refs: https://issues.redhat.com/browse/EC-1615
Add PolicySpec field to the Input struct for Rego policy evaluation.
This exposes the full EnterpriseContractPolicySpec including volatile
configuration (include/exclude rules with effectiveOn, effectiveUntil,
imageRef, imageDigest, componentNames) to Rego policies.

- Add PolicySpec field to Input struct with json tag
- Populate PolicySpec from a.policySpec in WriteInputFile
- Update snapshot files for new policy_spec field in JSON output

Refs: https://issues.redhat.com/browse/EC-1615
Add test cases to verify the new input fields are correctly serialized
to JSON for Rego policy evaluation.

- Add ecc import for EnterpriseContractPolicySpec type
- Add test case for component_name serialization
- Add test case for policy_spec with volatile config including:
  - sources[].volatileConfig.include with effectiveOn/effectiveUntil
  - sources[].volatileConfig.exclude with imageDigest
- Update snapshots with new test case output

Refs: https://issues.redhat.com/browse/EC-1615
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 15, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Sensitive data exposure

Description: The PR adds PolicySpec (and ComponentName) into the serialized Rego input.json, which can
unintentionally expose sensitive policy configuration (e.g., source URLs or embedded
credentials/tokens if present in ecc.EnterpriseContractPolicySpec) to disk and downstream
consumers of the input file.
application_snapshot_image.go [353-385]

Referred Code
type Input struct {
	Attestations  []attestationData                `json:"attestations"`
	Image         image                            `json:"image"`
	AppSnapshot   app.SnapshotSpec                 `json:"snapshot"`
	ComponentName string                           `json:"component_name,omitempty"`
	PolicySpec    ecc.EnterpriseContractPolicySpec `json:"policy_spec,omitempty"`
}

// WriteInputFile writes the JSON from the attestations to input.json in a random temp dir
func (a *ApplicationSnapshotImage) WriteInputFile(ctx context.Context) (string, []byte, error) {
	log.Debugf("Attempting to write %d attestations to input file", len(a.attestations))

	var attestations []attestationData
	for _, a := range a.attestations {
		attestations = append(attestations, attestationData{
			Statement:  a.Statement(),
			Signatures: a.Signatures(),
		})
	}

	input := Input{


 ... (clipped 12 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 15, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Add nil check for policy

Add a nil check for the policy.Policy parameter p in the
NewApplicationSnapshotImage function to prevent a potential panic from a nil
pointer dereference.

internal/evaluation_target/application_snapshot_image/application_snapshot_image.go [71-88]

 func NewApplicationSnapshotImage(ctx context.Context, component app.SnapshotComponent, p policy.Policy, snap app.SnapshotSpec) (*ApplicationSnapshotImage, error) {
+	if p == nil {
+		return nil, errors.New("policy cannot be nil")
+	}
 	opts, err := p.CheckOpts()
 	if err != nil {
 		return nil, err
 	}
 	a := &ApplicationSnapshotImage{
 		checkOpts:  *opts,
 		component:  component,
 		snapshot:   snap,
 		policySpec: p.Spec(),
 	}
 
 	if err := a.SetImageURL(component.ContainerImage); err != nil {
 		return nil, err
 	}
 
 	return a, nil
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a potential nil pointer dereference if a nil policy is passed to the function, which would cause a panic. Adding the proposed check improves the function's robustness and prevents a runtime crash.

Medium
General
Make policy spec field optional

*In the Input struct, change the PolicySpec field to a pointer type
(ecc.EnterpriseContractPolicySpec) to ensure it is omitted from JSON output
when empty.

internal/evaluation_target/application_snapshot_image/application_snapshot_image.go [358]

-PolicySpec    ecc.EnterpriseContractPolicySpec `json:"policy_spec,omitempty"`
+PolicySpec    *ecc.EnterpriseContractPolicySpec `json:"policy_spec,omitempty"`
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: This is a valid and idiomatic Go suggestion. Using a pointer with omitempty ensures that the policy_spec field is completely omitted from the JSON output when it's not provided, rather than being an empty object, leading to cleaner and more correct serialization.

Low
  • Update

Update snapshots to include the new component_name and policy_spec fields
added to the Rego input JSON. Fixed field ordering to match actual output:
- component_name and policy_spec come after snapshot
- policy_spec includes correct URL format (no https://, includes ref param)
- policy_spec includes additional fields (rekorUrl, publicKey)

Affected tests:
- policy input output
- OLM manifests

Refs: https://issues.redhat.com/browse/EC-1615
@codecov
Copy link

codecov bot commented Jan 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
acceptance 56.09% <100.00%> (+0.11%) ⬆️
generative 18.96% <0.00%> (-0.01%) ⬇️
integration 28.43% <0.00%> (-0.01%) ⬇️
unit 67.97% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ation_snapshot_image/application_snapshot_image.go 83.33% <100.00%> (+0.26%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions bot added size: XL and removed size: L labels Jan 15, 2026
@joejstuart joejstuart force-pushed the volatile-poc branch 2 times, most recently from 0b64eb9 to af1d18b Compare January 16, 2026 16:18
Add acceptance test scenario that validates the schema contract between
ec-cli and ec-policies for volatile config warnings. This test:

1. Creates a policy with volatileConfig.include rules containing:
   - Rule with no expiration (triggers no_expiration warning)
   - Rule with effectiveUntil in future (triggers expiring_rule warning)
   - Rule with effectiveOn in future (triggers pending_rule warning)
   - Rule scoped to component name (tests componentNames field)

2. Uses a Rego policy (package main) that reads from:
   - input.policy_spec.sources[_].volatileConfig.include[_]
   - input.component_name
   - All VolatileCriteria fields (effectiveOn, effectiveUntil, componentNames, etc.)

3. If either the CLI or ec-policies changes the schema in a breaking way,
   this test will fail, providing early detection of contract violations.

Fixed: Added deny rule (always false) required by ec validation framework.
@joejstuart
Copy link
Contributor Author

/retest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant