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
24 changes: 16 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,13 @@ ports:
sudo cp /etc/letsencrypt/live/calypr-demo.ddns.net/fullchain.pem /tmp/
sudo cp /etc/letsencrypt/live/calypr-demo.ddns.net/privkey.pem /tmp/
sudo chmod 644 /tmp/fullchain.pem /tmp/privkey.pem
kubectl create secret tls ${TLS_SECRET_NAME} -n default --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n default --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n argocd --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n argo-workflows --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n argo-events --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n argo-stack --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n calypr-api --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
kubectl create secret tls ${TLS_SECRET_NAME} -n calypr-tenants --cert=/tmp/fullchain.pem --key=/tmp/privkey.pem || true
sudo rm /tmp/fullchain.pem /tmp/privkey.pem
# install ingress
helm upgrade --install ingress-authz-overlay \
Expand All @@ -184,14 +190,16 @@ ports:
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
-n ingress-nginx --create-namespace \
--set controller.service.type=NodePort \
--set controller.extraArgs.default-ssl-certificate=default/${TLS_SECRET_NAME}
--set controller.extraArgs.default-ssl-certificate=default/${TLS_SECRET_NAME} \
--set controller.watchIngressWithoutClass=true \
-f helm/argo-stack/overlays/ingress-authz-overlay/values-ingress-nginx.yaml
# Assign external address (only if PUBLIC_IP is set)
@if [ -n "${PUBLIC_IP}" ]; then \
echo "➡️ Assigning external IP: ${PUBLIC_IP}"; \
kubectl patch svc ingress-nginx-controller -n ingress-nginx -p "{\"spec\": {\"type\": \"NodePort\", \"externalIPs\": [\"${PUBLIC_IP}\"]}}"; \
else \
echo "⚠️ PUBLIC_IP not set, skipping external IP assignment"; \
fi
# @if [ -n "${PUBLIC_IP}" ]; then \
# echo "➡️ Assigning external IP: ${PUBLIC_IP}"; \
# kubectl patch svc ingress-nginx-controller -n ingress-nginx -p "{\"spec\": {\"type\": \"NodePort\", \"externalIPs\": [\"${PUBLIC_IP}\"]}}"; \
# else \
# echo "⚠️ PUBLIC_IP not set, skipping external IP assignment"; \
# fi
Comment on lines +197 to +202
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large blocks of commented-out code should be removed rather than committed. If this PUBLIC_IP assignment logic might be needed in the future, document why it was disabled in a comment and consider removing the code block, or explain the rationale for keeping it commented.

Copilot uses AI. Check for mistakes.
# Solution - Use NodePort instead of LoadBalancer in kind
kubectl patch svc ingress-nginx-controller -n ingress-nginx -p '{"spec":{"type":"NodePort","ports":[{"port":80,"nodePort":30080},{"port":443,"nodePort":30443}]}}'

Expand Down
34 changes: 34 additions & 0 deletions helm/argo-stack/overlays/ingress-authz-overlay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,40 @@ ingressAuthzOverlay:
clusterIssuer: letsencrypt-prod
```

### Route Configuration Options

Each route supports the following options:

| Option | Description | Default |
|--------|-------------|---------|
| `enabled` | Enable/disable this route | `true` |
| `namespace` | Namespace where the ingress is created | Required |
| `service` | Backend service name | Required |
| `serviceNamespace` | Namespace of the actual service (for cross-namespace routing) | Same as `namespace` |
| `port` | Backend service port | Required |
| `pathPrefix` | URL path prefix for this route | Required |
| `useRegex` | Enable regex path matching | `false` |
| `rewriteTarget` | Path rewrite target (when `useRegex` is true) | `/$2` |
| `backendProtocol` | Backend protocol (`HTTP`, `HTTPS`, `GRPC`, `GRPCS`) | `HTTP` |
| `proxyConnectTimeout` | NGINX proxy connect timeout | - |
| `proxyReadTimeout` | NGINX proxy read timeout | - |
| `proxySendTimeout` | NGINX proxy send timeout | - |

### Backend Protocol

Some services use HTTPS or gRPC internally. Use the `backendProtocol` option to specify the correct protocol:

```yaml
ingressAuthzOverlay:
routes:
applications:
# ArgoCD server uses HTTPS by default
backendProtocol: HTTPS
grpc-service:
# For gRPC services
backendProtocol: GRPC
```

## Documentation

- [User Guide](docs/authz-ingress-user-guide.md) - Complete installation and configuration guide
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,39 @@ curl -I -H "Authorization: Bearer $TOKEN" https://calypr-demo.ddns.net/workflows

### Common Issues

1. **502 Bad Gateway**: AuthZ adapter not reachable
1. **404 Not Found**: Routes return 404 error
- Check if backend services exist in their respective namespaces:
```bash
# For workflows
kubectl get svc argo-stack-argo-workflows-server -n argo-workflows
# For applications (ArgoCD)
kubectl get svc argo-stack-argocd-server -n argocd
# For registrations
kubectl get svc github-repo-registrations-eventsource-svc -n argo-events
```
- Verify ExternalName proxy services are created for cross-namespace routing:
```bash
kubectl get svc -n argo-stack -l app.kubernetes.io/component=externalname-proxy
Comment on lines +536 to +537
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command only checks for ExternalName services in the argo-stack namespace. However, based on the values.yaml configuration, proxy services are created in the ingress namespace where each route is defined (e.g., argocd, argo-workflows, argo-events). Consider adding a note that ExternalName services are created in each route's namespace, or use -A to check all namespaces: kubectl get svc -A -l app.kubernetes.io/component=externalname-proxy.

