> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/argoproj/argo-cd/llms.txt
> Use this file to discover all available pages before exploring further.

# Projects

> AppProject CRD for multi-tenancy, access control, and resource restrictions

Projects provide a logical grouping of applications with security and operational boundaries. They are especially useful when Argo CD is used by multiple teams.

## Overview

AppProject is a Custom Resource Definition (CRD) that provides:

* **Source restrictions** - Control which Git repositories can be deployed
* **Destination restrictions** - Control where apps may be deployed (clusters and namespaces)
* **Resource restrictions** - Control what kinds of Kubernetes objects can be deployed
* **RBAC** - Define project roles with fine-grained permissions

## AppProject CRD Structure

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: my-project
  namespace: argocd
spec:
  description: Project for team applications
  
  # Source repositories
  sourceRepos:
    - 'https://github.com/myorg/*'
    - 'https://charts.helm.sh/stable'
  
  # Destination clusters and namespaces
  destinations:
    - namespace: 'team-*'
      server: 'https://kubernetes.default.svc'
    - namespace: 'production'
      name: 'prod-cluster'
  
  # Cluster-scoped resource whitelist
  clusterResourceWhitelist:
    - group: ''
      kind: Namespace
  
  # Namespace-scoped resource blacklist
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota
    - group: ''
      kind: LimitRange
```

## The Default Project

Every application belongs to a project. If unspecified, applications belong to the `default` project.

### Default Project Specification

The `default` project is created automatically with permissive settings:

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: default
spec:
  sourceRepos:
    - '*'
  destinations:
    - namespace: '*'
      server: '*'
  clusterResourceWhitelist:
    - group: '*'
      kind: '*'
```

<Warning>
  The `default` project can be modified but not deleted. For production use, create dedicated projects with explicit restrictions.
</Warning>

### Locking Down Default Project

To prevent accidental use of the overly-permissive default project:

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: default
spec:
  sourceRepos: []
  destinations: []
  namespaceResourceBlacklist:
    - group: '*'
      kind: '*'
```

## Creating Projects

<Tabs>
  <Tab title="Declarative (YAML)">
    ```yaml theme={null}
    apiVersion: argoproj.io/v1alpha1
    kind: AppProject
    metadata:
      name: myproject
      namespace: argocd
    spec:
      sourceRepos:
        - https://github.com/argoproj/argocd-example-apps.git
      destinations:
        - server: https://kubernetes.default.svc
          namespace: mynamespace
    ```

    ```bash theme={null}
    kubectl apply -f project.yaml
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    argocd proj create myproject \
      -d https://kubernetes.default.svc,mynamespace \
      -s https://github.com/argoproj/argocd-example-apps.git
    ```
  </Tab>
</Tabs>

## Source Repository Restrictions

Control which Git repositories can be used:

### Allow Specific Repositories

```yaml theme={null}
spec:
  sourceRepos:
    - 'https://github.com/myorg/frontend-apps'
    - 'https://github.com/myorg/backend-apps'
    - 'https://charts.bitnami.com/bitnami'
```

### Using Wildcards

```yaml theme={null}
spec:
  sourceRepos:
    - 'https://github.com/myorg/*'
    - 'https://gitlab.com/team-*/*'
```

### Denying Repositories

Use `!` prefix to explicitly deny repositories:

```yaml theme={null}
spec:
  sourceRepos:
    # Deny specific test repository
    - '!ssh://git@github.com:argoproj/test'
    # Deny all GitLab repos under group/
    - '!https://gitlab.com/group/**'
    # Allow everything else
    - '*'
```

<Note>
  A repository is valid if ANY allow rule permits it AND NO deny rule rejects it. The pattern `!*` is invalid.
</Note>

### Managing Sources via CLI

```bash theme={null}
# Add source repository
argocd proj add-source myproject https://github.com/myorg/myrepo

# Remove source repository
argocd proj remove-source myproject https://github.com/myorg/myrepo

