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.