Skip to content

builder: enforce BuildRequest.output_directory is absolute at the CLI boundary #333

Description

@antoinetoussaint-byte

Context

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions