Summary
A missing authorization check in Argo CD PostDelete hooks allows a repository contributor to define deletion-time resources that bypass the Application's AppProject destination and resource restrictions. When the Application is deleted, the application-controller may create those resources with its destination-cluster credentials, potentially reaching forbidden namespaces, resource kinds, or cluster-scoped objects.
A missing authorization check in Argo CD PostDelete hooks allows a repository contributor to define deletion-time resources that bypass the Application's AppProject destination and resource restrictions. When the Application is deleted, the application-controller may create those resources with its destination-cluster credentials, potentially reaching forbidden namespaces, resource kinds, or cluster-scoped objects.
Affected context
The issue affects Argo CD deployments using PostDelete resource hooks in affected 2.10.x through 3.3.x, 3.4.x, 3.5.x, and prerelease 3.6 configurations. The risk exists when an Application's Git repository can be modified by a user who can also cause the Application to be deleted, and when the application-controller has permissions broader than the intended AppProject policy. Other hook phases, including PreSync, Sync, PostSync, and SyncFail, continue to use the ordinary project authorization checks.
The issue affects Argo CD deployments using PostDelete resource hooks in affected 2.10.x through 3.3.x, 3.4.x, 3.5.x, and prerelease 3.6 configurations. The risk exists when an Application's Git repository can be modified by a user who can also cause the Application to be deleted, and when the application-controller has permissions broader than the intended AppProject policy. Other hook phases, including PreSync, Sync, PostSync, and SyncFail, continue to use the ordinary project authorization checks.
Exploit preconditions
- Attack surface: Argo CD Application deletion and PostDelete hook processing
- Required access: Ability to write to the Application's Git repository, plus a way to cause deletion of the associated Application
- Trigger point: Application deletion, when the application-controller processes the committed PostDelete hook
- Required deployment condition: The controller must hold permissions for the targeted destination cluster or resources
- Why exploitation is possible: PostDelete hook creation omits the AppProject destination and resource allow/deny checks applied during ordinary synchronization
- Attack surface: Argo CD Application deletion and PostDelete hook processing
- Required access: Ability to write to the Application's Git repository, plus a way to cause deletion of the associated Application
- Trigger point: Application deletion, when the application-controller processes the committed PostDelete hook
- Required deployment condition: The controller must hold permissions for the targeted destination cluster or resources
- Why exploitation is possible: PostDelete hook creation omits the AppProject destination and resource allow/deny checks applied during ordinary synchronization
Why this happens
The underlying flaw is an authorization enforcement gap in a lifecycle-specific resource creation path. Argo CD applies AppProject restrictions during normal synchronization but does not consistently apply the same destination, namespace, group, kind, and resource-name checks when creating PostDelete hook resources. This behavior maps to CWE-863: Incorrect Authorization, because a request that should be constrained by project policy is accepted without the required authorization decision.
The underlying flaw is an authorization enforcement gap in a lifecycle-specific resource creation path. Argo CD applies AppProject restrictions during normal synchronization but does not consistently apply the same destination, namespace, group, kind, and resource-name checks when creating PostDelete hook resources. This behavior maps to CWE-863: Incorrect Authorization, because a request that should be constrained by project policy is accepted without the required authorization decision.
Potential impact
- An attacker may create resources in namespaces excluded by AppProject policy.
- An attacker may create cluster-scoped or otherwise disallowed resource kinds.
- A hook may persist after the intended Application lifecycle event.
- A hook Job could create secondary resources or perform additional actions using controller-authorized credentials.
- The reachable impact could include cluster compromise, depending on the controller's permissions.
- An attacker may create resources in namespaces excluded by AppProject policy.
- An attacker may create cluster-scoped or otherwise disallowed resource kinds.
- A hook may persist after the intended Application lifecycle event.
- A hook Job could create secondary resources or perform additional actions using controller-authorized credentials.
- The reachable impact could include cluster compromise, depending on the controller's permissions.
General mitigation guidance
Mitigation generally focuses on making authorization checks consistent across every resource lifecycle and hook-processing path.
Common defensive patterns include:
- Applying the same AppProject destination and resource allow/deny checks to PostDelete hooks as to ordinary synchronization.
- Treating repository-authored lifecycle hooks as untrusted configuration.
- Limiting application-controller permissions to the smallest set of clusters, namespaces, and resource types required.
- Restricting who can write to Application repositories and who can delete Applications.
- Using admission policies to independently deny prohibited namespaces, kinds, names, and cluster-scoped resources.
- Reviewing and removing unnecessary hook persistence and secondary-resource creation capabilities.
Mitigation generally focuses on making authorization checks consistent across every resource lifecycle and hook-processing path.
Common defensive patterns include:
- Applying the same AppProject destination and resource allow/deny checks to PostDelete hooks as to ordinary synchronization.
- Treating repository-authored lifecycle hooks as untrusted configuration.
- Limiting application-controller permissions to the smallest set of clusters, namespaces, and resource types required.
- Restricting who can write to Application repositories and who can delete Applications.
- Using admission policies to independently deny prohibited namespaces, kinds, names, and cluster-scoped resources.
- Reviewing and removing unnecessary hook persistence and secondary-resource creation capabilities.
How teams detect issues like this
Detection approaches can include:
- Static analysis and code review for lifecycle handlers that create resources without invoking shared authorization routines.
- Tests that compare authorization behavior across PreSync, Sync, PostSync, SyncFail, and PostDelete hooks.
- Repository scanning for PostDelete hooks targeting restricted namespaces, clusters, groups, kinds, or resource names.
- Audit-log monitoring for resource creation by the application-controller outside the expected AppProject scope.
- Admission-policy enforcement that records or blocks resources violating project or namespace boundaries.
- Automated security review tools that flag authorization checks missing from alternate execution paths.
Detection approaches can include:
- Static analysis and code review for lifecycle handlers that create resources without invoking shared authorization routines.
- Tests that compare authorization behavior across PreSync, Sync, PostSync, SyncFail, and PostDelete hooks.
- Repository scanning for PostDelete hooks targeting restricted namespaces, clusters, groups, kinds, or resource names.
- Audit-log monitoring for resource creation by the application-controller outside the expected AppProject scope.
- Admission-policy enforcement that records or blocks resources violating project or namespace boundaries.
- Automated security review tools that flag authorization checks missing from alternate execution paths.

