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.