- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. ArgoCD Security Architecture Overview
- 2. Authentication
- 3. Authorization - RBAC
- 4. Repository Credential Management
- 5. Cluster Credential Management
- 6. Secret Management Integration
- 7. Network Security
- 8. Audit Logging
- 9. Security Best Practices
- 10. Summary
1. ArgoCD Security Architecture Overview
ArgoCD holds broad access to clusters and Git repositories as a GitOps tool for Kubernetes. Security is therefore central to ArgoCD operations.
Security Layers
Layer 1: Authentication
- Who is accessing?
- Local Users, SSO (OIDC/SAML/LDAP via Dex)
Layer 2: Authorization
- What can they do?
- RBAC Policies, AppProject Scoping
Layer 3: Credential Management
- Git repository, cluster access credentials
- Stored securely as Kubernetes Secrets
Layer 4: Secret Management
- Safe handling of application secrets
- Sealed Secrets, External Secrets, Vault
Layer 5: Network Security
- TLS, Network Policy, access restrictions
2. Authentication
Local Users
ArgoCD provides built-in user accounts:
# argocd-cm ConfigMap
data:
accounts.alice: apiKey, login
accounts.bob: login
accounts.ci-bot: apiKey
| Capability | Description |
|---|---|
| login | Web UI and CLI login |
| apiKey | API token generation (for automation) |
SSO via Dex
Dex is the built-in OIDC Identity Provider:
data:
url: https://argocd.example.com
dex.config: |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: YOUR_CLIENT_ID
clientSecret: $dex.github.clientSecret
orgs:
- name: my-org
teams:
- platform-team
- dev-team
Direct OIDC Integration (Without Dex)
Connect directly to Okta, Auth0, Keycloak:
data:
oidc.config: |
name: Okta
issuer: https://my-org.okta.com/oauth2/default
clientID: YOUR_CLIENT_ID
clientSecret: $oidc.okta.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
requestedIDTokenClaims:
groups:
essential: true
LDAP Integration
data:
dex.config: |
connectors:
- type: ldap
id: ldap
name: LDAP
config:
host: ldap.example.com:636
insecureNoSSL: false
bindDN: cn=admin,dc=example,dc=com
bindPW: $dex.ldap.bindPW
userSearch:
baseDN: ou=users,dc=example,dc=com
filter: "(objectClass=person)"
username: uid
idAttr: uid
emailAttr: mail
nameAttr: cn
groupSearch:
baseDN: ou=groups,dc=example,dc=com
filter: "(objectClass=groupOfNames)"
userMatchers:
- userAttr: DN
groupAttr: member
nameAttr: cn
Authentication Flow
SSO Login:
1. User accesses ArgoCD UI
2. Clicks "Log in via SSO"
3. API Server redirects to Dex authorization endpoint
4. Dex redirects to external IdP (GitHub/Okta/LDAP)
5. User authenticates at external IdP
6. IdP redirects to Dex callback URL (auth code)
7. Dex exchanges auth code for tokens
8. Dex generates ID Token (user info + groups)
9. API Server validates ID Token
10. ArgoCD JWT issued (includes group info)
11. JWT stored in browser cookie
3. Authorization - RBAC
RBAC Policy Structure
ArgoCD uses Casbin-based RBAC:
# argocd-rbac-cm ConfigMap
data:
policy.default: role:readonly
policy.csv: |
# Admin role
p, role:admin, applications, *, */*, allow
p, role:admin, clusters, *, *, allow
p, role:admin, repositories, *, *, allow
p, role:admin, projects, *, *, allow
# Developer role
p, role:developer, applications, get, */*, allow
p, role:developer, applications, sync, */*, allow
p, role:developer, applications, action/*, */*, allow
p, role:developer, logs, get, */*, allow
# Read-only role
p, role:readonly, applications, get, */*, allow
p, role:readonly, projects, get, *, allow
# CI/CD bot role
p, role:ci-bot, applications, sync, ci-project/*, allow
p, role:ci-bot, applications, get, ci-project/*, allow
# Group mappings (SSO groups -> ArgoCD roles)
g, platform-team, role:admin
g, dev-team, role:developer
g, viewers, role:readonly
g, ci-bot, role:ci-bot
scopes: '[groups, email]'
Resources and Actions
| Resource | Actions | Description |
|---|---|---|
| applications | get, create, update, delete, sync, override, action/* | Application management |
| clusters | get, create, update, delete | Cluster management |
| repositories | get, create, update, delete | Repository management |
| projects | get, create, update, delete | Project management |
| logs | get | Pod log viewing |
| exec | create | Pod exec execution |
AppProject RBAC
Fine-grained RBAC within AppProjects:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-alpha
spec:
roles:
- name: deployer
description: 'Deployment permissions'
policies:
- p, proj:team-alpha:deployer, applications, sync, team-alpha/*, allow
- p, proj:team-alpha:deployer, applications, get, team-alpha/*, allow
groups:
- team-alpha-deployers
- name: viewer
description: 'View permissions'
policies:
- p, proj:team-alpha:viewer, applications, get, team-alpha/*, allow
groups:
- team-alpha-viewers
4. Repository Credential Management
HTTPS Credentials
apiVersion: v1
kind: Secret
metadata:
name: repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: git
url: https://github.com/my-org/my-repo.git
username: git
password: ghp_XXXXXXXXXXXX
SSH Credentials
apiVersion: v1
kind: Secret
metadata:
name: repo-creds-ssh
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: git
url: git@github.com:my-org/my-repo.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Credential Templates
Apply common credentials to multiple repositories with the same pattern:
apiVersion: v1
kind: Secret
metadata:
name: repo-creds-template
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
type: Opaque
stringData:
type: git
url: https://github.com/my-org
username: git
password: ghp_XXXXXXXXXXXX
5. Cluster Credential Management
Least Privilege Principle
For production, apply minimal permissions instead of cluster-admin:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argocd-manager-minimal
rules:
- apiGroups: ['*']
resources: ['*']
verbs: ['get', 'list', 'watch']
- apiGroups: ['apps']
resources: ['deployments', 'statefulsets', 'daemonsets', 'replicasets']
verbs: ['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']
- apiGroups: ['']
resources: ['services', 'configmaps', 'secrets', 'serviceaccounts', 'namespaces', 'pods']
verbs: ['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']
- apiGroups: ['networking.k8s.io']
resources: ['ingresses', 'networkpolicies']
verbs: ['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']
- apiGroups: ['batch']
resources: ['jobs', 'cronjobs']
verbs: ['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']
6. Secret Management Integration
Sealed Secrets
Encrypt secrets for safe Git storage:
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: my-secret
namespace: default
spec:
encryptedData:
password: AgBy3i4OJSWK+...
template:
metadata:
name: my-secret
namespace: default
External Secrets Operator (ESO)
Integration with external secret management systems:
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
spec:
provider:
vault:
server: 'https://vault.example.com'
path: 'secret'
auth:
kubernetes:
mountPath: 'kubernetes'
role: 'argocd'
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-app-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: my-app-secrets
creationPolicy: Owner
data:
- secretKey: database-password
remoteRef:
key: my-app/database
property: password
SOPS Integration
SOPS selectively encrypts YAML values:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
stringData:
password: ENC[AES256_GCM,data:...,iv:...,tag:...,type:str]
api-key: ENC[AES256_GCM,data:...,iv:...,tag:...,type:str]
sops:
age:
- recipient: age1...
lastmodified: '2026-03-20T00:00:00Z'
version: 3.7.3
7. Network Security
TLS Configuration
# argocd-cmd-params-cm ConfigMap
data:
server.insecure: 'false'
reposerver.tls.minversion: '1.2'
Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-server-policy
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- port: 8080
protocol: TCP
- port: 8083
protocol: TCP
egress:
- to: []
8. Audit Logging
ArgoCD API Server logs all user operations:
Log entries:
- Timestamp: When the action occurred
- User: Who performed the action (including SSO groups)
- Action: What was done (sync, create, delete, etc.)
- Resource: Target Application or resource
- Result: Success/failure
Prometheus Metrics
ArgoCD exposes security-related metrics:
argocd_app_sync_total: Total sync count
argocd_app_info: Application state information
argocd_cluster_api_server_requests_total: Cluster API request count
argocd_redis_request_total: Redis request count
9. Security Best Practices
Authentication
- Mandate SSO in production
- Disable or rotate local admin account password
- Set expiry on API tokens
- Enable MFA (Multi-Factor Authentication)
Authorization
- Set default policy to
role:readonly - Apply Least Privilege principle
- Isolate teams with AppProjects
- Restrict sync permissions for production namespaces
Credentials
- Prefer SSH keys over HTTPS tokens
- Apply minimal scope to tokens
- Implement periodic key rotation
- Apply minimal RBAC for cluster access
Secrets
- Never store plaintext secrets in Git
- Use Sealed Secrets or External Secrets Operator
- Implement auto-rotation mechanisms for secrets
Network
- Apply TLS to all communications
- Restrict ArgoCD component access with Network Policies
- Limit ArgoCD UI access via VPN or IP whitelisting
10. Summary
Key elements of the ArgoCD security model:
- Authentication: SSO (OIDC/SAML/LDAP via Dex) + local users
- Authorization: Casbin RBAC + AppProject scoping
- Repository Credentials: Secure management via HTTPS/SSH Secrets
- Cluster Credentials: ServiceAccount + Least Privilege
- Secret Management: Sealed Secrets / ESO / AVP / SOPS
- Network Security: TLS + Network Policy
- Audit: API Server logs + Prometheus metrics
Properly configuring these security layers enables building a secure GitOps operational environment.