# Add denial pattern
argocd proj add-source myproject '!https://github.com/untrusted/*'
```

## Destination Restrictions

Control where applications can deploy:

### Specific Destinations

```yaml theme={null}
spec:
  destinations:
    - server: https://kubernetes.default.svc
      namespace: dev
    - server: https://kubernetes.default.svc
      namespace: staging
    - server: https://prod-cluster.example.com
      namespace: production
```

### Using Cluster Names

```yaml theme={null}
spec:
  destinations:
    - name: in-cluster
      namespace: '*'
    - name: prod-cluster
      namespace: 'prod-*'
```

### Denying Destinations

```yaml theme={null}
spec:
  destinations:
    # Deny kube-system on all clusters
    - namespace: '!kube-system'
      server: '*'
    # Deny specific cluster pattern
    - namespace: '*'
      server: '!https://team1-*'
    # Allow everything else
    - namespace: '*'
      server: '*'
```

### Managing Destinations via CLI

```bash theme={null}
# Add destination
argocd proj add-destination myproject \
  https://kubernetes.default.svc,mynamespace

# Remove destination
argocd proj remove-destination myproject \
  https://kubernetes.default.svc,mynamespace

# Add denial pattern
argocd proj add-destination myproject '!*,!kube-system'
```

## Resource Restrictions

### Cluster-Scoped Resources (Whitelist)

Only explicitly allowed cluster-scoped resources can be deployed:

```yaml theme={null}
spec:
  clusterResourceWhitelist:
    - group: ''
      kind: Namespace
    - group: 'rbac.authorization.k8s.io'
      kind: ClusterRole
    - group: 'rbac.authorization.k8s.io'
      kind: ClusterRoleBinding
```

#### Restrict by Name

```yaml theme={null}
spec:
  clusterResourceWhitelist:
    # Only allow namespaces starting with team1-
    - group: ''
      kind: Namespace
      name: 'team1-*'
```

### Namespace-Scoped Resources (Blacklist)

All namespace-scoped resources are allowed except those blacklisted:

```yaml theme={null}
spec:
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota
    - group: ''
      kind: LimitRange
    - group: 'networking.k8s.io'
      kind: NetworkPolicy
```

### Managing Resources via CLI

```bash theme={null}
# Allow cluster resource
argocd proj allow-cluster-resource myproject rbac.authorization.k8s.io ClusterRole

# Deny namespace resource
argocd proj deny-namespace-resource myproject "" ResourceQuota

