23 min to read
Enterprise-Grade ArgoCD SSO with GitLab Integration
Production-ready guide to implementing secure ArgoCD SSO with GitLab including advanced RBAC and multi-cluster federation

Overview
In the last post, I tried configuring ArgoCD SSO using Google Oauth,
This post explains how to configure Single Sign-On (SSO) for ArgoCD using GitLab. We’ll walk through the process of setting up GitLab OAuth and integrating it with ArgoCD.
Enterprise GitOps Authentication Architecture
Modern enterprise environments require sophisticated authentication strategies that can scale across multiple clusters while maintaining security and compliance. The integration between ArgoCD and GitLab provides a robust foundation for enterprise GitOps workflows.
Benefits of GitLab SSO Integration
-
Unified Authentication
Allows developers to use their existing GitLab credentials for ArgoCD access. -
Streamlined Access Management
Leverages GitLab's groups and user management for ArgoCD authorization. -
Improved Developer Experience
Eliminates the need to manage separate credentials for GitLab and ArgoCD. -
Consistent Permissions
GitLab groups can be mapped directly to ArgoCD roles for consistent access control.
Prerequisites
- GitLab instance (Self-hosted CE/EE 13.0+ or GitLab.com)
- ArgoCD 2.8+ installed on a Kubernetes cluster
- Administrative access to both GitLab and ArgoCD
- Properly configured DNS for ArgoCD server
- SSL/TLS certificates for secure communication
- Kubernetes RBAC enabled cluster
Security Planning Considerations
Before implementing SSO, consider these enterprise security requirements:
Security Domain | Requirements | Implementation |
---|---|---|
Identity Provider | Multi-factor authentication, SAML integration | GitLab + Enterprise SSO |
Network Security | TLS 1.3, Network policies, WAF | Ingress + cert-manager |
Access Control | Least privilege, role separation | RBAC + Project isolation |
Audit & Compliance | Complete audit trails, compliance reporting | Centralized logging + monitoring |
Steps
1. Create GitLab Application
Console Method
- Navigate to Admin Area > Applications in GitLab
- Create new application:
- Name: Argo CD
- Redirect URI: https://argocd-server-urlapi/dex/callback
- Select Scopes:
- read_user
- openid
- profile
- Save the credentials:
- Application ID (Client ID)
- Secret (Client Secret)
Command Line Setup
If you’re using GitLab API to create the application:
GitLab Application Security Considerations
Application Security Best Practices:
- Scopes Selection:
- Only select required scopes (read_user, openid, profile, email)
- Avoid adding unnecessary permissions like
api
orwrite_repository
- Application Configuration:
- Use a descriptive application name for audit purposes
- Set application expiration date for security rotation
- Rotate client secrets every 90 days in production
- Use secure redirect URI validation
- Access Management:
- Limit admin access to GitLab application settings
- Document the integration for security reviews
- Implement approval workflows for changes
Enterprise Security Enhancements:
# Enhanced security configuration
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.your-domain.com
clientID: $dex.gitlab.clientId
clientSecret: $dex.gitlab.clientSecret
redirectURI: https://argocd.your-domain.com/api/dex/callback
groups:
- engineering
- platform
# Enhanced security options
useLoginAsID: false
insecureSkipVerify: false
# Custom CA certificate for private GitLab
rootCAs: |
-----BEGIN CERTIFICATE-----
... your CA certificate ...
-----END CERTIFICATE-----
2. Configure ArgoCD Installation
Create values/mgmt.yaml
with production-ready configuration:
global:
domain: argocd.your-domain.com
configs:
params:
create: true
server.insecure: false # Always use TLS in production
# Security hardening
server.enable.grpc.web: true
server.grpc.keepalive.time: 60s
server.grpc.keepalive.timeout: 5s
ssh:
extraHosts: |
gitlab.your-domain.com ssh-rsa AAAAB3N...
gitlab.your-domain.com ecdsa-sha2-nistp256...
gitlab.your-domain.com ssh-ed25519 AAAA..
# Global security configurations
cm:
# Session timeout for security
timeout.hard.reconciliation: 0
timeout.reconciliation: 180s
# Application source restrictions
application.instanceLabelKey: argocd.argoproj.io/instance
# Repository credentials template
repositories: |
- type: git
url: https://gitlab.your-domain.com
passwordSecret:
name: gitlab-secret
key: password
usernameSecret:
name: gitlab-secret
key: username
controller:
replicas: 3 # High availability
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
# Application controller metrics
metrics:
enabled: true
serviceMonitor:
enabled: true
dex:
enabled: true
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 250m
memory: 128Mi
redis:
enabled: true
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
server:
replicas: 3 # High availability
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 250m
memory: 512Mi
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/grpc-backend: "true"
ingressClassName: "nginx"
path: /
pathType: Prefix
tls:
- secretName: argocd-server-tls
hosts:
- argocd.your-domain.com
# Server metrics
metrics:
enabled: true
serviceMonitor:
enabled: true
repoServer:
replicas: 3 # High availability
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 250m
memory: 512Mi
# Repo server metrics
metrics:
enabled: true
serviceMonitor:
enabled: true
applicationSet:
replicas: 2 # High availability
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
notifications:
enabled: true
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
# Notification integrations
notifiers:
service.slack: |
token: $slack-token
service.email.gmail: |
username: $email-username
password: $email-password
host: smtp.gmail.com
port: 587
from: $email-username
3. Configure GitLab SSO
Update values/mgmt.yaml
with SSO configuration:
configs:
cm:
timeout.reconciliation: 60s
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: <gitlab url>
clientID: <application id>
clientSecret: <secret>
redirectURI: https://<argocd url>/api/dex/callback
groups:
- server
rbac:
create: true
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, *, *, allow
p, role:org-admin, projects, get, *, allow
p, role:org-admin, logs, get, *, allow
p, role:org-admin, exec, create, */*, allow
g, <group>, role:org-admin
secrets:
dex.gitlab.clientId: "<application id>"
dex.gitlab.clientSecret: "<secret>"
Apply the changes:
helm upgrade argocd . -n argocd -f ./values/mgmt.yaml
kubectl rollout restart -n argocd deployment argocd-dex-server
4. Test Login
Access your ArgoCD instance and verify GitLab SSO login works correctly.
Advanced GitLab SSO Configuration
Multi-Environment RBAC Strategy
Implement a comprehensive RBAC strategy that scales across multiple environments:
configs:
rbac:
policy.csv: |
# Global Admin Role - Full cluster access
p, role:global-admin, applications, *, */*, allow
p, role:global-admin, clusters, *, *, allow
p, role:global-admin, repositories, *, *, allow
p, role:global-admin, projects, *, *, allow
p, role:global-admin, accounts, *, *, allow
p, role:global-admin, certificates, *, *, allow
p, role:global-admin, gpgkeys, *, *, allow
p, role:global-admin, logs, *, *, allow
p, role:global-admin, exec, *, *, allow
# Platform Team - Infrastructure management
p, role:platform-admin, applications, *, platform/*, allow
p, role:platform-admin, applications, *, infrastructure/*, allow
p, role:platform-admin, clusters, get, *, allow
p, role:platform-admin, repositories, *, *, allow
p, role:platform-admin, projects, get, *, allow
p, role:platform-admin, logs, *, platform/*, allow
p, role:platform-admin, logs, *, infrastructure/*, allow
# DevOps Team - Application deployment
p, role:devops-engineer, applications, *, */prod, allow
p, role:devops-engineer, applications, *, */staging, allow
p, role:devops-engineer, applications, sync, */*, allow
p, role:devops-engineer, repositories, get, *, allow
p, role:devops-engineer, logs, *, */*, allow
p, role:devops-engineer, exec, create, */staging, allow
# Senior Developers - Production read, staging full
p, role:senior-developer, applications, get, */prod, allow
p, role:senior-developer, applications, *, */staging, allow
p, role:senior-developer, applications, *, */dev, allow
p, role:senior-developer, logs, *, */*, allow
p, role:senior-developer, exec, create, */dev, allow
p, role:senior-developer, exec, create, */staging, allow
# Regular Developers - Development environment only
p, role:developer, applications, get, */prod, allow
p, role:developer, applications, get, */staging, allow
p, role:developer, applications, *, */dev, allow
p, role:developer, logs, *, */dev, allow
p, role:developer, exec, create, */dev, allow
# Security Team - Read-only audit access
p, role:security-auditor, applications, get, */*, allow
p, role:security-auditor, logs, get, */*, allow
p, role:security-auditor, repositories, get, *, allow
p, role:security-auditor, clusters, get, *, allow
# Map GitLab groups to roles
g, gitlab:platform-admins, role:global-admin
g, gitlab:infrastructure-team, role:platform-admin
g, gitlab:devops-engineers, role:devops-engineer
g, gitlab:senior-developers, role:senior-developer
g, gitlab:developers, role:developer
g, gitlab:security-team, role:security-auditor
# Default policy for authenticated users
policy.default: role:readonly
# Required scopes for group mapping
scopes: "[groups, email, profile]"
Role-Based Access Control with GitLab Groups
You can map different GitLab groups to different ArgoCD roles for granular access control:
configs:
rbac:
policy.csv: |
# Administrators with full access
p, role:admin, applications, *, */*, allow
p, role:admin, clusters, *, *, allow
p, role:admin, repositories, *, *, allow
p, role:admin, projects, *, *, allow
p, role:admin, accounts, *, *, allow
p, role:admin, gpgkeys, *, *, allow
p, role:admin, logs, *, *, allow
p, role:admin, exec, *, *, allow
p, role:admin, certificates, *, *, allow
# DevOps team with broad access but not admin
p, role:devops, applications, *, */*, allow
p, role:devops, clusters, get, *, allow
p, role:devops, repositories, *, *, allow
p, role:devops, logs, *, *, allow
p, role:devops, exec, create, */*, allow
# Developers with limited access
p, role:developer, applications, get, */*, allow
p, role:developer, applications, sync, */*, allow
p, role:developer, repositories, get, *, allow
p, role:developer, logs, get, */*, allow
# Map GitLab groups to roles
g, gitlab:platform-admin, role:admin
g, gitlab:devops-team, role:devops
g, gitlab:developers, role:developer
Project-Specific Access Control
You can also configure access to specific ArgoCD projects:
configs:
rbac:
policy.csv: |
# Team A access to Team A projects only
p, role:team-a, applications, *, team-a/*, allow
p, role:team-a, logs, *, team-a/*, allow
g, gitlab:team-a, role:team-a
# Team B access to Team B projects only
p, role:team-b, applications, *, team-b/*, allow
p, role:team-b, logs, *, team-b/*, allow
g, gitlab:team-b, role:team-b
Using GitLab Subgroups
If you have GitLab subgroups, you can map them in ArgoCD:
configs:
cm:
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.your-domain.com
clientID: <application_id>
clientSecret: <secret>
redirectURI: https://argocd.your-domain.com/api/dex/callback
groups:
- engineering/backend
- engineering/frontend
- operations/platform
Manual Installation and Configuration
If you’re not using Helm, here’s how to configure ArgoCD manually:
1. Create argocd-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.your-domain.com
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.your-domain.com
clientID: <application_id>
clientSecret: $dex.gitlab.clientSecret
redirectURI: https://argocd.your-domain.com/api/dex/callback
groups:
- devops
- engineering
2. Create argocd-secret for GitLab Credentials
# Convert client secret to base64
GITLAB_CLIENT_SECRET_BASE64=$(echo -n "your-gitlab-client-secret" | base64)
# Apply the secret
kubectl patch secret argocd-secret -n argocd --type=json -p='[{"op": "add", "path": "/data/dex.gitlab.clientSecret", "value":"'$GITLAB_CLIENT_SECRET_BASE64'"}]'
3. Configure RBAC
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, *, *, allow
p, role:org-admin, projects, get, *, allow
p, role:org-admin, logs, get, *, allow
p, role:org-admin, exec, create, */*, allow
g, gitlab:devops, role:org-admin
policy.default: role:readonly
scopes: "[groups, email]"
Troubleshooting GitLab SSO
Common Issues and Solutions:
1. Authentication Failed: - Verify client ID and secret match GitLab application
- Check baseURL points to correct GitLab instance
- Ensure redirectURI matches exactly (including trailing slash)
- Verify required scopes are enabled in GitLab application
2. User Successfully Authenticates but Has No Access: - Check if user belongs to the correct GitLab group
- Verify groups are correctly mapped in RBAC policy
- Confirm 'groups' is included in scopes setting
- Check ArgoCD logs for group claim issues
3. Redirect URI Error: - Double check the redirect URI in both GitLab and ArgoCD config
- Ensure the ArgoCD server is accessible at the configured URL
- Check for TLS/SSL certificate issues
4. Timeout During Authentication: - Check network connectivity between ArgoCD and GitLab
- Verify GitLab instance is running and accessible
- Check for firewall or proxy issues
Debugging Steps
# Check Dex logs for authentication issues
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-dex-server
# Check ArgoCD server logs
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-server
# Verify configuration
kubectl get configmap argocd-cm -n argocd -o yaml
kubectl get configmap argocd-rbac-cm -n argocd -o yaml
# Check if secret is properly configured (will be masked)
kubectl get secret argocd-secret -n argocd -o yaml
Self-Hosted GitLab SSL Issues
If you’re using a self-signed certificate with GitLab, you may need to add it to ArgoCD:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
# ... existing config ...
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.your-domain.com
clientID: <application_id>
clientSecret: $dex.gitlab.clientSecret
redirectURI: https://argocd.your-domain.com/api/dex/callback
groups:
- devops
# For self-signed certificates:
insecureSkipVerify: true
Note: Using insecureSkipVerify: true
is not recommended for production environments. Instead, properly configure certificates.
Security Best Practices
- Access Control:
- Implement least privilege principle in RBAC policies
- Regularly audit group memberships in GitLab
- Periodically review ArgoCD access
- Credentials Management:
- Rotate GitLab client secret periodically
- Store secrets in Kubernetes secrets, not in plain text
- Consider using a secrets management solution
- Network Security:
- Use HTTPS for all communication
- Implement network policies in Kubernetes
- Consider IP restrictions if applicable
- Audit and Monitoring:
- Enable and review audit logs
- Set up alerts for unauthorized access attempts
- Monitor SSO configuration changes
Advanced Security Configuration
Network Policies for ArgoCD
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-security-policy
namespace: argocd
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: TCP
port: 443
- to: []
ports:
- protocol: TCP
port: 443 # HTTPS to GitLab
External Secrets Integration
Pod Security Standards
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: restricted
Enterprise Automation Framework
Here’s an enhanced automation script for enterprise GitLab SSO configuration:
Monitoring and Observability
Prometheus Metrics Configuration
Grafana Dashboard Integration
{
"dashboard": {
"title": "ArgoCD SSO Monitoring",
"panels": [
{
"title": "Login Success Rate",
"type": "stat",
"targets": [
{
"expr": "rate(argocd_server_login_successes_total[5m]) / (rate(argocd_server_login_successes_total[5m]) + rate(argocd_server_login_failures_total[5m])) * 100"
}
]
},
{
"title": "Active Sessions",
"type": "graph",
"targets": [
{
"expr": "argocd_server_sessions_total"
}
]
}
]
}
}
Multi-Cluster Federation
Hub Cluster Configuration
# Hub cluster ArgoCD configuration
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: spoke-cluster-apps
namespace: argocd
spec:
project: default
source:
repoURL: https://gitlab.your-domain.com/platform/cluster-configs
targetRevision: HEAD
path: spoke-clusters
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
Spoke Cluster Integration
# Register spoke cluster with hub
apiVersion: v1
kind: Secret
metadata:
name: spoke-cluster-secret
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: spoke-cluster-prod
server: https://spoke-cluster-api.your-domain.com
config: |
{
"bearerToken": "spoke-cluster-token",
"tlsClientConfig": {
"insecure": false,
"caData": "base64-encoded-ca-cert"
}
}
Advanced Authentication Patterns
SAML Integration with GitLab
For enterprise environments requiring SAML integration:
configs:
cm:
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.your-domain.com
clientID: $dex.gitlab.clientId
clientSecret: $dex.gitlab.clientSecret
redirectURI: https://argocd.your-domain.com/api/dex/callback
groups:
- engineering
- platform
- type: saml
id: saml
name: Enterprise SSO
config:
ssoURL: https://sso.your-domain.com/saml/login
redirectURI: https://argocd.your-domain.com/api/dex/callback
entityIssuer: https://argocd.your-domain.com/api/dex/callback
caData: |
-----BEGIN CERTIFICATE-----
... enterprise CA certificate ...
-----END CERTIFICATE-----
usernameAttr: email
emailAttr: email
groupsAttr: groups
JWT Token Configuration
configs:
cm:
# JWT token configuration
oidc.config: |
name: GitLab
issuer: https://gitlab.your-domain.com
clientId: your-application-id
clientSecret: $oidc.gitlab.clientSecret
requestedScopes: ["openid", "profile", "email", "groups"]
requestedIDTokenClaims: {"groups": {"essential": true}}
# Token lifetime configuration
skipClientIDCheck: false
skipIssuerCheck: false
# Custom claims mapping
claimsMapping:
groups: gitlab_groups
email: email
preferred_username: preferred_username
- OAuth Authentication
- SAML Authentication
- OpenID Connect Authentication
- Multi-factor Authentication (MFA)
- Certificate-based Authentication
- Security Configuration:
- TLS/SSL certificates properly configured
- Network policies implemented
- RBAC policies tested and validated
- Secret rotation strategy in place
- Audit logging enabled
- High Availability:
- Multiple replicas for all components
- Resource limits and requests defined
- Pod disruption budgets configured
- Health checks and readiness probes
- Monitoring & Observability:
- Prometheus metrics collection
- Grafana dashboards configured
- Alert rules defined
- Log aggregation setup
- Operational Excellence:
- Backup and disaster recovery plan
- Documentation and runbooks
- Incident response procedures
- Performance testing completed
- Compliance & Governance:
- Security policies enforced
- Compliance requirements met
- Change management process
- Access control regularly audited
Enterprise Deployment Patterns
Blue-Green Deployment for ArgoCD
# Blue environment
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd-blue
namespace: argocd-system
spec:
destination:
namespace: argocd-blue
server: https://kubernetes.default.svc
source:
path: argocd
repoURL: https://gitlab.your-domain.com/platform/argocd-config
targetRevision: v2.8.4
---
# Green environment
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd-green
namespace: argocd-system
spec:
destination:
namespace: argocd-green
server: https://kubernetes.default.svc
source:
path: argocd
repoURL: https://gitlab.your-domain.com/platform/argocd-config
targetRevision: v2.9.0
GitOps Repository Structure
├── clusters/
│ ├── production/
│ │ ├── cluster-config.yaml
│ │ └── applications/
│ ├── staging/
│ │ ├── cluster-config.yaml
│ │ └── applications/
│ └── development/
│ ├── cluster-config.yaml
│ └── applications/
├── applications/
│ ├── base/
│ ├── overlays/
│ │ ├── production/
│ │ ├── staging/
│ │ └── development/
├── projects/
│ ├── platform.yaml
│ ├── application-team-a.yaml
│ └── application-team-b.yaml
└── bootstrap/
└── argocd-apps.yaml
Conclusion
This comprehensive guide provides a production-ready approach to implementing enterprise-grade ArgoCD SSO with GitLab integration. By following these patterns and best practices, organizations can achieve:
- Scalable Authentication: Support for thousands of users across multiple clusters
- Enhanced Security: Zero-trust architecture with comprehensive audit trails
- Operational Excellence: Automated operations with robust monitoring and alerting
- Compliance Ready: Built-in governance and audit capabilities
The integration between ArgoCD and GitLab creates a powerful platform for modern software delivery, enabling teams to maintain velocity while ensuring security and compliance requirements are met at scale.
Comments