Skip to content
Merged
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
2 changes: 1 addition & 1 deletion 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
19 changes: 18 additions & 1 deletion app/cli/pkg/action/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 @@ -27,6 +27,7 @@ import (
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/unmarshal"
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter"
clientAPI "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1"
"github.com/chainloop-dev/chainloop/pkg/attestation/renderer"
"github.com/chainloop-dev/chainloop/pkg/casclient"
"github.com/chainloop-dev/chainloop/pkg/policies"
"github.com/rs/zerolog"
Expand Down Expand Up @@ -305,6 +306,22 @@ func (action *AttestationInit) Run(ctx context.Context, opts *AttestationInitRun
// Don't fail the init - this is best-effort
}

// Evaluate attestation-level policies at init phase
attClient := pb.NewAttestationServiceClient(action.CPConnection)
r, err := renderer.NewAttestationRenderer(action.c.CraftingState, attClient, "", "", nil, renderer.WithLogger(action.Logger))
if err != nil {
return "", fmt.Errorf("creating attestation renderer: %w", err)
}

statement, err := r.RenderStatement(ctx)
if err != nil {
return "", fmt.Errorf("rendering statement: %w", err)
}

if err := action.c.EvaluateAttestationPolicies(ctx, attestationID, statement, policies.EvalPhaseInit); err != nil {
return "", fmt.Errorf("evaluating attestation policies: %w", err)
}

return attestationID, nil
}

Expand Down
9 changes: 7 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 @@ -27,6 +27,7 @@ import (
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter"
"github.com/chainloop-dev/chainloop/pkg/attestation/renderer"
"github.com/chainloop-dev/chainloop/pkg/attestation/signer"
"github.com/chainloop-dev/chainloop/pkg/policies"
"github.com/secure-systems-lab/go-securesystemslib/dsse"
protobundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1"
"google.golang.org/grpc"
Expand Down Expand Up @@ -100,6 +101,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)
if err != nil {
return nil, fmt.Errorf("creating running status action: %w", err)
Expand Down Expand Up @@ -196,10 +198,13 @@ func (action *AttestationPush) Run(ctx context.Context, attestationID string, ru
}

// Add attestation-level policy evaluations
if err := crafter.EvaluateAttestationPolicies(ctx, attestationID, statement); err != nil {
if err := crafter.EvaluateAttestationPolicies(ctx, attestationID, statement, policies.EvalPhasePush); err != nil {
return nil, fmt.Errorf("evaluating attestation policies: %w", err)
}

// Update the status result with the definitive push-phase evaluation against the final statement
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
44 changes: 5 additions & 39 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 All @@ -20,11 +20,9 @@ import (
"fmt"
"time"

pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1"
pbc "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
"github.com/chainloop-dev/chainloop/pkg/attestation/crafter"
v1 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1"
"github.com/chainloop-dev/chainloop/pkg/attestation/renderer"
"github.com/chainloop-dev/chainloop/pkg/attestation/renderer/chainloop"
)

Expand All @@ -39,8 +37,7 @@ type AttestationStatus struct {
*ActionsOpts
c *crafter.Crafter
// Do not show information about the project version release status
isPushed bool
skipPolicyEvaluation bool
isPushed bool
}

type AttestationStatusResult struct {
Expand Down Expand Up @@ -93,19 +90,7 @@ func NewAttestationStatus(cfg *AttestationStatusOpts) (*AttestationStatus, error
}, nil
}

func WithSkipPolicyEvaluation() func(*AttestationStatus) {
return func(opts *AttestationStatus) {
opts.skipPolicyEvaluation = true
}
}

type AttestationStatusOpt func(*AttestationStatus)

func (action *AttestationStatus) Run(ctx context.Context, attestationID string, opts ...AttestationStatusOpt) (*AttestationStatusResult, error) {
for _, opt := range opts {
opt(action)
}

func (action *AttestationStatus) Run(ctx context.Context, attestationID string) (*AttestationStatusResult, error) {
c := action.c

if initialized, err := c.AlreadyInitialized(ctx, attestationID); err != nil {
Expand Down Expand Up @@ -141,27 +126,8 @@ func (action *AttestationStatus) Run(ctx context.Context, attestationID string,
TimestampAuthority: att.GetSigningOptions().GetTimestampAuthorityUrl(),
}

if !action.skipPolicyEvaluation {
// We need to render the statement to get the policy evaluations
attClient := pb.NewAttestationServiceClient(action.CPConnection)
renderer, err := renderer.NewAttestationRenderer(c.CraftingState, attClient, "", "", nil, renderer.WithLogger(action.Logger))
if err != nil {
return nil, fmt.Errorf("rendering statement: %w", err)
}

// We do not want to evaluate policies here during render since we want to do it in a separate step
statement, err := renderer.RenderStatement(ctx)
if err != nil {
return nil, fmt.Errorf("rendering statement: %w", err)
}

// Add attestation-level policy evaluations
if err := c.EvaluateAttestationPolicies(ctx, attestationID, statement); err != nil {
return nil, fmt.Errorf("evaluating attestation policies: %w", err)
}

res.PolicyEvaluations, res.HasPolicyViolations = getPolicyEvaluations(c)
}
// Read policy evaluations from crafting state (evaluation happens in init/push, not here)
res.PolicyEvaluations, res.HasPolicyViolations = getPolicyEvaluations(c)

if v := workflowMeta.GetVersion(); v != nil {
res.WorkflowMeta.ProjectVersion = &ProjectVersion{
Expand Down

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

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

Loading
Loading