# Deny specific resource by name
argocd proj deny-namespace-resource myproject apps Deployment critical-app
```

## Project Roles and RBAC

Define roles within projects for fine-grained access control:

```yaml theme={null}
spec:
  roles:
    - name: read-only
      description: Read-only access to project applications
      policies:
        - p, proj:myproject:read-only, applications, get, myproject/*, allow
        - p, proj:myproject:read-only, applications, list, myproject/*, allow
      groups:
        - my-oidc-group
        - another-group
    
    - name: ci-pipeline
      description: CI pipeline sync permissions
      policies:
        - p, proj:myproject:ci-pipeline, applications, sync, myproject/*, allow
      # No groups - accessed via JWT tokens
```

<Warning>
  Policy rules must follow the pattern `proj:<project-name>:<role-name>` to be effective during authorization.
</Warning>

### Available Actions

Roles can control access to multiple resource types:

* `applications` - Application resources
* `applicationsets` - ApplicationSet resources
* `repositories` - Repository credentials
* `clusters` - Cluster credentials
* `logs` - Application logs
* `exec` - Exec into pod containers

### Managing Roles via CLI

```bash theme={null}
# Create role
argocd proj role create myproject deployer

# Add policy to role
argocd proj role add-policy myproject deployer \
  --action sync \
  --permission allow \
  --object 'myproject/*'

# List roles
argocd proj role list myproject

# Get role details
argocd proj role get myproject deployer
```

## JWT Tokens for Automation

Generate JWT tokens for programmatic access:

```bash theme={null}
# Create token (with expiration)
argocd proj role create-token myproject ci-pipeline -e 10m

# Create token (no expiration)
argocd proj role create-token myproject ci-pipeline

# List tokens
argocd proj role list myproject

# Revoke token
argocd proj role delete-token myproject ci-pipeline <issued-at-timestamp>
```

### Using JWT Tokens

```bash theme={null}
# Set token as environment variable
export ARGOCD_AUTH_TOKEN=<jwt-token>

# Or use --auth-token flag
argocd app sync myapp --auth-token <jwt-token>
```

## Sync Windows

Define time windows when syncs are allowed or denied:

```yaml theme={null}
spec:
  syncWindows:
    # Deny syncs during business hours
    - kind: deny
      schedule: '0 9-17 * * MON-FRI'
      duration: 8h
      applications:
        - 'prod-*'
      namespaces:
        - production
    
    # Allow syncs during maintenance window
    - kind: allow
      schedule: '0 2 * * SAT'
      duration: 4h
      clusters:
        - prod-cluster
      manualSync: true
```

## Source Namespaces

Restrict which namespaces can contain ApplicationSet resources:

```yaml theme={null}
spec:
  sourceNamespaces:
    - team-apps
    - team-infrastructure
```

## Project-Scoped Repositories and Clusters

Allow developers to add repositories and clusters to projects:

### RBAC Configuration

```yaml theme={null}
# In argocd-rbac-cm ConfigMap
data:
  policy.csv: |
    p, proj:my-project:admin, repositories, create, my-project/*, allow
    p, proj:my-project:admin, repositories, delete, my-project/*, allow
    p, proj:my-project:admin, repositories, update, my-project/*, allow
```

### Adding Project-Scoped Repository

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    argocd repo add https://github.com/myorg/myrepo \
      --project my-project
    ```
  </Tab>

  <Tab title="Declarative">
    ```yaml theme={null}
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-repo
      namespace: argocd
      labels:
        argocd.argoproj.io/secret-type: repository
    type: Opaque
    stringData:
      project: my-project
      url: https://github.com/myorg/myrepo.git
      username: myuser
      password: mytoken
    ```
  </Tab>
</Tabs>

<Warning>
  When using ApplicationSets with templated projects (containing `{{ }}`), only non-scoped repositories can be used.
</Warning>

## Restrict to Project-Scoped Clusters

Force applications to only use clusters belonging to the same project:

```yaml theme={null}
spec:
  permitOnlyProjectScopedClusters: true
```

With this setting, applications can only deploy to clusters that have `project: my-project` in their Secret.

## Global Projects

Define global projects that other projects can inherit from:

```yaml theme={null}
# In argocd-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
data:
  globalProjects: |
    - labelSelector:
        matchExpressions:
          - key: environment
            operator: In
            values:
              - production
      projectName: global-prod-policies
```

Projects matching the label selector inherit:

* namespaceResourceBlacklist
* namespaceResourceWhitelist
* clusterResourceBlacklist
* clusterResourceWhitelist
* syncWindows
* sourceRepos
* destinations

## Destination Service Accounts

Specify service accounts for application deployments:

```yaml theme={null}
spec:
  destinationServiceAccounts:
    - server: https://kubernetes.default.svc
      namespace: 'team-*'
      defaultServiceAccount: team-deployer
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Use descriptive names" icon="tag">
    Name projects after teams or applications for clarity
  </Card>

  <Card title="Principle of least privilege" icon="shield">
    Start restrictive and add permissions as needed
  </Card>

  <Card title="Leverage deny patterns" icon="ban">
    Use `!` patterns to explicitly block dangerous operations
  </Card>

  <Card title="Implement sync windows" icon="clock">
    Use sync windows for production change management
  </Card>

  <Card title="Enable project-scoped repos" icon="code-branch">
    Give teams self-service capabilities with proper RBAC
  </Card>

  <Card title="Use global projects" icon="globe">
    Share common policies across multiple projects
  </Card>
</CardGroup>

<Card title="Related Resources" icon="book">
  * [RBAC Documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/)
  * [Sync Windows](https://argo-cd.readthedocs.io/en/stable/user-guide/sync_windows/)
  * [Project Specification](https://argo-cd.readthedocs.io/en/stable/operator-manual/project-specification/)
</Card>
