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,109 changes: 1,927 additions & 182 deletions app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts

Large diffs are not rendered by default.

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.

2 changes: 1 addition & 1 deletion app/controlplane/pkg/biz/workflowcontract.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (uc *WorkflowContractUseCase) findPolicy(att *schemav1.PolicyAttachment, to
provider, name := loader.ProviderParts(att.GetRef())
remotePolicy, err := uc.GetPolicy(provider, name, token)
if err != nil {
return nil, fmt.Errorf("failed to get policy '%s': %w", name, err)
return nil, err
}
return remotePolicy.Policy, nil
}
Expand Down
15 changes: 14 additions & 1 deletion app/controlplane/pkg/policies/policyprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"net/url"

schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
"github.com/chainloop-dev/chainloop/pkg/policies"
"google.golang.org/protobuf/encoding/protojson"
)

Expand Down Expand Up @@ -50,7 +51,19 @@ func (p *PolicyProvider) Resolve(policyName string, token string) (*schemaapi.Po
return nil, nil, fmt.Errorf("both policyname and token are mandatory")
}

req, err := http.NewRequest("GET", fmt.Sprintf("%s/%s", p.host, policyName), nil)
// the policy name might include a digest in the form of <name>@sha256:<digest>
policyName, digest := policies.ExtractDigest(policyName)
// craft the URL
uri, err := url.Parse(fmt.Sprintf("%s/%s", p.host, policyName))
if err != nil {
return nil, nil, fmt.Errorf("error parsing policy provider URL: %w", err)
}

if digest != "" {
uri.RawQuery = fmt.Sprintf("digest=%s", digest)
}

req, err := http.NewRequest("GET", uri.String(), nil)
if err != nil {
return nil, nil, fmt.Errorf("error creating policy request: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ init: init-api-tools
init-api-tools:
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
go install github.com/bufbuild/buf/cmd/buf@v1.10.0
go install github.com/bufbuild/buf/cmd/buf@v1.40.1
go install github.com/envoyproxy/protoc-gen-validate@v1.0.1
# Tools fixed to a specific version via its commit since they are not released standalone
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@v2.0.0-20231102162905-3fc8fb7a0a0b
Expand Down
26 changes: 23 additions & 3 deletions pkg/policies/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ func (l *FileLoader) Load(_ context.Context, attachment *v1.PolicyAttachment) (*
err error
)

ref := attachment.GetRef()
// First remove the digest if present
ref, wantDigest := ExtractDigest(attachment.GetRef())
filePath, err := ensureScheme(ref, fileScheme)
if err != nil {
return nil, nil, err
Expand All @@ -73,7 +74,7 @@ func (l *FileLoader) Load(_ context.Context, attachment *v1.PolicyAttachment) (*
return nil, nil, fmt.Errorf("loading policy spec: %w", err)
}

p, err := unmarshalPolicy(raw, filepath.Ext(ref))
p, err := unmarshalPolicy(raw, filepath.Ext(filePath))
if err != nil {
return nil, nil, fmt.Errorf("unmarshalling policy spec: %w", err)
}
Expand All @@ -84,14 +85,19 @@ func (l *FileLoader) Load(_ context.Context, attachment *v1.PolicyAttachment) (*
return nil, nil, fmt.Errorf("calculating hash: %w", err)
}

// compare it with the wanted digest if needed
if wantDigest != "" && h.String() != wantDigest {
return nil, nil, fmt.Errorf("digest mismatch: got %s, want %s", h.String(), wantDigest)
}

return p, policyReferenceResourceDescriptor(ref, h), nil
}

// HTTPSLoader loader loads policies from HTTP or HTTPS references
type HTTPSLoader struct{}

func (l *HTTPSLoader) Load(_ context.Context, attachment *v1.PolicyAttachment) (*v1.Policy, *v12.ResourceDescriptor, error) {
ref := attachment.GetRef()
ref, wantDigest := ExtractDigest(attachment.GetRef())

// and do not remove the scheme since we need http(s):// to make the request
if _, err := ensureScheme(ref, httpScheme, httpsScheme); err != nil {
Expand Down Expand Up @@ -120,6 +126,11 @@ func (l *HTTPSLoader) Load(_ context.Context, attachment *v1.PolicyAttachment) (
return nil, nil, fmt.Errorf("calculating hash: %w", err)
}

// compare it with the wanted digest if needed
if wantDigest != "" && h.String() != wantDigest {
return nil, nil, fmt.Errorf("digest mismatch: got %s, want %s", h.String(), wantDigest)
}

return p, policyReferenceResourceDescriptor(ref, h), nil
}

Expand Down Expand Up @@ -244,3 +255,12 @@ func policyReferenceResourceDescriptor(ref string, digest crv1.Hash) *v12.Resour
},
}
}

