Hello! When operating GitOps in a Kubernetes environment, there’s a challenge you’re bound to face: controlling “who can access which project, and to what extent?”
Today, we will delve into the structure of Argo CD’s authorization engine, argocd-rbac-cm, and explore in detail the method for issuing CI-specific tokens based on AppProject, which can be considered the pinnacle of security. π οΈ

1. ποΈ The Heart of Argo CD RBAC: argocd-rbac-cm Overview
Argo CD fundamentally follows the Role-Based Access Control (RBAC) model. The ConfigMap responsible for these settings is argocd-rbac-cm.
π Key Components
- Policy: Follows the format p,
, , , - Scopes: Determines which group information to base permissions on (e.g., GitHub Org, Keycloak Group).
- Default Role: The default permission to grant to users for whom no specific permissions are defined (role:readonly is generally recommended).
π» argocd-rbac-cm Basic Configuration Example
YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
# 1. Default permission settings: Users without any specific permissions are set to read-only π§
policy.default: role:readonly
# 2. Custom policy definition π
# Format: p, <role/user/group>, <resource>, <action>, <object>, <allow/deny>
policy.csv: |
# The 'dev-team' role has 'sync' and 'get' permissions for all apps within the 'default' project
p, role:dev-team, applications, get, default/*, allow
p, role:dev-team, applications, sync, default/*, allow
# Map specific groups (when integrating OIDC) to roles
g, "my-github-org:eng-team", role:dev-team
# 3. CSV data source settings (default)
scopes: '[groups]'
2. π― Roles for Specific Projects: AppProject Role
It’s not feasible to grant all users full cluster permissions. Argo CD provides logical isolation through a unit called AppProject.
π Advantages of AppProject Role
- Multi-tenancy: Enforces that Team A manages only Project A, and Team B manages only Project B.
- Fine-grained Control: Allows setting permissions such that ‘application creation’ is possible within a project, but ‘project modification’ is not.
3. π How to Issue Scoped Tokens for CI Pipelines
Here’s the most important question: “How can CI tools like Jenkins or GitHub Actions securely obtain tokens that can only access specific projects?” π‘
Using a global administrator token (admin) is extremely risky. Instead, you should create a Role within an AppProject and issue a token tied to that Role.
Step 1: Define a Role within AppProject
First, modify the AppProject resource to create a dedicated role for CI.
YAML
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: ecommerce-project
namespace: argocd
spec:
description: "μ΄μ»€λ¨Έμ€ μλΉμ€ μ μ© νλ‘μ νΈ"
# ... Existing settings omitted ...
roles:
# 1. Define a role named 'ci-bot'. π€
- name: ci-bot
description: "CI νμ΄νλΌμΈμ© μ μ© ν ν° μν "
policies:
# This role can only update/sync applications within this project
- p, proj:ecommerce-project:ci-bot, applications, get, ecommerce-project/*, allow
- p, proj:ecommerce-project:ci-bot, applications, sync, ecommerce-project/*, allow
- p, proj:ecommerce-project:ci-bot, applications, update, ecommerce-project/*, allow
Step 2: Issue a Token using Argo CD CLI
Once the Role is created, you now need to generate a JWT token associated with this Role. This task is most easily performed using the Argo CD CLI.
Bash
# 1. Request token creation for a Role in a specific project
# --expires-in: Set token expiration time (e.g., 1 year = 8760h)
argocd proj role generate-token ecommerce-project ci-bot --expires-in 8760h
β οΈ Caution: The output token value is shown only once, so you must store it in a secure location (e.g., Vault, GitHub Secrets)!
Step 3: Utilize the Token in CI Environment
Now, register the issued token as an environment variable in your CI tool (e.g., ARGOCD_TOKEN) and use it as follows.
Bash
# Commands can be executed with just the token, without a separate login process! π
argocd app sync my-app --server argocd.example.com --auth-token $ARGOCD_TOKEN
4. π‘ Operational Tips: Checklist for More Secure RBAC
- Principle of Least Privilege: Never set policy.default to role:admin. It is safer to set it to role:readonly or leave it empty.
- Group-based Management: Instead of assigning ‘p’ policies to individual users, map OIDC (Okta, Dex, GitHub) groups to Roles using ‘g’ settings. This significantly boosts management efficiency.
- AppProject Token Management: Periodically renew (rotate) CI tokens, and immediately revoke tokens that are no longer in use with the argocd proj role delete-token command.
π Summary Table
| Category | Global RBAC (argocd-rbac-cm) | Project RBAC (AppProject) |
|---|---|---|
| Management Scope | Entire system permissions (Admin, Readonly, etc.) | Resource permissions within a specific project |
| Primary Target | Operations team, entire developer group | Specific service development team, CI bot |
| Token Issuance | Based on Local Account (Local User) | Based on Project Role |
| Recommended Use | System-wide access control | CI/CD Pipeline Integration (Scoped) |
—
π‘ Conclusion
Argo CD’s security begins with the harmony of macroscopic control via argocd-rbac-cm and microscopic control via AppProject. In particular, the CI-specific Scoped Token we explored today is the best way to minimize cluster security threats while increasing automation efficiency.
Apply it to your GitOps environment right now! If you have any questions, please leave a comment. π
Leave a Reply