Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/cli/cmd/attestation_init.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024-2025 The Chainloop Authors.
// Copyright 2024-2026 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -127,7 +127,7 @@ func newAttestationInitCmd() *cobra.Command {
return newGracefulError(err)
}

res, err := statusAction.Run(cmd.Context(), attestationID)
res, err := statusAction.Run(cmd.Context(), attestationID, action.WithSkipPolicyEvaluation())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we may be losing relevant evaluations (git commit signature, crafter checks, gather info, PR metadata, etc)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I am going to stop this PR and instead work on a lifecycle management per-policy.

Thanks

if err != nil {
return newGracefulError(err)
}
Expand Down
7 changes: 5 additions & 2 deletions app/cli/pkg/action/attestation_push.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024-2025 The Chainloop Authors.
// Copyright 2024-2026 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -100,7 +100,7 @@ func (action *AttestationPush) Run(ctx context.Context, attestationID string, ru
if err != nil {
return nil, fmt.Errorf("creating status action: %w", err)
}
attestationStatus, err := statusAction.Run(ctx, attestationID)
attestationStatus, err := statusAction.Run(ctx, attestationID, WithSkipPolicyEvaluation())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code, it might not make sense to call StatusAction at this point, but doing it after it has been rendered and all evaluations have been done.

if err != nil {
return nil, fmt.Errorf("creating running status action: %w", err)
}
Expand Down Expand Up @@ -200,6 +200,9 @@ func (action *AttestationPush) Run(ctx context.Context, attestationID string, ru
return nil, fmt.Errorf("evaluating attestation policies: %w", err)
}

// Update the status result with the evaluated policies
attestationStatus.PolicyEvaluations, attestationStatus.HasPolicyViolations = getPolicyEvaluations(crafter)

// render final attestation with all the evaluated policies inside
envelope, bundle, err := renderer.Render(ctx)
if err != nil {
Expand Down
14 changes: 10 additions & 4 deletions app/cli/pkg/action/attestation_status.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024-2025 The Chainloop Authors.
// Copyright 2024-2026 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -93,6 +93,9 @@ func NewAttestationStatus(cfg *AttestationStatusOpts) (*AttestationStatus, error
}, nil
}

// WithSkipPolicyEvaluation skips re-evaluating policies against the attestation statement.
// Existing policy evaluations already stored in the crafting state (e.g. from material additions)
// will still be included in the result.
func WithSkipPolicyEvaluation() func(*AttestationStatus) {
return func(opts *AttestationStatus) {
opts.skipPolicyEvaluation = true
Expand Down Expand Up @@ -159,10 +162,12 @@ func (action *AttestationStatus) Run(ctx context.Context, attestationID string,
if err := c.EvaluateAttestationPolicies(ctx, attestationID, statement); err != nil {
return nil, fmt.Errorf("evaluating attestation policies: %w", err)
}

res.PolicyEvaluations, res.HasPolicyViolations = getPolicyEvaluations(c)
}

// Always read existing policy evaluations from crafting state,
// even when skipping re-evaluation (e.g. material-level evaluations from add)
res.PolicyEvaluations, res.HasPolicyViolations = getPolicyEvaluations(c)

if v := workflowMeta.GetVersion(); v != nil {
res.WorkflowMeta.ProjectVersion = &ProjectVersion{
Version: v.GetVersion(),
Expand Down Expand Up @@ -210,7 +215,8 @@ func (action *AttestationStatus) Run(ctx context.Context, attestationID string,
return res, nil
}

// getPolicyEvaluations retrieves both material-level and attestation-level policy evaluations and returns if it has violations
// getPolicyEvaluations retrieves both material-level and attestation-level policy evaluations from the crafting state
// and returns whether any violations exist.
func getPolicyEvaluations(c *crafter.Crafter) (map[string][]*PolicyEvaluation, bool) {
// grouped by material name
evaluations := make(map[string][]*PolicyEvaluation)
Expand Down
Loading