Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions helm/argo-stack/overlays/ingress-authz-overlay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,27 @@ See the [User Guide](docs/authz-ingress-user-guide.md) for architecture diagrams
- NGINX Ingress Controller
- cert-manager (for TLS) - **must be installed before deploying this overlay**

### TLS Certificate Ownership

When using cert-manager's ingress-shim, only **one** ingress resource can "own" a Certificate.
This overlay uses a `primary: true` flag on routes to designate which ingress should have the
`cert-manager.io/cluster-issuer` annotation.

By default, the `workflows` route is set as primary. Other ingresses reference the same TLS
secret but without the cluster-issuer annotation, avoiding the "certificate resource is not
owned by this object" error.

To change the primary route:

```yaml
ingressAuthzOverlay:
routes:
workflows:
primary: false # Remove primary from workflows
applications:
primary: true # Make applications the primary
```

### Installing cert-manager

If you see `no matches for kind "ClusterIssuer"`, cert-manager is not installed:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,41 @@ Common issues:
- **ACME Registration Failed**: Check your email address is valid and you can reach Let's Encrypt's API
- **Secret Not Found in Expected Namespace**: The secret is created in the cert-manager namespace, not your application namespace

### TLS Certificate Ownership

When using multiple ingress resources with the same TLS secret and cert-manager's ingress-shim, you may encounter an error:

```
certificate resource is not owned by this object. refusing to update non-owned certificate resource
```

This happens because **cert-manager only allows one Ingress to own a Certificate**. When multiple ingresses have the `cert-manager.io/cluster-issuer` annotation pointing to the same certificate, a conflict occurs.

**Solution**: This overlay uses a `primary: true` flag on routes. Only the primary route's Ingress gets the `cert-manager.io/cluster-issuer` annotation. Other ingresses reference the TLS secret but don't trigger certificate creation.

```yaml
ingressAuthzOverlay:
routes:
workflows:
enabled: true
primary: true # Only this route has cert-manager.io/cluster-issuer annotation
# ...
applications:
enabled: true
# primary: false (default) - uses the TLS secret but doesn't trigger cert creation
```

By default, the `workflows` route is primary. To change:

```yaml
ingressAuthzOverlay:
routes:
workflows:
primary: false
api:
primary: true # Move certificate ownership to /api route
```

### Configuration Options

| Setting | Description | Default |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Ingress resources for each route in the ingress-authz-overlay.
Each route creates a separate Ingress resource in its respective namespace,
all sharing the same host and TLS configuration.
All routes are protected by the authz-adapter via NGINX external auth.

NOTE: Only the route with primary: true should have the cert-manager.io/cluster-issuer
annotation. Other routes just reference the TLS secret without the annotation to avoid
cert-manager ownership conflicts. If no route has primary: true, no ingress will have
the cluster-issuer annotation (the Certificate must be created manually or by another means).
*/}}
{{- if .Values.ingressAuthzOverlay.enabled }}
{{- $root := . }}
Expand All @@ -25,8 +30,8 @@ metadata:
meta.helm.sh/release-namespace: {{ $root.Release.Namespace }}
# NGINX external auth annotations
{{- include "ingress-authz-overlay.authAnnotations" $root | nindent 4 }}
{{- if $config.tls.enabled }}
# Let's Encrypt / cert-manager integration
{{- if and $config.tls.enabled $route.primary }}
# Let's Encrypt / cert-manager integration (only on primary route to avoid ownership conflicts)
cert-manager.io/cluster-issuer: {{ $config.tls.clusterIssuer | quote }}
{{- end }}
{{- if $route.useRegex }}
Expand Down
9 changes: 8 additions & 1 deletion helm/argo-stack/overlays/ingress-authz-overlay/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,17 @@ ingressAuthzOverlay:
# Each route creates a separate Ingress resource in the specified namespace.
# All routes share the same host and TLS configuration.
# All routes are protected by the authz-adapter via NGINX external auth.
#
# IMPORTANT: Only ONE route should have the cert-manager.io/cluster-issuer annotation
# to avoid "certificate resource is not owned by this object" errors.
# Set `primary: true` on exactly one route to designate it as the certificate owner.
routes:
# Argo Workflows UI
# Argo Workflows UI (primary route - manages TLS certificate)
workflows:
enabled: true
# Set primary: true to designate this route as the certificate owner
# Only the primary route gets the cert-manager.io/cluster-issuer annotation
primary: true
namespace: argo-stack
service: argo-stack-argo-workflows-server
port: 2746
Expand Down