Argo CD can connect to private Git repositories, but it needs credentials to do so.

Let’s see how this works with a live example. Imagine you have a private GitHub repository where your Kubernetes manifests are stored. You want Argo CD to deploy these manifests.

First, you’ll need to create a Secret in your Argo CD namespace (usually argocd) that contains your Git credentials. This secret will be of type kubernetes.io/basic-auth if you’re using username/password (or token), or kubernetes.io/ssh if you’re using SSH keys.

For GitHub, using a Personal Access Token (PAT) is highly recommended over your account password. You can generate a PAT in your GitHub settings under "Developer settings" -> "Personal access tokens". Make sure to grant it the repo scope.

Here’s how you’d create a basic auth secret for GitHub using a PAT:

apiVersion: v1
kind: Secret
metadata:
  name: github-creds
  namespace: argocd
type: kubernetes.io/basic-auth
stringData:
  username: YOUR_GITHUB_USERNAME
  password: YOUR_GITHUB_PAT

Replace YOUR_GITHUB_USERNAME with your actual GitHub username and YOUR_GITHUB_PAT with your generated Personal Access Token. Apply this secret to your cluster:

kubectl apply -f github-creds.yaml -n argocd

If you prefer using SSH keys, you’d generate an SSH key pair, add the public key as a deploy key to your GitHub repository, and then create an ssh-privatekey secret.

apiVersion: v1
kind: Secret
metadata:
  name: github-ssh-key
  namespace: argocd
type: kubernetes.io/ssh
data:
  ssh-privatekey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...
    -----END OPENSSH PRIVATE KEY-----

The private key needs to be base64 encoded. You can achieve this with:

cat ~/.ssh/id_rsa | base64 -w 0

Then apply the secret:

kubectl apply -f github-ssh-key.yaml -n argocd

Once the secret is created, you tell Argo CD to use it when connecting to your repository. You do this by adding the project.argoproj.io/sync-windows annotation to your Application or AppProject manifest. This annotation specifies a list of repository credentials that Argo CD can use.

When creating your Argo CD Application manifest, you’ll reference the secret in the source section:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/your-username/your-private-repo.git
    targetRevision: HEAD
    path: path/to/your/manifests
    # For basic auth:
    # username: <username from secret>  # Usually not needed if secret name matches
    # password: <password from secret>  # Usually not needed if secret name matches
    # For SSH:
    sshPrivateKeySecretRef:
      name: github-ssh-key # The name of your SSH secret
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  project: default

Argo CD automatically looks for secrets named argocd-basic-auth or argocd-ssh-known-hosts in the argocd namespace. If your secret has a different name, you need to configure it explicitly in the Application spec.

The key here is that Argo CD’s Git automation controller, a component within Argo CD, is responsible for fetching code from Git. When it encounters a private repository, it consults its configured credentials. If a matching secret is found in the argocd namespace, it uses those credentials to authenticate with the Git provider.

The most surprising thing about this setup is that Argo CD doesn’t need a separate GitOps agent running in your cluster to talk to Git. The core Argo CD controller itself handles all Git interactions, making it a self-contained system for GitOps.

Let’s say you have an Application pointing to your private repo, and you’ve just applied the github-creds secret. Argo CD will now attempt to clone https://github.com/your-username/your-private-repo.git. The Git automation controller will see that this URL requires authentication. It will then search for a secret named github-creds in the argocd namespace. Upon finding it, it extracts the username and password (your PAT) and uses them to authenticate the Git request. If successful, it clones the repository and proceeds with syncing your application.

A common pitfall is forgetting to base64 encode the SSH private key when creating the secret. If you paste the key directly, Argo CD won’t be able to read it. The base64 -w 0 command ensures it’s properly encoded for Kubernetes secrets.

If you’ve correctly set up the secret and referenced it in your Application manifest, but Argo CD still can’t connect, the next error you’ll likely see is a Git clone failure due to invalid credentials or network issues.

Want structured learning?

Take the full Argocd course →