Add support for selecting a policy by ID (#41)
This commit is contained in:
@@ -56,6 +56,7 @@ func ExampleVerify_remote() {
|
||||
TufClient: tufClient,
|
||||
LocalTargetsDir: filepath.Join(home, ".docker", "policy"), // location to store policy files downloaded from TUF
|
||||
LocalPolicyDir: "", // overrides TUF policy for local policy files if set
|
||||
PolicyId: "", // set to ignore policy mapping and select a policy by id
|
||||
}
|
||||
|
||||
// verify attestations
|
||||
|
||||
@@ -79,6 +79,7 @@ type PolicyOptions struct {
|
||||
TufClient tuf.TUFClient
|
||||
LocalTargetsDir string
|
||||
LocalPolicyDir string
|
||||
PolicyId string
|
||||
}
|
||||
|
||||
type Policy struct {
|
||||
@@ -195,7 +196,44 @@ func findPolicyMatch(named reference.Named, mappings *PolicyMappings) (*PolicyMa
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func resolvePolicyById(opts *PolicyOptions) (*Policy, error) {
|
||||
if opts.PolicyId != "" {
|
||||
localMappings, err := LoadLocalMappings(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load local policy mappings: %w", err)
|
||||
}
|
||||
if localMappings != nil {
|
||||
for _, mapping := range localMappings.Policies {
|
||||
if mapping.Id == opts.PolicyId {
|
||||
return resolveLocalPolicy(opts, &mapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// must check tuf
|
||||
tufMappings, err := loadTufMappings(opts.TufClient, opts.LocalTargetsDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load tuf policy mappings: %w", err)
|
||||
}
|
||||
for _, mapping := range tufMappings.Policies {
|
||||
if mapping.Id == opts.PolicyId {
|
||||
return resolveTufPolicy(opts, &mapping)
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("policy with id %s not found", opts.PolicyId)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func ResolvePolicy(ctx context.Context, resolver oci.AttestationResolver, opts *PolicyOptions) (*Policy, error) {
|
||||
p, err := resolvePolicyById(opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve policy by id: %w", err)
|
||||
}
|
||||
if p != nil {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
imageName, err := resolver.ImageName(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get image name: %w", err)
|
||||
|
||||
@@ -31,7 +31,7 @@ func loadAttestation(t *testing.T, path string) *attestation.Envelope {
|
||||
|
||||
func TestRegoEvaluator_Evaluate(t *testing.T) {
|
||||
ctx, _ := test.Setup(t)
|
||||
|
||||
errorStr := "failed to resolve policy by id: policy with id non-existent-policy-id not found"
|
||||
TestDataPath := filepath.Join("..", "..", "test", "testdata")
|
||||
ExampleAttestation := filepath.Join(TestDataPath, "example_attestation.json")
|
||||
|
||||
@@ -47,8 +47,12 @@ func TestRegoEvaluator_Evaluate(t *testing.T) {
|
||||
isCanonical bool
|
||||
resolver oci.AttestationResolver
|
||||
policy *policy.PolicyOptions
|
||||
policyId string
|
||||
errorStr string
|
||||
}{
|
||||
{repo: "testdata/mock-tuf-allow", expectSuccess: true, isCanonical: false, resolver: defaultResolver},
|
||||
{repo: "testdata/mock-tuf-allow", expectSuccess: true, isCanonical: false, resolver: defaultResolver, policyId: "docker-official-images"},
|
||||
{repo: "testdata/mock-tuf-allow", expectSuccess: false, isCanonical: false, resolver: defaultResolver, policyId: "non-existent-policy-id", errorStr: errorStr},
|
||||
{repo: "testdata/mock-tuf-deny", expectSuccess: false, isCanonical: false, resolver: defaultResolver},
|
||||
{repo: "testdata/mock-tuf-verify-sig", expectSuccess: true, isCanonical: false, resolver: defaultResolver},
|
||||
{repo: "testdata/mock-tuf-wrong-key", expectSuccess: false, isCanonical: false, resolver: defaultResolver},
|
||||
@@ -69,11 +73,17 @@ func TestRegoEvaluator_Evaluate(t *testing.T) {
|
||||
tc.policy = &policy.PolicyOptions{
|
||||
TufClient: tufClient,
|
||||
LocalTargetsDir: test.CreateTempDir(t, "", "tuf-targets"),
|
||||
PolicyId: tc.policyId,
|
||||
}
|
||||
}
|
||||
|
||||
policy, err := policy.ResolvePolicy(ctx, tc.resolver, tc.policy)
|
||||
assert.NoErrorf(t, err, "failed to resolve policy")
|
||||
if tc.errorStr != "" {
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), tc.errorStr)
|
||||
return
|
||||
}
|
||||
require.NoErrorf(t, err, "failed to resolve policy")
|
||||
result, err := re.Evaluate(ctx, tc.resolver, policy, input)
|
||||
require.NoErrorf(t, err, "Evaluate failed")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user