Spoke Cluster Deployment¶
Spoke clusters run authenticated frontend access and proxy API traffic to the hub backend.
Pod Composition¶
The spoke frontend deployment contains three containers:
oauth-proxy(:8443) for OpenShift OAuth loginauth-header-injector(:8081) to resolve namespace access into forwarded scope headersfrontend(:8080) nginx SPA with/api/*proxy to hub
Auth Header Injector Behavior¶
- Reads
X-Forwarded-User - Resolves namespace permissions from Kubernetes namespace annotations:
rhacs-manager.io/users(comma-separated usernames)rhacs-manager.io/groups(comma-separated group names)rhacs-manager.io/escalation-email(single escalation contact email for the namespace)- Writes
X-Forwarded-Namespacesasnamespace:clusterpairs or*for wildcard access - Writes
X-Forwarded-Namespace-Emailsasnamespace:cluster=email@company.compairs - Writes
X-Forwarded-Groupsfrom the resolved OpenShift user groups - If the user belongs to a configured
ALL_NAMESPACES_GROUPSgroup, the injector emitsX-Forwarded-Namespaces: *instead of enumerating namespaces
Configuration:
| Variable | Default | Description |
|---|---|---|
CLUSTER_NAME |
required | Name of this spoke cluster |
NAMESPACE_ANNOTATION |
rhacs-manager.io/users |
User annotation key |
GROUP_ANNOTATION |
rhacs-manager.io/groups |
Group annotation key |
EMAIL_ANNOTATION |
rhacs-manager.io/escalation-email |
Namespace escalation contact annotation key |
CACHE_TTL_SECONDS |
300 |
Cache refresh interval |
GROUP_CACHE_TTL_SECONDS |
60 |
Group lookup cache interval |
ALL_NAMESPACES_GROUPS |
"" |
Comma-separated groups that should receive wildcard namespace access |
* namespace access is for users who need fleet-wide visibility without receiving backend sec_team privileges. The hub interprets this as full namespace scope, not as an administrative role change.
Example namespace metadata:
apiVersion: v1
kind: Namespace
metadata:
name: payments
annotations:
rhacs-manager.io/users: "alice,bob"
rhacs-manager.io/groups: "payments-oncall,platform-sec"
rhacs-manager.io/escalation-email: "payments-escalation@example.com"
Spoke Secret¶
Set these values via Helm (or in a values file under spoke.secret.stringData):
| Key | Description |
|---|---|
HUB_API_URL |
Hub backend API URL (e.g. https://rhacs-manager-api.apps.hub.example.com) |
SPOKE_API_KEY |
Must match one entry in hub's SPOKE_API_KEYS |
CLUSTER_NAME |
Name of this spoke cluster |
OAuth Proxy Cookie Secret¶
Generate a random value for spoke.oauthProxy.cookieSecret:
Build and Push Images¶
just build-spoke-image tag=registry.example.com/rhacs-manager-spoke:latest
podman build -t registry.example.com/rhacs-manager-auth-header-injector:latest auth-header-injector/
podman push registry.example.com/rhacs-manager-spoke:latest
podman push registry.example.com/rhacs-manager-auth-header-injector:latest
Deploy¶
helm upgrade --install rhacs-manager-spoke deploy/helm/rhacs-manager \
-n rhacs-manager --create-namespace \
--set mode=spoke \
-f my-spoke-values.yaml
Or render plain YAML:
See examples/helm-values-spoke-minimal.yaml for a minimal values override.