Skip to content

Commit f176d7a

Browse files
committed
Get image manifests in parallel
The versions check in the trusted task rules pulls each task bundle in the attestation which takes too much time. This adds a built-in that pulls all task bundles in parallel. https://issues.redhat.com/browse/EC-1600 Assisted-by: Claude-4.5-opus
1 parent b78dafc commit f176d7a

File tree

8 files changed

+204
-114
lines changed

8 files changed

+204
-114
lines changed

policy/lib/tekton/trusted.rego

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,24 @@ missing_all_trusted_tasks_data if {
8484

8585
# Returns true if the task uses a trusted Task reference.
8686
# Routes to the appropriate system based on data presence.
87-
is_trusted_task(task) if {
87+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
88+
is_trusted_task(task, manifests) if {
8889
not missing_trusted_task_rules_data
89-
is_trusted_task_rules(task)
90+
is_trusted_task_rules(task, manifests)
9091
}
9192

92-
is_trusted_task(task) if {
93+
is_trusted_task(task, manifests) if {
9394
missing_trusted_task_rules_data
9495
not missing_trusted_tasks_data
9596
is_trusted_task_legacy(task)
9697
}
9798

9899
# Returns a subset of tasks that do not use a trusted Task reference.
99100
# Routes to the appropriate system based on data presence.
100-
untrusted_task_refs(tasks) := result if {
101+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
102+
untrusted_task_refs(tasks, manifests) := result if {
101103
not missing_trusted_task_rules_data
102-
result := untrusted_task_refs_rules(tasks)
104+
result := untrusted_task_refs_rules(tasks, manifests)
103105
} else := result if {
104106
result := untrusted_task_refs_legacy(tasks)
105107
}
@@ -111,19 +113,21 @@ untrusted_task_refs(tasks) := result if {
111113
# =============================================================================
112114

113115
# Returns a subset of tasks that are untrusted according to trusted_task_rules.
114-
untrusted_task_refs_rules(tasks) := {task |
116+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
117+
untrusted_task_refs_rules(tasks, manifests) := {task |
115118
some task in tasks
116-
not is_trusted_task_rules(task)
119+
not is_trusted_task_rules(task, manifests)
117120
}
118121

119122
# Returns true if the task uses a trusted Task reference according to trusted_task_rules.
120123
# 1. If task matches a deny rule, it's not trusted
121124
# 2. If task matches an allow rule, it's trusted
122125
# 3. Otherwise, it's not trusted
123-
is_trusted_task_rules(task) if {
126+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
127+
is_trusted_task_rules(task, manifests) if {
124128
ref := task_ref(task)
125-
not _task_matches_deny_rule(ref)
126-
_task_matches_allow_rule(ref)
129+
not _task_matches_deny_rule(ref, manifests)
130+
_task_matches_allow_rule(ref, manifests)
127131
}
128132

129133
# Merging in the trusted_task_rules rule data
@@ -279,12 +283,13 @@ _rule_is_future(rule) if {
279283
}
280284

281285
# Returns future deny rules that would match the given task
282-
future_deny_rules_for_task(task) := matching_rules if {
286+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
287+
future_deny_rules_for_task(task, manifests) := matching_rules if {
283288
ref := task_ref(task)
284289
matching_rules := [rule |
285290
some rule in future_deny_rules
286291
_pattern_matches(ref.key, rule.pattern)
287-
_version_satisfies_any_rule_constraints(ref, rule)
292+
_version_satisfies_any_rule_constraints(ref, rule, manifests)
288293
]
289294
}
290295

@@ -297,19 +302,21 @@ _rule_is_effective(rule) if {
297302
}
298303

299304
# Returns true if the task reference matches a deny rule pattern and version constraints (if specified)
300-
_task_matches_deny_rule(ref) if {
305+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
306+
_task_matches_deny_rule(ref, manifests) if {
301307
some rule in _effective_deny_rules
302308
_pattern_matches(ref.key, rule.pattern)
303-
_version_satisfies_any_rule_constraints(ref, rule)
309+
_version_satisfies_any_rule_constraints(ref, rule, manifests)
304310
}
305311

306312
# Returns a list of patterns from deny rules that match the task, or an empty list if no deny rules match.
307313
# This only applies to trusted_task_rules (not legacy trusted_tasks).
308-
denying_pattern(task) := [rule.pattern |
314+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
315+
denying_pattern(task, manifests) := [rule.pattern |
309316
ref := task_ref(task)
310317
some rule in _effective_deny_rules
311318
_pattern_matches(ref.key, rule.pattern)
312-
_version_satisfies_any_rule_constraints(ref, rule)
319+
_version_satisfies_any_rule_constraints(ref, rule, manifests)
313320
]
314321

315322
# Returns the reason why a task reference was denied, or nothing if the task is trusted.
@@ -319,8 +326,9 @@ denying_pattern(task) := [rule.pattern |
319326
# 2. It doesn't match any allow rule pattern (type: "not_allowed", pattern: empty list)
320327
# 3. No effective allow rules exist but raw rules are defined (type: "no_effective_rules")
321328
# This only applies to trusted_task_rules (not legacy trusted_tasks).
322-
denial_reason(task) := reason if {
323-
deny_info := _denying_rules_info(task)
329+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
330+
denial_reason(task, manifests) := reason if {
331+
deny_info := _denying_rules_info(task, manifests)
324332
count(deny_info.patterns) > 0
325333
reason := {
326334
"type": "deny_rule",
@@ -332,8 +340,8 @@ denial_reason(task) := reason if {
332340
# Only applies if there are effective allow rules defined
333341
ref := task_ref(task)
334342
count(_effective_allow_rules) > 0
335-
not _task_matches_allow_rule(ref)
336-
not _task_matches_deny_rule(ref)
343+
not _task_matches_allow_rule(ref, manifests)
344+
not _task_matches_deny_rule(ref, manifests)
337345

338346
reason := {
339347
"type": "not_allowed",
@@ -354,25 +362,27 @@ denial_reason(task) := reason if {
354362
}
355363

356364
# Returns patterns and messages from deny rules that match the task
357-
_denying_rules_info(task) := {"patterns": patterns, "messages": messages} if {
365+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
366+
_denying_rules_info(task, manifests) := {"patterns": patterns, "messages": messages} if {
358367
ref := task_ref(task)
359368

360369
# Get all matching deny rules
361370
matching_rules := [rule |
362371
some rule in _effective_deny_rules
363372
_pattern_matches(ref.key, rule.pattern)
364-
_version_satisfies_any_rule_constraints(ref, rule)
373+
_version_satisfies_any_rule_constraints(ref, rule, manifests)
365374
]
366375

367376
patterns := [rule.pattern | some rule in matching_rules]
368377
messages := [rule.message | some rule in matching_rules; "message" in object.keys(rule)]
369378
}
370379

371380
# Returns true if the task reference matches an allow rule pattern and version constraints (if specified)
372-
_task_matches_allow_rule(ref) if {
381+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
382+
_task_matches_allow_rule(ref, manifests) if {
373383
some rule in _effective_allow_rules
374384
_pattern_matches(ref.key, rule.pattern)
375-
_version_satisfies_all_rule_constraints(ref, rule)
385+
_version_satisfies_all_rule_constraints(ref, rule, manifests)
376386
}
377387

378388
# Converts a wildcard pattern to a regex pattern and checks if the key matches
@@ -478,11 +488,12 @@ _trusted_task_rules_schema := {
478488
# Returns false if versions field exists but no manifest version is found (don't allow by default for security)
479489
# Returns true if task version satisfies all constraints
480490
# Returns false otherwise
481-
_version_satisfies_all_rule_constraints(ref, rule) if {
491+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
492+
_version_satisfies_all_rule_constraints(ref, rule, manifests) if {
482493
not "versions" in object.keys(rule)
483494
} else if {
484495
# If versions field exists, manifest version must be found
485-
manifest_version := _get_manifest_version_annotation(ref)
496+
manifest_version := _get_manifest_version_annotation(ref, manifests)
486497
version := _normalize_version(manifest_version)
487498
semver.is_valid(version)
488499

@@ -505,18 +516,19 @@ _version_satisfies_all_rule_constraints(ref, rule) if {
505516
# Returns true if versions field exists but no manifest version is found (deny by default for security)
506517
# Returns true if task version satisfies at least one constraint
507518
# Returns false otherwise
508-
_version_satisfies_any_rule_constraints(ref, rule) if {
519+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
520+
_version_satisfies_any_rule_constraints(ref, rule, manifests) if {
509521
not "versions" in object.keys(rule)
510522
} else if {
511523
# If versions field exists but no manifest version found, deny the task (return true)
512524
"versions" in object.keys(rule)
513-
not _get_manifest_version_annotation(ref)
525+
not _get_manifest_version_annotation(ref, manifests)
514526
} else if {
515-
manifest_version := _get_manifest_version_annotation(ref)
527+
manifest_version := _get_manifest_version_annotation(ref, manifests)
516528
version := _normalize_version(manifest_version)
517529
not semver.is_valid(version)
518530
} else if {
519-
manifest_version := _get_manifest_version_annotation(ref)
531+
manifest_version := _get_manifest_version_annotation(ref, manifests)
520532
version := _normalize_version(manifest_version)
521533
semver.is_valid(version)
522534

@@ -572,11 +584,10 @@ _result_satisfies_operator(result, constraint) if {
572584
result < 0
573585
} else := false
574586

575-
_get_manifest_version_annotation(ref) := version if {
576-
# Only attempt to fetch manifest for bundle references
577-
bundle_ref := object.get(ref, "bundle", "")
578-
bundle_ref != ""
579-
task_manifest := ec.oci.image_manifest(bundle_ref)
587+
# Returns the version annotation from the manifest for a bundle reference.
588+
# manifests is a map of bundle_ref -> manifest from ec.oci.image_manifests
589+
_get_manifest_version_annotation(ref, manifests) := version if {
590+
task_manifest := manifests[ref.bundle]
580591
annotations := object.get(task_manifest, "annotations", {})
581592
version := annotations["org.opencontainers.image.version"]
582593
version != null

0 commit comments

Comments
 (0)