Suggested change
```bash
kubectl get svc -n argo-stack -l app.kubernetes.io/component=externalname-proxy
> **Note:** ExternalName proxy services are created in the namespace for each route (e.g., `argocd`, `argo-workflows`, `argo-events`), not just in `argo-stack`.
```bash
kubectl get svc -A -l app.kubernetes.io/component=externalname-proxy

Copilot uses AI. Check for mistakes.
```
- Check if NGINX ingress controller is running and has ADDRESS assigned:
```bash
kubectl get ingress -A -l app.kubernetes.io/name=ingress-authz-overlay
```
- Verify backend protocol settings (ArgoCD requires HTTPS):
```bash
kubectl get ingress ingress-authz-applications -n argo-stack -o yaml | grep backend-protocol
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The namespace in this command is incorrect. Based on the values.yaml changes, the applications ingress is created in the argocd namespace (line 122 of values.yaml), not argo-stack. Update the command to: kubectl get ingress ingress-authz-applications -n argocd -o yaml | grep backend-protocol.

Suggested change
kubectl get ingress ingress-authz-applications -n argo-stack -o yaml | grep backend-protocol
kubectl get ingress ingress-authz-applications -n argocd -o yaml | grep backend-protocol

Copilot uses AI. Check for mistakes.
```
- Check NGINX ingress controller logs for routing errors:
```bash
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller --tail=100
```
- Test direct connectivity to backend services:
```bash
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
curl -v http://argo-stack-argo-workflows-server.argo-workflows:2746/
```

2. **502 Bad Gateway**: AuthZ adapter not reachable
- Check authz-adapter deployment is running
- Verify service selector matches pod labels

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ in its original namespace. This enables NGINX Ingress to route traffic correctly
{{- $root := . }}
{{- $config := .Values.ingressAuthzOverlay }}
{{- range $routeName, $route := $config.routes }}
{{- if $route.enabled }}
{{- $routeEnabled := $route.enabled | default true }}
{{- if $routeEnabled }}
{{- $serviceNamespace := $route.serviceNamespace | default $route.namespace }}
{{- if ne $route.namespace $serviceNamespace }}
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ externalname-services.yaml template.
{{- $root := . }}
{{- $config := .Values.ingressAuthzOverlay }}
{{- range $routeName, $route := $config.routes }}
{{- if $route.enabled }}
{{- $routeEnabled := $route.enabled | default true }}
{{- if $routeEnabled }}
{{- $serviceNamespace := $route.serviceNamespace | default $route.namespace }}
{{- $isCrossNamespace := ne $route.namespace $serviceNamespace }}
{{- $serviceName := ternary (printf "%s-proxy" $route.service) $route.service $isCrossNamespace }}
Expand Down Expand Up @@ -45,6 +46,11 @@ metadata:
# # 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.backendProtocol }}
# Backend protocol for services using HTTPS/GRPC internally
# Valid values: HTTP, HTTPS, GRPC, GRPCS, AJP, FCGI
nginx.ingress.kubernetes.io/backend-protocol: {{ $route.backendProtocol | quote }}
{{- end }}
{{- if $route.useRegex }}
# Path rewriting for subpath support
nginx.ingress.kubernetes.io/use-regex: "true"
Expand All @@ -54,8 +60,17 @@ metadata:
# Cross-namespace routing via ExternalName service
nginx.ingress.kubernetes.io/upstream-vhost: {{ $route.service }}.{{ $serviceNamespace }}.svc.cluster.local
{{- end }}
{{- if $route.proxyConnectTimeout }}
nginx.ingress.kubernetes.io/proxy-connect-timeout: {{ $route.proxyConnectTimeout | quote }}
{{- end }}
{{- if $route.proxyReadTimeout }}
nginx.ingress.kubernetes.io/proxy-read-timeout: {{ $route.proxyReadTimeout | quote }}
{{- end }}
{{- if $route.proxySendTimeout }}
nginx.ingress.kubernetes.io/proxy-send-timeout: {{ $route.proxySendTimeout | quote }}
{{- end }}
spec:
ingressClassName: {{ $config.ingressClassName | default "nginx" | quote }}
ingressClassName: "nginx"
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ingressClassName is now hardcoded to \"nginx\" instead of using the configurable $config.ingressClassName | default \"nginx\". This reduces flexibility and is inconsistent with the values.yaml which defines ingressClassName: nginx. Revert to using the template variable: ingressClassName: {{ $config.ingressClassName | default \"nginx\" | quote }}.

Suggested change
ingressClassName: "nginx"
ingressClassName: {{ $config.ingressClassName | default "nginx" | quote }}

Copilot uses AI. Check for mistakes.
{{- if $config.tls.enabled }}
tls:
- hosts:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
controller:
config:
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enabling snippet annotations with allow-snippet-annotations: true and annotations-risk-level: Critical creates a security risk. Snippet annotations allow arbitrary NGINX configuration code injection and should only be used in trusted environments. Consider documenting this security implication in a comment or the README, and ensure this configuration is intentional for the deployment environment.

Suggested change
config:
config:
# WARNING: Enabling snippet annotations with `allow-snippet-annotations: true` and
# `annotations-risk-level: Critical` allows arbitrary NGINX configuration code injection
# via Ingress annotations. This creates a significant security risk and should ONLY be
# used in trusted environments where Ingress resources are tightly controlled.
# See: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#snippet-annotations

Copilot uses AI. Check for mistakes.
allow-snippet-annotations: "true"
annotations-risk-level: Critical # allow Critical-risk annotations like auth-snippet
9 changes: 6 additions & 3 deletions helm/argo-stack/overlays/ingress-authz-overlay/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# --set ingressAuthzOverlay.enabled=true
# ============================================================================


ingressAuthzOverlay:
# Enable or disable the overlay
enabled: true
Expand Down Expand Up @@ -102,7 +103,7 @@ ingressAuthzOverlay:
# Only the primary route gets the cert-manager.io/cluster-issuer annotation
primary: true
# Namespace where the ingress will be created
namespace: argo-stack
namespace: argo-workflows
# Service name to route to
service: argo-stack-argo-workflows-server
# Namespace where the actual service exists (for cross-namespace routing)
Expand All @@ -118,19 +119,21 @@ ingressAuthzOverlay:
# Argo CD Applications UI
applications:
enabled: true
namespace: argo-stack
namespace: argocd
service: argo-stack-argocd-server
# ArgoCD server is in argocd namespace
serviceNamespace: argocd
port: 8080
pathPrefix: /applications
useRegex: true
rewriteTarget: /$2
# ArgoCD server uses HTTPS by default
backendProtocol: HTTPS

# GitHub Repository Registrations EventSource
registrations:
enabled: true
namespace: argo-stack
namespace: argo-events
service: github-repo-registrations-eventsource-svc
# EventSource is in argo-events namespace
serviceNamespace: argo-events
Expand Down
2 changes: 2 additions & 0 deletions helm/argo-stack/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ ingressAuthzOverlay:
service: argo-stack-argocd-server
port: 8080
pathPrefix: /applications
# ArgoCD server uses HTTPS by default
backendProtocol: HTTPS
registrations:
namespace: argo-stack
service: github-repo-registrations-eventsource-svc
Expand Down