Skip to content

policy: add recursive provenance material resolution#3662

Merged
crazy-max merged 4 commits intodocker:masterfrom
tonistiigi:policy-recursive-materials
Feb 27, 2026
Merged

policy: add recursive provenance material resolution#3662
crazy-max merged 4 commits intodocker:masterfrom
tonistiigi:policy-recursive-materials

Conversation

@tonistiigi
Copy link
Member

@tonistiigi tonistiigi commented Feb 23, 2026

closes #3639

return dockerMaterialSource(uri, dgst)
}

if gu, err := gitutil.ParseURL(uri); err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was looking at our gitutil and it only accepts http|https|ssh|git so common SLSA-style git+https://... URIs fail parse and then fail HTTP detection, so they are treated as unsupported and never resolved: https://slsa.dev/spec/v1.2/build-provenance#builddefinition

"externalParameters": {
    "repository": "https://github.com/octocat/hello-world",
    "ref": "refs/heads/main"
},
"resolvedDependencies": [{
    "uri": "git+https://github.com/octocat/hello-world@refs/heads/main",
    "digest": {"gitCommit": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"}
}]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think buildkit can produce git+https:// atm and there isn't specific git definition for purl. Just https URLs are used, and gitutil figures out if the URL is pointing to a repo.

Comment on lines +168 to +173
if _, _, err := parseSLSAMaterial(rd); err != nil {
if logf != nil {
logf(logrus.WarnLevel, fmt.Sprintf("skipping unsupported provenance material %q: %v", m.URI, err))
}
continue
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iiuc malformed material entries are silently filtered out and that includes digest mismatch errors, so invalid/tampered materials are omitted from input.image.provenance.materials instead of causing evaluation failure. Could that potentially hide the material records policy is supposed to inspect?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be preferred as we don't want images to fail automatically when new material types are added. Instead atm it will fail based on policy rules. So if the user has a policy rule expecting a specific material, but it fails to parse in here, then that policy rule will fail the build.

@crazy-max
Copy link
Member

Unify root/material unknown resolution with recursive Input traversal.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Track fields reloaded during eval --print resolution loops and filter
final invalid-field warnings against that set.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
@tonistiigi tonistiigi force-pushed the policy-recursive-materials branch from 1527c6a to 88cba2c Compare February 26, 2026 17:14
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Allow child refs from partial evaluation to match allowed parent keys on
path boundaries and return canonical unknowns for metadata resolution.

Add tests for parent-child matching and boundary safety cases.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
@tonistiigi
Copy link
Member Author

I did some more testing and unfortunately this does not behave quite as well as I would have hoped. The properties of materials that are not initially present are only loaded if the material is accessed via a static index. If it is accessed dynamically, eg.

every m in input.image.provenance.materials
  check(m)

or

every m in input.image.provenance.materials
  allow with m as input

Then the rego library can not figure out what fields of the materials are actually required to be loaded.

So while this is working (and maybe more useful in the policy eval atm) only subset of policy rules can be used, and actual dynamic recusiveness is hard to achieve atm. I'm not sure if it would be possible to extend rego library or alternatively some of this logic could instead be exposed as a custom helper in the future.

I added some new examples to https://github.com/tonistiigi/buildx-rego-examples

Copy link
Member

@crazy-max crazy-max left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok iiuc recursive material loading is currently reliable only for statically indexed material access, while dynamic iteration (every m in input.image.provenance.materials) doesn't give enough hints for lazy resolution.

As follow-up I agree that we should either extend unknown-field discovery in the Rego lib or add a dedicated helper that pre-resolves/iterates material inputs in a policy-friendly way.

@crazy-max crazy-max merged commit e43156d into docker:master Feb 27, 2026
159 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Policy: add provenance fields

2 participants