You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Followup from the Docker build-recipe contract PR (#332).
BuildRequest.output_directory is documented in proto/codefly/services/builder/v0/builder.proto as "an absolute destination owned by the caller", but nothing asserts absoluteness anywhere.
It cannot be enforced inside core's BuildDockerBuildPlan (agents/services/docker_recipe.go): a relative destination still works correctly there (the filepath.WalkDir + filepath.Rel inventory is relative-safe), so an filepath.IsAbs guard in that function would be enforcement in the wrong layer — it would reject valid callers rather than catch a real failure. Nothing in core constructs or consumes the field; it arrives already-resolved as the destination string.
Ask
Enforce the "absolute" invariant where the field is actually populated — the CLI caller that sets BuildRequest.output_directory (separate repo). The CLI should resolve/validate to an absolute path before sending the build request, and reject a relative one with a clear error, so the doc'd contract is actually guaranteed.
Explicitly considered and NOT actioned (recorded so they aren't re-raised)
Honor dockerignore / hash only referenced files in the inventory — rejected. Hashing the entire emitted tree is intentional: the plan is a fingerprint of exactly what the agent wrote, and honoring dockerignore would make verification blind to drift in ignored-but-present files. The performance concern that motivated it was addressed by streaming the file hash (io.Copy) instead of os.ReadFile.
Symlink handling in the inventory walk — rejected. WalkDir doesn't descend directory symlinks and file-symlink reads are deterministic across Build and Verify, so it is not a verification bug. The one exploitable angle (a symlink pointing buildx's context/Dockerfile outside the tree) is a recipe path and is already closed by recipeRelPath's containment check in feat(builder): Docker build-recipe contract for CLI-owned builds #332.
Context
Followup from the Docker build-recipe contract PR (#332).
BuildRequest.output_directoryis documented inproto/codefly/services/builder/v0/builder.protoas "an absolute destination owned by the caller", but nothing asserts absoluteness anywhere.It cannot be enforced inside
core'sBuildDockerBuildPlan(agents/services/docker_recipe.go): a relativedestinationstill works correctly there (thefilepath.WalkDir+filepath.Relinventory is relative-safe), so anfilepath.IsAbsguard in that function would be enforcement in the wrong layer — it would reject valid callers rather than catch a real failure. Nothing incoreconstructs or consumes the field; it arrives already-resolved as thedestinationstring.Ask
Enforce the "absolute" invariant where the field is actually populated — the CLI caller that sets
BuildRequest.output_directory(separate repo). The CLI should resolve/validate to an absolute path before sending the build request, and reject a relative one with a clear error, so the doc'd contract is actually guaranteed.Explicitly considered and NOT actioned (recorded so they aren't re-raised)
dockerignore/ hash only referenced files in the inventory — rejected. Hashing the entire emitted tree is intentional: the plan is a fingerprint of exactly what the agent wrote, and honoring dockerignore would make verification blind to drift in ignored-but-present files. The performance concern that motivated it was addressed by streaming the file hash (io.Copy) instead ofos.ReadFile.WalkDirdoesn't descend directory symlinks and file-symlink reads are deterministic across Build and Verify, so it is not a verification bug. The one exploitable angle (a symlink pointing buildx's context/Dockerfile outside the tree) is a recipe path and is already closed byrecipeRelPath's containment check in feat(builder): Docker build-recipe contract for CLI-owned builds #332.