Use Dagger with Private Git Repositories
Dagger recommends you to rely on your host's SSH authentication agent to securely authenticate against private remote Git repositories.
To clone private repositories, the only requirements are to run ssh-add
on the Dagger host (to add your SSH key to the authentication agent), and mount its socket using the SSHAuthSocket
parameter of the (Dagger.GitRef).Tree
API.
Assume that you have a Dagger CI tool containing the following code, which references a private repository:
- Go
- Node.js (TypeScript)
- Python
package main
import (
"context"
"fmt"
"os"
"dagger.io/dagger"
)
func main() {
ctx := context.Background()
client, err := dagger.Connect(ctx)
if err != nil {
panic(err)
}
defer client.Close()
// Retrieve path of authentication agent socket from host
sshAgentPath := os.Getenv("SSH_AUTH_SOCK")
// Private repository with a README.md file at the root.
readme, err := client.
Git("git@private-repository.git", dagger.GitOpts{
SSHAuthSocket: client.Host().UnixSocket(sshAgentPath),
}).
Branch("main").
Tree().
File("README.md").
Contents(ctx)
if err != nil {
panic(err)
}
fmt.Println("readme", readme)
}
import { connect, Client } from "@dagger.io/dagger"
import process from "process"
// initialize Dagger client
connect(async (client: Client) => {
// Collect value of SSH_AUTH_SOCK env var, to retrieve authentication socket path
const sshAuthSockPath = process.env.SSH_AUTH_SOCK?.toString() || ""
// Retrieve authentication socket ID from host
const sshAgentSocketID = await client.host().unixSocket(sshAuthSockPath).id()
const repo = client
// Retrieve the repository
.git("git@private-repository.git")
// Select the main branch, and the filesystem tree associated
.branch("main")
.tree({
sshAuthSocket: sshAgentSocketID,
})
// Select the README.md file
.file("README.md")
// Retrieve the content of the README file
const file = await repo.contents()
console.log(file)
})
"""Clone a Private Git Repository and print the content of the README.md file."""
import os
import sys
import anyio
import dagger
async def main():
async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as client:
# Collect value of SSH_AUTH_SOCK env var, to retrieve auth socket path
ssh_auth_path = os.environ.get("SSH_AUTH_SOCK", "")
# Retrieve authentication socket from host
ssh_agent_socket = client.host().unix_socket(ssh_auth_path)
repo = (
client
# Retrieve the repository
.git("git@private-repository.git")
# Select the main branch, and the filesystem tree associated
.branch("main").tree(ssh_auth_socket=ssh_agent_socket)
# Select the README.md file
.file("README.md")
)
# Retrieve the content of the README file
file = await repo.contents()
print(file)
anyio.run(main)
Now, first remove all the SSH keys from the authentication agent on the Dagger host:
➜ ssh-add -D
All identities removed.
Attempt to run the CI tool:
- Go
- Node.js (TypeScript)
- Python
➜ dagger run go run .
panic: input:1: git.branch.tree.file.contents failed to load cache key: failed to fetch remote
exit status 128
➜ dagger run node --loader ts-node/esm clone.ts
{'message': 'failed to load cache key: failed to fetch remote https://xxxxx@private-repository.git: exit status 128', 'locations': [{'line': 6, 'column': 11}], 'path': ['git', 'branch', 'tree', 'file', 'contents']}
➜ dagger run python clone.py
{'message': 'failed to load cache key: failed to fetch remote https://xxxxx@private-repository.git: exit status 128', 'locations': [{'line': 6, 'column': 11}], 'path': ['git', 'branch', 'tree', 'file', 'contents']}
The CI tool fails, as it is unable to find the necessary authentication credentials to read the private repository in the SSH authentication agent.
Now, add the SSH key to the authentication agent on the host and try again:
- Go
- Node.js (TypeScript)
- Python
➜ ssh-add
Identity added: xxxxx
dagger run go run .
readme #
➜ ssh-add
Identity added: xxxxx
➜ dagger run node --loader ts-node/esm clone.ts
readme #
➜ ssh-add
Identity added: xxxxx
➜ dagger run python clone.py
readme #
Finally, the CI tool succeeds in reading the private Git repository.