func ExtractDigest(ref string) (string, string) {
parts := strings.SplitN(ref, "@", 2)
if len(parts) == 2 {
return parts[0], parts[1]
}

return parts[0], ""
}
26 changes: 26 additions & 0 deletions pkg/policies/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,29 @@ func TestPolicyReferenceResourceDescriptor(t *testing.T) {
assert.Equal(t, tc.want, got)
}
}

func TestExtractNameAndDigestFromRef(t *testing.T) {
testCases := []struct {
ref string
want []string
}{
{
ref: "chainloop://policy.json@sha256:1234",
want: []string{"chainloop://policy.json", "sha256:1234"},
},
{
ref: "chainloop://policy.json",
want: []string{"chainloop://policy.json", ""},
},
{
ref: "",
want: []string{"", ""},
},
}

for _, tc := range testCases {
gotName, gotDigest := ExtractDigest(tc.ref)
assert.Equal(t, tc.want[0], gotName)
assert.Equal(t, tc.want[1], gotDigest)
}
}
8 changes: 4 additions & 4 deletions pkg/policies/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewPolicyError(err error) *PolicyError {
}

func (e *PolicyError) Error() string {
return fmt.Sprintf("policy error: %s", e.err.Error())
return e.err.Error()
}

func (e *PolicyError) Unwrap() error {
Expand Down Expand Up @@ -200,12 +200,12 @@ func (pv *PolicyVerifier) loadPolicySpec(ctx context.Context, attachment *v1.Pol
}
}
if err != nil {
return nil, nil, fmt.Errorf("loading policy spec: %w", err)
return nil, nil, err
}

// Validate just in case
if err = validatePolicy(spec); err != nil {
return nil, nil, fmt.Errorf("invalid policy: %w", err)
return nil, nil, err
}

return spec, ref, nil
Expand Down Expand Up @@ -360,7 +360,7 @@ func (pv *PolicyVerifier) requiredPoliciesForMaterial(ctx context.Context, mater
// load the policy spec
spec, _, err := pv.loadPolicySpec(ctx, policyAtt)
if err != nil {
return nil, fmt.Errorf("failed to load policy spec: %w", err)
return nil, fmt.Errorf("failed to load policy attachment %q: %w", policyAtt.GetRef(), err)
}

specType := spec.GetSpec().GetType()
Expand Down
24 changes: 24 additions & 0 deletions pkg/policies/policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,30 @@ func (s *testSuite) TestLoadPolicySpec() {
},
},
},
{
name: "by file ref with valid digest",
attachment: &v12.PolicyAttachment{
Policy: &v12.PolicyAttachment_Ref{
Ref: "file://testdata/sbom_syft.yaml@sha256:24c4bd4f56b470d7436ed0c5a340483fff9ad058033f94b164f5efc59aba5136",
},
},
expectedName: "made-with-syft",
expectedRef: &v1.ResourceDescriptor{
Name: "file://testdata/sbom_syft.yaml",
Digest: map[string]string{
"sha256": "24c4bd4f56b470d7436ed0c5a340483fff9ad058033f94b164f5efc59aba5136",
},
},
},
{
name: "by file ref with invalid digest",
attachment: &v12.PolicyAttachment{
Policy: &v12.PolicyAttachment_Ref{
Ref: "file://testdata/sbom_syft.yaml@sha256:deadbeef",
},
},
wantErr: true,
},
{
name: "embedded invalid",
attachment: &v12.PolicyAttachment{
Expand Down