Skip to content
Open
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
79 changes: 79 additions & 0 deletions acceptance/examples/image_referrers.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package referrers

import rego.v1

# METADATA
# custom:
# short_name: count
deny contains result if {
refs := ec.oci.image_referrers(input.image.ref)
count(refs) != 2
result := {
"code": "referrers.count",
"msg": sprintf("Expected 2 referrers, got %d: %v", [count(refs), refs]),
}
}

# METADATA
# custom:
# short_name: format
deny contains result if {
descriptors := ec.oci.image_referrers(input.image.ref)
not all_descriptors_valid_format(descriptors)
result := {
"code": "referrers.format",
"msg": sprintf("Invalid referrer descriptor format in: %v", [descriptors]),
}
}

# METADATA
# custom:
# short_name: content_types
deny contains result if {
descriptors := ec.oci.image_referrers(input.image.ref)
not has_expected_artifact_types(descriptors)
result := {
"code": "referrers.content_types",
"msg": sprintf("Expected one signature and one attestation artifact type in referrers: %v", [descriptors]),
}
}

all_descriptors_valid_format(descriptors) if {
every descriptor in descriptors {
# Each descriptor should have required fields
descriptor.digest != ""
descriptor.mediaType != ""
descriptor.size >= 0
descriptor.artifactType != ""
descriptor.ref != ""

# Digest should be a digest-only format: sha256:<hex>
startswith(descriptor.digest, "sha256:")
not contains(descriptor.digest, "@")

# Ref should be a full OCI reference with digest format: registry/repo@sha256:<hex>
contains(descriptor.ref, "@")
contains(descriptor.ref, "sha256:")
# Split by @ and verify format
parts := split(descriptor.ref, "@")
count(parts) == 2
# Verify digest format matches
parts[1] == descriptor.digest
}
}

has_expected_artifact_types(descriptors) if {
# Check that we have one signature artifact directly from descriptors
signature_artifacts := [d |
some d in descriptors
d.artifactType == "application/vnd.dev.cosign.simplesigning.v1+json"
]
count(signature_artifacts) == 1

# Check that we have one attestation artifact directly from descriptors
attestation_artifacts := [d |
some d in descriptors
d.artifactType == "application/vnd.dsse.envelope.v1+json"
]
count(attestation_artifacts) == 1
}
75 changes: 75 additions & 0 deletions acceptance/examples/image_tag_refs.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package tag_refs

import rego.v1

# METADATA
# custom:
# short_name: count
deny contains result if {
refs := ec.oci.image_tag_refs(input.image.ref)
count(refs) != 2
result := {
"code": "tag_refs.count",
"msg": sprintf("Expected 2 tag-based artifact references, got %d: %v", [count(refs), refs]),
}
}

# METADATA
# custom:
# short_name: format
deny contains result if {
refs := ec.oci.image_tag_refs(input.image.ref)
not all_refs_valid_format(refs)
result := {
"code": "tag_refs.format",
"msg": sprintf("Invalid tag reference format in: %v", [refs]),
}
}

# METADATA
# custom:
# short_name: sig_count
deny contains result if {
refs := ec.oci.image_tag_refs(input.image.ref)
sig_count := count([ref | some ref in refs; contains(ref, ".sig")])
sig_count != 1
result := {
"code": "tag_refs.sig_count",
"msg": sprintf("Expected 1 .sig reference, got %d", [sig_count]),
}
}

# METADATA
# custom:
# short_name: att_count
deny contains result if {
refs := ec.oci.image_tag_refs(input.image.ref)
att_count := count([ref | some ref in refs; contains(ref, ".att")])
att_count != 1
result := {
"code": "tag_refs.att_count",
"msg": sprintf("Expected 1 .att reference, got %d", [att_count]),
}
}

all_refs_valid_format(refs) if {
every ref in refs {
# Each ref should be a valid OCI reference with tag format: registry/repo:sha256-<hex>.<suffix>
contains(ref, ":")
contains(ref, "sha256-")
# Split by : and get the last part (the tag)
parts := split(ref, ":")
tag_part := parts[count(parts) - 1]
# Tag should start with sha256- and end with .sig or .att
startswith(tag_part, "sha256-")
valid_suffix(tag_part)
}
}

valid_suffix(tag) if {
endswith(tag, ".sig")
}

valid_suffix(tag) if {
endswith(tag, ".att")
}
Loading
Loading