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