Safeguard
Developer Tools•

How do you clone a private repo in a Docker build without leaking keys?

Use an SSH mount so the build borrows your agent for one step and never stores the key in a layer. Steps, what to avoid, and how to verify the result.

Safeguard Security Team
3 min read

Use a BuildKit SSH mount. It forwards your SSH agent socket into one build step, so the build can clone a private repository without the private key ever being copied into an image layer. Avoid copying key files or passing tokens through build arguments.

What Docker documents

Docker's secrets guide says build arguments and environment variables persist in the final image, so secrets passed that way can leak, and recommends secret mounts or SSH mounts instead. SSH mounts expose an SSH agent socket or key to the build, which suits cloning private repositories. You pass your socket when you run the build, with the ssh option set to default.

The Dockerfile reference adds details. The SSH mount type forwards the agent socket, the default ID is default, and the default target is a socket path under the BuildKit run directory. Setting required to true fails the build if no key is available, which is better than a silent fallback.

Steps

  1. Start an SSH agent on the build machine and add the key that can read the repository.
  2. In the Dockerfile, use a RUN instruction with an SSH mount of type ssh for the clone step.
  3. Add the host's key to known hosts in that step, rather than disabling host checking.
  4. Run the build with the ssh option forwarding your default agent.
  5. Check the result with history and an image scan to confirm nothing sensitive stayed behind.
# RUN with an ssh mount, then clone
RUN git clone git@example.com:org/private-lib.git /src/private-lib

The comment shows the shape. The real instruction carries the mount type as an option on RUN, as in the reference.

What not to do

PracticeProblem
Copy a private key into the imageKey stays in a layer
Pass a token as a build argumentVisible in image history
Delete the key in a later stepEarlier layer still holds it
Turn off host key checkingOpens the build to impersonation

Deleting a file later does not remove it from earlier layers. See a deleted secret in a later layer is still there.

Use a narrow credential

Even with a safe mount, the build can use whatever the agent holds. Use a deploy key that is read only and limited to the repositories the build needs, and rotate it. In CI, prefer short lived credentials from your platform over a long lived personal key.

Better still, avoid the clone

Fetching private code at image build time makes the build depend on a live network and a moving branch. Where you can, vendor the dependency, publish it to a private package registry, or pin the clone to a commit hash. A pinned commit makes the build repeatable.

Quick check

Is a multi-stage build enough to hide a key?

It helps only if the key never lands in the final stage, but a mount is cleaner because the key is never written to a layer at all.

How do I confirm no secret leaked?

Run docker history with the no truncate option, inspect environment settings, and scan the image for secrets.

Safeguard

Safeguard does SBOM and dependency scanning, and its policies and gates can run in CI so a bad image does not reach production. You can try a free scan before deciding anything.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.