ArgoCD ExternalSecret Namespace Permission Error
Problem
ExternalSecrets defined in a shared "external-secrets-resources" ApplicationSet fail to
deploy to namespaces that aren't in the ArgoCD project's allowed destinations. The sync
shows OutOfSync but refuses to apply.
Context / Trigger Conditions
Root Cause
ArgoCD projects define allowed destination namespaces. When ExternalSecrets are deployed
via a centralized "infrastructure" project but target namespaces managed by application-specific
projects, the infrastructure project doesn't have permission to deploy to those namespaces.
Solution
Move the ExternalSecret from the shared external-secrets-resources to the application itself.
Step 1: Create ExternalSecret in the application
# k8s/applications/gorse/base/external-secret.yaml
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: gorse-secrets
namespace: gorse
spec:
refreshInterval: 1h
secretStoreRef:
name: gcp-secret-manager
kind: ClusterSecretStore
target:
name: gorse-secrets
creationPolicy: Owner
data:
- secretKey: api_key
remoteRef:
key: gorse-api-key-ENVIRONMENT
Step 2: Add to application kustomization
# k8s/applications/gorse/base/kustomization.yaml
resources:
- namespace.yaml
- external-secret.yaml # Add here
- deployment.yaml
Step 3: Add environment-specific patches in overlays
# k8s/applications/gorse/overlays/staging/kustomization.yaml
patches:
- target:
kind: ExternalSecret
name: gorse-secrets
patch: |-
- op: replace
path: /spec/data/0/remoteRef/key
value: gorse-api-key-staging
Step 4: Remove from external-secrets-resources
Remove the ExternalSecret from k8s/external-secrets/base/ and all overlay patches.
Verification
- Sync the application:
argocd app sync gorse
- Check ExternalSecret status:
kubectl get externalsecrets -n gorse
- Verify secret created:
kubectl get secrets -n gorse
Alternative Solutions
Option 1: Expand project destinations
Add the namespace to the infrastructure project's allowed destinations in ArgoCD.
Not recommended as it breaks project isolation.
Option 2: Use ClusterSecretStore
If using ClusterSecretStore, the secret can be referenced from any namespace.
The ExternalSecret itself still needs to be in an allowed namespace.
Notes
- This pattern is common when migrating from monolithic to modular ArgoCD setups
- Each application should own its secret definitions for better isolation
- ClusterSecretStore remains shared; only ExternalSecret moves
- The "infrastructure" project typically manages cluster-wide resources, not app-specific secrets