Seguridad de ArgoCD
Versiones compatibles: ArgoCD v2.9+ Última actualización: February 22, 2026
Tabla de contenidos
- Integración de SSO
- Gestión de Secret
- Configuración de TLS
- Registro de auditoría
- Seguridad de red
- Credenciales de repositorio
- Verificación de firmas GPG
Integración de SSO
ArgoCD admite varios proveedores de SSO para la autenticación.
Configuración de OIDC
Configuración genérica de OIDC en argocd-cm:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: OIDC
issuer: https://auth.example.com
clientID: argocd
clientSecret: $oidc.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
requestedIDTokenClaims:
groups:
essential: trueAlmacene el Secret del cliente:
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
stringData:
oidc.clientSecret: <your-client-secret>Integración con Okta
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Okta
issuer: https://dev-123456.okta.com
clientID: 0oa1234567890abcdef
clientSecret: $oidc.okta.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
requestedIDTokenClaims:
groups:
essential: trueConfiguración de la aplicación de Okta:
- Cree una nueva aplicación OIDC en Okta
- Establezca la URI de redirección de inicio de sesión:
https://argocd.example.com/api/dex/callback - Habilite el alcance "groups"
- Agregue la declaración de grupos al token ID
Integración con Azure AD
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Azure AD
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
clientID: <application-id>
clientSecret: $oidc.azure.clientSecret
requestedScopes:
- openid
- profile
- email
requestedIDTokenClaims:
groups:
essential: true
# For Azure AD groups, use the groups claim
# Configure in Azure: Token configuration > Add groups claimConfiguración de Azure AD:
- Registre una nueva aplicación en Azure AD
- Establezca la URI de redirección:
https://argocd.example.com/api/dex/callback - Agregue permisos de API:
openid,profile,email - Configure la declaración de grupos en la configuración de Token
AWS IAM Identity Center (AWS SSO)
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: AWS IAM Identity Center
issuer: https://identitycenter.amazonaws.com/ssoins-1234567890abcdef
clientID: <client-id>
clientSecret: $oidc.aws.clientSecret
requestedScopes:
- openid
- profile
- email
requestedIDTokenClaims:
groups:
essential: trueIntegración de Dex LDAP
Para LDAP/Active Directory, use Dex como agente de identidad:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
dex.config: |
connectors:
- type: ldap
name: Active Directory
id: ad
config:
host: ldap.example.com:636
insecureNoSSL: false
insecureSkipVerify: false
rootCAData: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
bindDN: cn=argocd,ou=Service Accounts,dc=example,dc=com
bindPW: $dex.ldap.bindPW
usernamePrompt: Username
userSearch:
baseDN: ou=Users,dc=example,dc=com
filter: "(objectClass=person)"
username: sAMAccountName
idAttr: sAMAccountName
emailAttr: mail
nameAttr: displayName
groupSearch:
baseDN: ou=Groups,dc=example,dc=com
filter: "(objectClass=group)"
userMatchers:
- userAttr: DN
groupAttr: member
nameAttr: cnIntegración de SAML
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
dex.config: |
connectors:
- type: saml
id: saml
name: SAML Provider
config:
ssoURL: https://idp.example.com/sso/saml
caData: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
redirectURI: https://argocd.example.com/api/dex/callback
usernameAttr: name
emailAttr: email
groupsAttr: groups
entityIssuer: https://argocd.example.com/api/dex/callbackAsignar grupos de SSO a RBAC
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
# Map SSO groups to ArgoCD roles
g, ArgoCD-Admins, role:admin
g, ArgoCD-Developers, role:developer
g, ArgoCD-Viewers, role:readonly
# Azure AD group IDs
g, 12345678-1234-1234-1234-123456789012, role:admin
# Okta groups
g, argocd-admins, role:adminGestión de Secret
Sealed Secrets
Cifre los Secret para almacenarlos de forma segura en Git:
# Install Sealed Secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# Install kubeseal CLI
brew install kubeseal
# Seal a secret
kubectl create secret generic my-secret \
--from-literal=password=secret123 \
--dry-run=client -o yaml | \
kubeseal --format yaml > sealed-secret.yamlapiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: my-secret
namespace: my-app
spec:
encryptedData:
password: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq...External Secrets Operator
Sincronice Secret desde proveedores externos:
# Install External Secrets Operator
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
--namespace external-secrets \
--create-namespaceAWS Secrets Manager
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets
namespace: my-app
spec:
provider:
aws:
service: SecretsManager
region: us-west-2
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-app-secrets
namespace: my-app
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets
kind: SecretStore
target:
name: my-app-secrets
creationPolicy: Owner
data:
- secretKey: database-password
remoteRef:
key: myapp/production
property: database-password
- secretKey: api-key
remoteRef:
key: myapp/production
property: api-keyHashiCorp Vault
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault
namespace: my-app
spec:
provider:
vault:
server: https://vault.example.com
path: secret
version: v2
auth:
kubernetes:
mountPath: kubernetes
role: external-secrets
serviceAccountRef:
name: external-secrets-sa
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: vault-secrets
namespace: my-app
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: SecretStore
target:
name: app-secrets
data:
- secretKey: password
remoteRef:
key: myapp/config
property: passwordArgoCD Vault Plugin (AVP)
Inyecte Secret directamente en los manifiestos:
# Install AVP as ArgoCD plugin
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: cmp-plugin
namespace: argocd
data:
avp.yaml: |
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: argocd-vault-plugin
spec:
allowConcurrency: true
discover:
find:
command:
- sh
- "-c"
- "find . -name '*.yaml' | xargs -I {} grep \"<path\\|avp\\.kubernetes\\.io\" {} | grep ."
generate:
command:
- argocd-vault-plugin
- generate
- "."
lockRepo: false
EOFÚselo en los manifiestos:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
annotations:
avp.kubernetes.io/path: "secret/data/myapp"
type: Opaque
stringData:
password: <password>
api-key: <api-key>SOPS (Secrets OPerationS)
Cifre Secret con age, GPG o KMS en la nube:
# Install SOPS
brew install sops
# Create .sops.yaml configuration
cat > .sops.yaml <<EOF
creation_rules:
- path_regex: .*secrets.*\.yaml$
kms: arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012
EOF
# Encrypt a secret file
sops -e secrets.yaml > secrets.enc.yamlConfigure ArgoCD para descifrar:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
kustomize.buildOptions: --enable-alpha-pluginsConfiguración de TLS
Certificado TLS personalizado
apiVersion: v1
kind: Secret
metadata:
name: argocd-server-tls
namespace: argocd
type: kubernetes.io/tls
stringData:
tls.crt: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
tls.key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----Integración con cert-manager
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: argocd-server-tls
namespace: argocd
spec:
secretName: argocd-server-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- argocd.example.com
privateKey:
algorithm: RSA
size: 2048TLS para el servidor de repositorio
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-tls-certs-cm
namespace: argocd
data:
# Add custom CA certificates for private Git servers
git.example.com: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----Registro de auditoría
Habilitar el registro de auditoría
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
namespace: argocd
data:
# API server audit logging
server.audit.enabled: "true"
server.audit.path: "/var/log/argocd/audit.log"
# Application controller logging
controller.log.format: json
controller.log.level: infoFormato de registro de auditoría
{
"level": "info",
"time": "2024-01-15T10:30:00Z",
"msg": "sync operation completed",
"application": "my-app",
"project": "default",
"user": "admin@example.com",
"action": "sync",
"result": "success",
"revision": "abc1234",
"destination": {
"server": "https://kubernetes.default.svc",
"namespace": "my-app"
}
}Reenviar registros a un sistema externo
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
namespace: argocd
spec:
template:
spec:
containers:
- name: argocd-server
volumeMounts:
- name: audit-logs
mountPath: /var/log/argocd
# Sidecar for log forwarding
- name: fluentbit
image: fluent/fluent-bit:latest
volumeMounts:
- name: audit-logs
mountPath: /var/log/argocd
- name: fluentbit-config
mountPath: /fluent-bit/etc/
volumes:
- name: audit-logs
emptyDir: {}
- name: fluentbit-config
configMap:
name: fluentbit-configSeguridad de red
Network Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-server-network-policy
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
policyTypes:
- Ingress
- Egress
ingress:
# Allow from ingress controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8083
egress:
# Allow to repo server
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server
ports:
- protocol: TCP
port: 8081
# Allow to Redis
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: argocd-redis
ports:
- protocol: TCP
port: 6379
# Allow to Kubernetes API
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-repo-server-network-policy
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-repo-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
- podSelector:
matchLabels:
app.kubernetes.io/name: argocd-application-controller
ports:
- protocol: TCP
port: 8081
egress:
# Allow to Git servers
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 22Estándares de seguridad de Pod
apiVersion: v1
kind: Namespace
metadata:
name: argocd
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restrictedCredenciales de repositorio
HTTPS con Personal Access Token
apiVersion: v1
kind: Secret
metadata:
name: repo-creds-github
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
type: Opaque
stringData:
type: git
url: https://github.com/myorg
password: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
username: gitAutenticación con clave SSH
apiVersion: v1
kind: Secret
metadata:
name: private-repo-ssh
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: git
url: git@github.com:myorg/private-repo.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
...
-----END OPENSSH PRIVATE KEY-----Autenticación de GitHub App
apiVersion: v1
kind: Secret
metadata:
name: repo-creds-github-app
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repo-creds
type: Opaque
stringData:
type: git
url: https://github.com/myorg
githubAppID: "123456"
githubAppInstallationID: "12345678"
githubAppPrivateKey: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----Credenciales de repositorio Helm
apiVersion: v1
kind: Secret
metadata:
name: helm-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: helm
name: private-charts
url: https://charts.example.com
username: admin
password: secretpasswordVerificación de firmas GPG
Verifique que los commits estén firmados por claves de confianza.
Configurar claves GPG
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-gpg-keys-cm
namespace: argocd
data:
# Add GPG public keys
developer1.asc: |
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
developer2.asc: |
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----Habilitar la verificación de firmas
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: secure-project
namespace: argocd
spec:
signatureKeys:
- keyID: ABC123DEF456
- keyID: DEF456GHI789
sourceRepos:
- https://github.com/myorg/secure-repoApplication con verificación de firmas
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: verified-app
namespace: argocd
spec:
project: secure-project
source:
repoURL: https://github.com/myorg/secure-repo
targetRevision: HEAD
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: my-appCuando la verificación de firmas está habilitada, ArgoCD:
- Comprueba si el commit está firmado
- Verifica la firma con las claves configuradas
- Rechaza la sincronización si la verificación falla
Cuestionario
Para evaluar lo que ha aprendido, pruebe el cuestionario de seguridad de ArgoCD.