github.com/argoproj/argo-cd/v2@v2.10.5/docs/user-guide/projects.md (about) 1 ## Projects 2 3 Projects provide a logical grouping of applications, which is useful when Argo CD is used by multiple 4 teams. Projects provide the following features: 5 6 * restrict what may be deployed (trusted Git source repositories) 7 * restrict where apps may be deployed to (destination clusters and namespaces) 8 * restrict what kinds of objects may or may not be deployed (e.g. RBAC, CRDs, DaemonSets, NetworkPolicy etc...) 9 * defining project roles to provide application RBAC (bound to OIDC groups and/or JWT tokens) 10 11 ### The Default Project 12 13 Every application belongs to a single project. If unspecified, an application belongs to the 14 `default` project, which is created automatically and by default, permits deployments from any 15 source repo, to any cluster, and all resource Kinds. The default project can be modified, but not 16 deleted. When initially created, it's specification is configured to be the most permissive: 17 18 ```yaml 19 spec: 20 sourceRepos: 21 - '*' 22 destinations: 23 - namespace: '*' 24 server: '*' 25 clusterResourceWhitelist: 26 - group: '*' 27 kind: '*' 28 ``` 29 30 ### Creating Projects 31 32 Additional projects can be created to give separate teams different levels of access to namespaces. 33 The following command creates a new project `myproject` which can deploy applications to namespace 34 `mynamespace` of cluster `https://kubernetes.default.svc`. The permitted Git source repository is 35 set to `https://github.com/argoproj/argocd-example-apps.git` repository. 36 37 ```bash 38 argocd proj create myproject -d https://kubernetes.default.svc,mynamespace -s https://github.com/argoproj/argocd-example-apps.git 39 ``` 40 41 ### Managing Projects 42 43 Permitted source Git repositories are managed using commands: 44 45 ```bash 46 argocd proj add-source <PROJECT> <REPO> 47 argocd proj remove-source <PROJECT> <REPO> 48 ``` 49 50 We can also do negations of sources (i.e. do _not_ use this repo). 51 52 ```bash 53 argocd proj add-source <PROJECT> !<REPO> 54 argocd proj remove-source <PROJECT> !<REPO> 55 ``` 56 57 Declaratively we can do something like this: 58 59 ```yaml 60 spec: 61 sourceRepos: 62 # Do not use the test repo in argoproj 63 - '!ssh://git@GITHUB.com:argoproj/test' 64 # Nor any Gitlab repo under group/ 65 - '!https://gitlab.com/group/**' 66 # Any other repo is fine though 67 - '*' 68 ``` 69 70 A source repository is considered valid if the following conditions hold: 71 72 1. _Any_ allow source rule (i.e. a rule which isn't prefixed with `!`) permits the source 73 2. AND *no* deny source (i.e. a rule which is prefixed with `!`) rejects the source 74 75 Keep in mind that `!*` is an invalid rule, since it doesn't make any sense to disallow everything. 76 77 Permitted destination clusters and namespaces are managed with the commands (for clusters always provide server, the name is not used for matching): 78 79 ```bash 80 argocd proj add-destination <PROJECT> <CLUSTER>,<NAMESPACE> 81 argocd proj remove-destination <PROJECT> <CLUSTER>,<NAMESPACE> 82 ``` 83 84 As with sources, we can also do negations of destinations (i.e. install anywhere _apart from_). 85 86 ```bash 87 argocd proj add-destination <PROJECT> !<CLUSTER>,!<NAMESPACE> 88 argocd proj remove-destination <PROJECT> !<CLUSTER>,!<NAMESPACE> 89 ``` 90 91 Declaratively we can do something like this: 92 93 ```yaml 94 spec: 95 destinations: 96 # Do not allow any app to be installed in `kube-system` 97 - namespace: '!kube-system' 98 server: '*' 99 # Or any cluster that has a URL of `team1-*` 100 - namespace: '*' 101 server: '!https://team1-*' 102 # Any other namespace or server is fine though. 103 - namespace: '*' 104 server: '*' 105 ``` 106 107 As with sources, a destination is considered valid if the following conditions hold: 108 109 1. _Any_ allow destination rule (i.e. a rule which isn't prefixed with `!`) permits the destination 110 2. AND *no* deny destination (i.e. a rule which is prefixed with `!`) rejects the destination 111 112 Keep in mind that `!*` is an invalid rule, since it doesn't make any sense to disallow everything. 113 114 Permitted destination K8s resource kinds are managed with the commands. Note that namespaced-scoped 115 resources are restricted via a deny list, whereas cluster-scoped resources are restricted via 116 allow list. 117 118 ```bash 119 argocd proj allow-cluster-resource <PROJECT> <GROUP> <KIND> 120 argocd proj allow-namespace-resource <PROJECT> <GROUP> <KIND> 121 argocd proj deny-cluster-resource <PROJECT> <GROUP> <KIND> 122 argocd proj deny-namespace-resource <PROJECT> <GROUP> <KIND> 123 ``` 124 125 ### Assign Application To A Project 126 127 The application project can be changed using `app set` command. In order to change the project of 128 an app, the user must have permissions to access the new project. 129 130 ``` 131 argocd app set guestbook-default --project myproject 132 ``` 133 134 ## Project Roles 135 136 Projects include a feature called roles that enable automated access to a project's applications. 137 These can be used to give a CI pipeline a restricted set of permissions. For example, a CI system 138 may only be able to sync a single app (but not change its source or destination). 139 140 Projects can have multiple roles, and those roles can have different access granted to them. These 141 permissions are called policies, and they are stored within the role as a list of policy strings. 142 A role's policy can only grant access to that role and are limited to applications within the role's 143 project. However, the policies have an option for granting wildcard access to any application 144 within a project. 145 146 In order to create roles in a project and add policies to a role, a user will need permission to 147 update a project. The following commands can be used to manage a role. 148 149 ```bash 150 argocd proj role list 151 argocd proj role get 152 argocd proj role create 153 argocd proj role delete 154 argocd proj role add-policy 155 argocd proj role remove-policy 156 ``` 157 158 Project roles in itself are not useful without generating a token to associate to that role. Argo CD 159 supports JWT tokens as the means to authenticate to a role. Since the JWT token is 160 associated with a role's policies, any changes to the role's policies will immediately take effect 161 for that JWT token. 162 163 The following commands are used to manage the JWT tokens. 164 165 ```bash 166 argocd proj role create-token PROJECT ROLE-NAME 167 argocd proj role delete-token PROJECT ROLE-NAME ISSUED-AT 168 ``` 169 170 Since the JWT tokens aren't stored in Argo CD, they can only be retrieved when they are created. A 171 user can leverage them in the cli by either passing them in using the `--auth-token` flag or setting 172 the ARGOCD_AUTH_TOKEN environment variable. The JWT tokens can be used until they expire or are 173 revoked. The JWT tokens can created with or without an expiration, but the default on the cli is 174 creates them without an expirations date. Even if a token has not expired, it cannot be used if 175 the token has been revoked. 176 177 Below is an example of leveraging a JWT token to access a guestbook application. It makes the 178 assumption that the user already has a project named myproject and an application called 179 guestbook-default. 180 181 ```bash 182 PROJ=myproject 183 APP=guestbook-default 184 ROLE=get-role 185 argocd proj role create $PROJ $ROLE 186 argocd proj role create-token $PROJ $ROLE -e 10m 187 JWT=<value from command above> 188 argocd proj role list $PROJ 189 argocd proj role get $PROJ $ROLE 190 191 # This command will fail because the JWT Token associated with the project role does not have a policy to allow access to the application 192 argocd app get $APP --auth-token $JWT 193 # Adding a policy to grant access to the application for the new role 194 argocd proj role add-policy $PROJ $ROLE --action get --permission allow --object $APP 195 argocd app get $APP --auth-token $JWT 196 197 # Removing the policy we added and adding one with a wildcard. 198 argocd proj role remove-policy $PROJ $ROLE -a get -o $APP 199 argocd proj role add-policy $PROJ $ROLE -a get --permission allow -o '*' 200 # The wildcard allows us to access the application due to the wildcard. 201 argocd app get $APP --auth-token $JWT 202 argocd proj role get $PROJ $ROLE 203 204 205 argocd proj role get $PROJ $ROLE 206 # Revoking the JWT token 207 argocd proj role delete-token $PROJ $ROLE <id field from the last command> 208 # This will fail since the JWT Token was deleted for the project role. 209 argocd app get $APP --auth-token $JWT 210 ``` 211 212 ## Configuring RBAC With Projects 213 214 The project Roles allows configuring RBAC rules scoped to the project. The following sample 215 project provides read-only permissions on project applications to any member of `my-oidc-group` group. 216 217 *AppProject example:* 218 219 ```yaml 220 apiVersion: argoproj.io/v1alpha1 221 kind: AppProject 222 metadata: 223 name: my-project 224 namespace: argocd 225 spec: 226 roles: 227 # A role which provides read-only access to all applications in the project 228 - name: read-only 229 description: Read-only privileges to my-project 230 policies: 231 - p, proj:my-project:read-only, applications, get, my-project/*, allow 232 groups: 233 - my-oidc-group 234 ``` 235 236 You can use `argocd proj role` CLI commands or project details page in the user interface to configure the policy. 237 Note that each project role policy rule must be scoped to that project only. Use the `argocd-rbac-cm` ConfigMap described in 238 [RBAC](../operator-manual/rbac.md) documentation if you want to configure cross project RBAC rules. 239 240 ## Configuring Global Projects (v1.8) 241 242 Global projects can be configured to provide configurations that other projects can inherit from. 243 244 Projects, which match `matchExpressions` specified in `argocd-cm` ConfigMap, inherit the following fields from the global project: 245 246 * namespaceResourceBlacklist 247 * namespaceResourceWhitelist 248 * clusterResourceBlacklist 249 * clusterResourceWhitelist 250 * SyncWindows 251 * SourceRepos 252 * Destinations 253 254 Configure global projects in `argocd-cm` ConfigMap: 255 ```yaml 256 data: 257 globalProjects: |- 258 - labelSelector: 259 matchExpressions: 260 - key: opt 261 operator: In 262 values: 263 - prod 264 projectName: proj-global-test 265 kind: ConfigMap 266 ``` 267 268 Valid operators you can use are: In, NotIn, Exists, DoesNotExist. Gt, and Lt. 269 270 projectName: `proj-global-test` should be replaced with your own global project name. 271 272 ## Project scoped Repositories and Clusters 273 274 Normally, an Argo CD admin creates a project and decides in advance which clusters and Git repositories 275 it defines. However, this creates a problem in scenarios where a developer wants to add a repository or cluster 276 after the initial creation of the project. This forces the developer to contact their Argo CD admin again to update the project definition. 277 278 It is possible to offer a self-service process for developers so that they can add a repository and/or cluster in a project on their own even after the initial creation of the project. 279 280 For this purpose Argo CD supports project-scoped repositories and clusters. 281 282 To begin the process, Argo CD admins must configure RBAC security to allow this self-service behavior. 283 For example, to allow users to add project scoped repositories and admin would have to add 284 the following RBAC rules: 285 286 ``` 287 p, proj:my-project:admin, repositories, create, my-project/*, allow 288 p, proj:my-project:admin, repositories, delete, my-project/*, allow 289 p, proj:my-project:admin, repositories, update, my-project/*, allow 290 ``` 291 292 This provides extra flexibility so that admins can have stricter rules. e.g.: 293 294 ``` 295 p, proj:my-project:admin, repositories, update, my-project/https://github.example.com/*, allow 296 ``` 297 298 Once the appropriate RBAC rules are in place, developers can create their own Git repositories and (assuming 299 they have the correct credentials) can add them in an existing project either from the UI or the CLI. 300 Both the User interface and the CLI have the ability to optionally specify a project. If a project is specified then the respective cluster/repository is considered project scoped: 301 302 ```argocd repo add --name stable https://charts.helm.sh/stable --type helm --project my-project``` 303 304 For the declarative setup both repositories and clusters are stored as Kubernetes Secrets, and so a new field is used to denote that this resource is project scoped: 305 306 ```yaml 307 apiVersion: v1 308 kind: Secret 309 metadata: 310 name: argocd-example-apps 311 labels: 312 argocd.argoproj.io/secret-type: repository 313 type: Opaque 314 stringData: 315 project: my-project1 # Project scoped 316 name: argocd-example-apps 317 url: https://github.com/argoproj/argocd-example-apps.git 318 username: **** 319 password: **** 320 ``` 321 322 All the examples above talk about Git repositories, but the same principles apply to clusters as well. 323 324 ```yaml 325 apiVersion: v1 326 kind: Secret 327 metadata: 328 name: mycluster-secret 329 labels: 330 argocd.argoproj.io/secret-type: cluster 331 type: Opaque 332 stringData: 333 name: mycluster.example.com 334 project: my-project1 # Project scoped 335 server: https://mycluster.example.com 336 config: | 337 { 338 "bearerToken": "<authentication token>", 339 "tlsClientConfig": { 340 "insecure": false, 341 "caData": "<base64 encoded certificate>" 342 } 343 } 344 ``` 345 346 With project-scoped clusters we can also restrict projects to only allow applications whose destinations belong to the 347 same project. The default behavior allows for applications to be installed onto clusters which are not a part of the same 348 project, as the example below demonstrates: 349 350 ```yaml 351 apiVersion: argoproj.io/v1alpha1 352 kind: Application 353 metadata: 354 name: "some-ns" 355 spec: 356 destination: 357 # This destination might not actually be a cluster which belongs to `foo-project` 358 server: https://some-k8s-server/ 359 namespace: "some-ns" 360 project: foo-project 361 ``` 362 363 To prevent this behavior, we can set the attribute `permitOnlyProjectScopedClusters` on a project. 364 365 ```yaml 366 spec: 367 permitOnlyProjectScopedClusters: true 368 ``` 369 370 With this set, the application above would no longer be allowed to be synced to any cluster other than the ones which 371 are a part of the same project.