ArgoCD Image Updater - Authentication Guide
Configure authentication for container registries and Git repositories.
Registry Authentication
Docker Hub
apiVersion: v1
kind: Secret
metadata:
name: dockerhub-creds
namespace: argocd
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "<base64(username:password)>"
}
}
}
Generate the auth value (base64 encoded credentials):
# Generate the auth value (single base64 encoding of username:password)
echo -n 'username:password' | base64
# Example output: dXNlcm5hbWU6cGFzc3dvcmQ=
Note: The
authfield requires base64-encodedusername:password. UsingstringDatainstead ofdatameans Kubernetes handles the outer encoding automatically, so you only need to base64-encode the credentials once.
Reference in ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: argocd
data:
registries.conf: |
registries:
- name: Docker Hub
prefix: docker.io
api_url: https://registry-1.docker.io
credentials: pullsecret:argocd/dockerhub-creds
default: true
GitHub Container Registry (GHCR)
apiVersion: v1
kind: Secret
metadata:
name: ghcr-creds
namespace: argocd
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"ghcr.io": {
"auth": "<base64(username:PAT)>"
}
}
}
Registry configuration:
registries:
- name: GitHub Container Registry
prefix: ghcr.io
api_url: https://ghcr.io
credentials: pullsecret:argocd/ghcr-creds
Azure Container Registry (ACR)
Using Service Principal
apiVersion: v1
kind: Secret
metadata:
name: acr-creds
namespace: argocd
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"myregistry.azurecr.io": {
"auth": "<base64(SP_APP_ID:SP_PASSWORD)>"
}
}
}
Using Managed Identity (AKS)
If using Azure Workload Identity:
registries:
- name: ACR
prefix: myregistry.azurecr.io
api_url: https://myregistry.azurecr.io
# No credentials needed with Workload Identity
Amazon ECR
ECR requires dynamic credential retrieval since tokens expire every 12 hours. Use the external script method:
Step 1: Create the credential script Secret
apiVersion: v1
kind: Secret
metadata:
name: ecr-creds
namespace: argocd
type: Opaque
stringData:
ecr-login.sh: |
#!/bin/sh
aws ecr get-login-password --region us-east-1
Step 2: Mount the script into Image Updater deployment
Patch the argocd-image-updater deployment to mount the script:
# Add to deployment spec.template.spec.volumes:
volumes:
- name: ecr-script
secret:
secretName: ecr-creds
defaultMode: 0755 # Make script executable
# Add to deployment spec.template.spec.containers[0].volumeMounts:
volumeMounts:
- name: ecr-script
mountPath: /app/config/ecr
readOnly: true
If using Helm, add to values:
config:
extraVolumes:
- name: ecr-script
secret:
secretName: ecr-creds
defaultMode: 0755
extraVolumeMounts:
- name: ecr-script
mountPath: /app/config/ecr
readOnly: true
Step 3: Configure registry to use the script
registries:
- name: ECR
prefix: 123456789.dkr.ecr.us-east-1.amazonaws.com
api_url: https://123456789.dkr.ecr.us-east-1.amazonaws.com
credentials: ext:/app/config/ecr/ecr-login.sh
Important: Ensure AWS credentials are available to the pod via IAM Roles for Service Accounts (IRSA) or environment variables.
Google Container Registry (GCR)
apiVersion: v1
kind: Secret
metadata:
name: gcr-creds
namespace: argocd
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"gcr.io": {
"auth": "<base64(_json_key:SERVICE_ACCOUNT_JSON)>"
}
}
}
Quay.io
apiVersion: v1
kind: Secret
metadata:
name: quay-creds
namespace: argocd
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"quay.io": {
"auth": "<base64(username:password)>"
}
}
}
Credential Types
The Image Updater supports multiple credential formats in the ConfigMap registries.conf. Choose the appropriate type based on your secret format.
Pull Secret (Recommended for Docker Registries)
Use this when you have a standard Kubernetes docker-config secret (type kubernetes.io/dockerconfigjson). This is the most common approach for registry authentication.
credentials: pullsecret:<namespace>/<secret-name>
Example:
credentials: pullsecret:argocd/dockerhub-creds
Secret Reference
Use this when credentials are stored in a generic Opaque secret with separate keys for username and password, rather than the docker-config JSON format.
credentials: secret:<namespace>/<secret-name>#<key>
Example - referencing username and password from an Opaque secret:
# For a secret with keys 'username' and 'password':
apiVersion: v1
kind: Secret
metadata:
name: registry-creds
namespace: argocd
type: Opaque
stringData:
username: myuser
password: mytoken
# Reference in registries.conf:
registries:
- name: My Registry
prefix: registry.example.com
api_url: https://registry.example.com
credentials: secret:argocd/registry-creds#username
credsexpire: 5m # Optional: credential cache expiration
Note: The
secret:format references a single key. For username/password pairs, you may need to structure your secret appropriately or use thepullsecret:format with a docker-config secret instead.
Environment Variable
Reference credentials from environment variables set on the Image Updater pod:
credentials: env:REGISTRY_PASSWORD
External Script
For dynamic credentials that require runtime generation (like ECR tokens that expire):
credentials: ext:/path/to/script
The script must output the password/token to stdout. See the ECR section above for a complete example.
ImageUpdater CRD Authentication
Per-Image Credentials
apiVersion: argocd-image-updater.argoproj.io/v1alpha1
kind: ImageUpdater
metadata:
name: my-updater
namespace: argocd
spec:
registries:
- name: myregistry
prefix: myregistry.example.com
apiUrl: https://myregistry.example.com
credentials:
pullSecretRef:
name: registry-creds
namespace: argocd
applicationRefs:
- namePattern: "my-app"
images:
- alias: "app"
imageName: "myregistry.example.com/app"
Multiple Registries
spec:
registries:
- name: production
prefix: prod.registry.io
credentials:
pullSecretRef:
name: prod-creds
- name: development
prefix: dev.registry.io
credentials:
pullSecretRef:
name: dev-creds
Git Authentication
SSH Key
apiVersion: v1
kind: Secret
metadata:
name: git-ssh-key
namespace: argocd
type: Opaque
stringData:
sshPrivateKey: |
<SSH_PRIVATE_KEY_CONTENT>
# Generate with: ssh-keygen -t ed25519 -C "argocd-image-updater"
Deploy Key (GitHub)
- Generate SSH key:
ssh-keygen -t ed25519 -C "argocd-image-updater" -f deploy_key -N ""
Add public key as deploy key in GitHub repo settings
Create secret with private key:
kubectl create secret generic git-ssh-key \
--from-file=sshPrivateKey=deploy_key \
-n argocd
Personal Access Token (GitHub)
apiVersion: v1
kind: Secret
metadata:
name: github-token
namespace: argocd
type: Opaque
stringData:
username: git
password: ghp_xxxxxxxxxxxxxxxxxxxx
Required token scopes:
repo(for private repos)read:packages(for GHCR)
Azure DevOps
apiVersion: v1
kind: Secret
metadata:
name: azure-devops-creds
namespace: argocd
type: Opaque
stringData:
username: "" # Leave empty for PAT
password: <your-PAT>
Testing Authentication
Test Registry Access
# From Image Updater pod
kubectl exec -n argocd deployment/argocd-image-updater -- \
argocd-image-updater test myregistry.example.com/myimage
Test Git Access
# SSH
kubectl exec -n argocd deployment/argocd-image-updater -- \
ssh -T git@github.com
# HTTPS
kubectl exec -n argocd deployment/argocd-image-updater -- \
git ls-remote https://github.com/myorg/myrepo.git
Troubleshooting Authentication
Registry Authentication Failed
# Check secret exists and is correctly formatted
kubectl get secret dockerhub-creds -n argocd -o yaml
# Decode and verify
kubectl get secret dockerhub-creds -n argocd -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq .
Git Authentication Failed
# Check SSH key permissions
kubectl exec -n argocd deployment/argocd-image-updater -- \
ls -la /app/config/ssh/
# Test SSH connection
kubectl exec -n argocd deployment/argocd-image-updater -- \
ssh -vT git@github.com 2>&1 | head -50
ECR Token Expired
ECR tokens expire after 12 hours. Use the external script method:
#!/bin/sh
aws ecr get-login-password --region $AWS_REGION
Ensure AWS credentials are available (via IAM role or environment variables).