diff --git a/charts/controlplane/dashboards/union-controlplane-overview.json b/charts/controlplane/dashboards/union-controlplane-overview.json index f9d7f9d5..2aab235a 100644 --- a/charts/controlplane/dashboards/union-controlplane-overview.json +++ b/charts/controlplane/dashboards/union-controlplane-overview.json @@ -2784,6 +2784,269 @@ } ], "description": "Percentage of authorization decisions that denied access. Spikes indicate policy changes or auth issues. [Metrics pending: requires cloud service instrumentation to be deployed]" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [ + { + "type": "value", + "options": { + "noop": { "text": "Noop", "index": 0 }, + "userclouds": { "text": "UserClouds", "index": 1 }, + "external": { "text": "External", "index": 2 }, + "authorizer": { "text": "Authorizer", "index": 3 } + } + } + ] + } + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 0, + "y": 23 + }, + "id": 760, + "options": { + "colorMode": "background", + "graphMode": "none", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^type$/" + }, + "textMode": "value" + }, + "title": "Authorizer Mode", + "type": "stat", + "targets": [ + { + "expr": "authorizer:cloudauthorizer:authz_type_info{namespace=\"$namespace\"} == 1", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "description": "Currently active authorizer backend type (Noop, UserClouds, External, Authorizer)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ms" + } + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 4, + "y": 23 + }, + "id": 761, + "title": "External Backend Latency", + "type": "timeseries", + "targets": [ + { + "expr": "histogram_quantile(0.50, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p50", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.95, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p95", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p99", + "refId": "C" + } + ], + "description": "Latency of calls to the external authorization backend (p50/p95/p99)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 23 + }, + "id": 762, + "title": "External Errors by gRPC Code", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (grpc_code) (rate(authorizer:cloudauthorizer:external:errors{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ grpc_code }}", + "refId": "A" + } + ], + "description": "Error rate from the external authorization backend, broken down by gRPC status code." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 23 + }, + "id": 763, + "title": "Fail-Open Activations", + "type": "timeseries", + "targets": [ + { + "expr": "rate(authorizer:cloudauthorizer:external:fail_open_activated{namespace=\"$namespace\"}[$__rate_interval])", + "legendFormat": "Fail-Open", + "refId": "A" + } + ], + "description": "Rate of fail-open activations. Non-zero means the external backend is unreachable and requests are being allowed without authorization." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 764, + "title": "Decisions by Action", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_allowed{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "allowed: {{ action }}", + "refId": "A" + }, + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_denied{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "denied: {{ action }}", + "refId": "B" + } + ], + "description": "Authorization decisions broken down by action (e.g. read, write, execute). Stacked to show total volume." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 765, + "title": "Error Attribution", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (error_source) (rate(authorizer:cloudauthorizer:authorize_errors_total{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ error_source }}", + "refId": "A" + } + ], + "description": "Authorization errors attributed by source (e.g. identity resolution, backend, policy evaluation)." } ] }, diff --git a/charts/controlplane/templates/_helpers.tpl b/charts/controlplane/templates/_helpers.tpl index 6e2ca633..489070b9 100644 --- a/charts/controlplane/templates/_helpers.tpl +++ b/charts/controlplane/templates/_helpers.tpl @@ -361,16 +361,6 @@ IfNotPresent {{- end }} {{- $merged := (include "unionai.deepMerge" (dict "dest" $global "source" $svc) | fromYaml) }} -{{- /* When AUTHZ_TYPE is not "union", fall back to Noop authorizer. */}} -{{- /* Note: union.auth (service-to-service OAuth2 token acquisition) is intentionally NOT */}} -{{- /* disabled here. It controls whether services attach bearer tokens when calling other */}} -{{- /* services through nginx, which is needed in any deployment with auth enabled — */}} -{{- /* regardless of whether Union's RBAC authorizer is active. */}} -{{- if ne .Values.global.AUTHZ_TYPE "union" }} - {{- if hasKey $merged "authorizer" }} - {{- $_ := set $merged "authorizer" (dict "type" "Noop") }} - {{- end }} -{{- end }} {{- $rendered := tpl ($merged | toYaml) . }} {{- $rendered }} {{- end }} diff --git a/charts/controlplane/templates/authz/configmap.yaml b/charts/controlplane/templates/authz/configmap.yaml index 9b2b13fe..37fdda2f 100644 --- a/charts/controlplane/templates/authz/configmap.yaml +++ b/charts/controlplane/templates/authz/configmap.yaml @@ -1,4 +1,4 @@ -{{- if eq .Values.global.AUTHZ_TYPE "union" -}} +{{- if eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds" -}} apiVersion: v1 kind: ConfigMap metadata: diff --git a/charts/controlplane/templates/authz/deployment.yaml b/charts/controlplane/templates/authz/deployment.yaml index 9af5e75f..2513af68 100644 --- a/charts/controlplane/templates/authz/deployment.yaml +++ b/charts/controlplane/templates/authz/deployment.yaml @@ -1,4 +1,4 @@ -{{- if eq .Values.global.AUTHZ_TYPE "union" -}} +{{- if eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds" -}} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/charts/controlplane/templates/authz/hpa.yaml b/charts/controlplane/templates/authz/hpa.yaml index bbe5f7db..9f8de177 100644 --- a/charts/controlplane/templates/authz/hpa.yaml +++ b/charts/controlplane/templates/authz/hpa.yaml @@ -1,4 +1,4 @@ -{{- if and (eq .Values.global.AUTHZ_TYPE "union") .Values.union.authz.autoscaling.enabled }} +{{- if and (eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds") .Values.union.authz.autoscaling.enabled }} apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: diff --git a/charts/controlplane/templates/authz/networkpolicy.yaml b/charts/controlplane/templates/authz/networkpolicy.yaml index 64526758..3105c0c6 100644 --- a/charts/controlplane/templates/authz/networkpolicy.yaml +++ b/charts/controlplane/templates/authz/networkpolicy.yaml @@ -1,4 +1,4 @@ -{{- if and (eq .Values.global.AUTHZ_TYPE "union") .Values.union.authz.networkPolicy.enabled }} +{{- if and (eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds") .Values.union.authz.networkPolicy.enabled }} apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/charts/controlplane/templates/authz/pdb.yaml b/charts/controlplane/templates/authz/pdb.yaml index dfe0fe6b..42e1a421 100644 --- a/charts/controlplane/templates/authz/pdb.yaml +++ b/charts/controlplane/templates/authz/pdb.yaml @@ -1,4 +1,4 @@ -{{- if and (eq .Values.global.AUTHZ_TYPE "union") .Values.union.authz.pdb.enabled }} +{{- if and (eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds") .Values.union.authz.pdb.enabled }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: diff --git a/charts/controlplane/templates/authz/rbac.yaml b/charts/controlplane/templates/authz/rbac.yaml index f0f8b3e4..d681d292 100644 --- a/charts/controlplane/templates/authz/rbac.yaml +++ b/charts/controlplane/templates/authz/rbac.yaml @@ -1,4 +1,4 @@ -{{- if and (eq .Values.global.AUTHZ_TYPE "union") .Values.union.authz.serviceAccount.create -}} +{{- if and (eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds") .Values.union.authz.serviceAccount.create -}} apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: diff --git a/charts/controlplane/templates/authz/service.yaml b/charts/controlplane/templates/authz/service.yaml index 2393fb49..79cfa05f 100644 --- a/charts/controlplane/templates/authz/service.yaml +++ b/charts/controlplane/templates/authz/service.yaml @@ -1,4 +1,4 @@ -{{- if eq .Values.global.AUTHZ_TYPE "union" -}} +{{- if eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds" -}} apiVersion: v1 kind: Service metadata: diff --git a/charts/controlplane/templates/authz/serviceaccount.yaml b/charts/controlplane/templates/authz/serviceaccount.yaml index 3f9cfceb..2b3fab43 100644 --- a/charts/controlplane/templates/authz/serviceaccount.yaml +++ b/charts/controlplane/templates/authz/serviceaccount.yaml @@ -1,4 +1,4 @@ -{{- if and (eq .Values.global.AUTHZ_TYPE "union") .Values.union.authz.serviceAccount.create -}} +{{- if and (eq ((index .Values "services" "authorizer" "configMap" "authorizer" "type") | default "") "UserClouds") .Values.union.authz.serviceAccount.create -}} apiVersion: v1 kind: ServiceAccount metadata: diff --git a/charts/controlplane/templates/monitoring/prometheusrule.yaml b/charts/controlplane/templates/monitoring/prometheusrule.yaml index a6578619..66302a0a 100644 --- a/charts/controlplane/templates/monitoring/prometheusrule.yaml +++ b/charts/controlplane/templates/monitoring/prometheusrule.yaml @@ -45,6 +45,12 @@ spec: expr: | sum(rate(nginx_ingress_controller_request_duration_seconds_count{namespace="{{ .Release.Namespace }}", status=~"5.."}[5m])) + - record: union:cp:authz:external_error_rate + expr: | + sum(rate(authorizer:cloudauthorizer:external:errors{namespace="{{ .Release.Namespace }}"}[5m])) + / + (sum(rate(authorizer:cloudauthorizer:external:authorize_duration_count{namespace="{{ .Release.Namespace }}"}[5m])) > 0 or vector(1)) + {{- if .Values.monitoring.alerting.enabled }} # --- Operational alerts (opt-in) --- # Basic health checks only. For SLO-based alerts, see monitoring.slos. @@ -81,6 +87,40 @@ spec: severity: critical annotations: summary: "Handler panic detected in CP service" + + - alert: UnionCPAuthorizerExternalErrors + expr: | + sum(rate(authorizer:cloudauthorizer:external:errors{namespace="{{ .Release.Namespace }}"}[5m])) > 0.1 + for: 5m + labels: + severity: warning + annotations: + summary: "External authorization backend returning errors" + description: "The external authz backend is returning errors at >0.1/s for 5+ minutes. Check external backend health." + + - alert: UnionCPAuthorizerFailOpenActive + expr: | + sum(rate(authorizer:cloudauthorizer:external:fail_open_activated{namespace="{{ .Release.Namespace }}"}[5m])) > 0 + for: 1m + labels: + severity: critical + annotations: + summary: "Authorizer fail-open mode is actively bypassing authorization" + description: "The external authz backend is unreachable and fail-open is allowing requests without authorization checks." + + - alert: UnionCPAuthorizerHighDenyRate + expr: | + ( + sum(rate(authorizer:cloudauthorizer:authz_denied{namespace="{{ .Release.Namespace }}"}[5m])) + / + (sum(rate(authorizer:cloudauthorizer:authz_allowed{namespace="{{ .Release.Namespace }}"}[5m])) + sum(rate(authorizer:cloudauthorizer:authz_denied{namespace="{{ .Release.Namespace }}"}[5m]))) + ) > 0.5 + for: 10m + labels: + severity: warning + annotations: + summary: "Authorization deny rate exceeds 50%" + description: "More than half of authorization decisions are being denied. Possible policy misconfiguration." {{- end }} {{- if .Values.monitoring.slos.enabled }} diff --git a/charts/controlplane/templates/service.yaml b/charts/controlplane/templates/service.yaml index 300f4ab6..85d62203 100644 --- a/charts/controlplane/templates/service.yaml +++ b/charts/controlplane/templates/service.yaml @@ -19,6 +19,12 @@ spec: port: {{ $svc.grpcport | default 8080 }} protocol: TCP targetPort: {{ if $shared.connectPort }}connect{{ else }}grpc{{ end }} + {{- if $shared.connectPort }} + - name: grpc-native + port: {{ $shared.grpcNativePort | default 8080 }} + protocol: TCP + targetPort: grpc + {{- end }} {{- if $svc.connectport }} - name: connect port: {{ $svc.connectport }} diff --git a/charts/controlplane/values.yaml b/charts/controlplane/values.yaml index c1a56245..24e02989 100644 --- a/charts/controlplane/values.yaml +++ b/charts/controlplane/values.yaml @@ -51,12 +51,6 @@ global: # Contact Union for controlplane access and distribution. IMAGE_REPOSITORY_PREFIX: "643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp" - # Authorization type for RBAC. Set to "union" to enable UserClouds-based authorization. - # Controls union-authz pod deployment and all four authorizer blocks (union services, - # flyteadmin, cacheservice). Leave empty or set to "noop" to disable (default). - # Visible to subcharts (flyte-core) via global scope. - AUTHZ_TYPE: "" - # OAuth2 client ID for service-to-service authentication (client_credentials flow). # Services use this to acquire tokens for internal calls through nginx. # Example: "0oa3xyz4abc5def6g7h8" @@ -251,14 +245,19 @@ ingress: nginx.ingress.kubernetes.io/auth-cache-key: "$http_authorization$http_flyte_authorization$http_cookie" configMap: + # Authorization — all non-authorizer services use TypeAuthorizer to route + # Authorize() calls directly to the in-cluster authorizer service. + # The authorizer service itself decides the backend (Noop, UserClouds, + # or External) — see services.authorizer.configMap below. authorizer: - type: "UserClouds" - userCloudsClient: - tenantUrl: 'http://{{ .Release.Name }}-union-authz.{{ .Release.Namespace }}.svc.cluster.local:8080' - tenantID: '623771e7-ddd6-4575-bedb-7c970ec75b87' - clientID: '{{ .Values.union.authz.clientID }}' - clientSecretName: 'union/client_secret' - enableLogging: true + type: "Authorizer" + authorizerClient: + grpcConfig: + host: 'dns:///authorizer.{{ .Release.Namespace }}.svc.cluster.local:80' + insecure: true + forwardHeaders: + - authorization + - flyte-authorization cache: identity: enabled: false @@ -365,12 +364,41 @@ services: fullnameOverride: "authorizer" sharedService: connectPort: 8081 + grpcNativePort: 8080 args: - authorizer - serve - --config - /etc/config/*.yaml configMap: + # The authorizer service's own backend. All other services route to this + # service via TypeAuthorizer; this config controls what the authorizer + # service does with those requests. + # + # Supported types: + # - "Noop" — no enforcement (default) + # - "UserClouds" — Union Cloud's authorization backend + # - "External" — customer-provided gRPC authorization server (selfhosted) + # + # To enable Union Cloud RBAC, set type to "UserClouds" below. + # The userCloudsClient defaults are pre-configured — just change the type. + # + # To enable external authorization (selfhosted), set type to "External" + # and configure externalClient: + # externalClient: + # grpcConfig: + # host: "dns:///your-authz-server.namespace.svc.cluster.local:50051" + # insecure: true + # # forwardHeaders: ["authorization", "flyte-authorization"] + # # failOpen: false + authorizer: + type: "Noop" + userCloudsClient: + tenantUrl: 'http://{{ .Release.Name }}-union-authz.{{ .Release.Namespace }}.svc.cluster.local:8080' + tenantID: '623771e7-ddd6-4575-bedb-7c970ec75b87' + clientID: '{{ .Values.union.authz.clientID }}' + clientSecretName: 'union/client_secret' + enableLogging: true sharedService: connectPort: 8081 metrics: @@ -1093,22 +1121,24 @@ flyte: admin: endpoint: 'dns:///{{ .Values.global.UNION_HOST }}' insecure: false + # flyteadmin routes authorization to the in-cluster authorizer service. + # For Union Cloud with UserClouds, override with: + # type: "UserClouds" + # userCloudsClient: + # tenantUrl: 'http://{{ .Release.Name }}-union-authz.{{ .Release.Namespace }}.svc.cluster.local:8080' + # tenantID: '623771e7-ddd6-4575-bedb-7c970ec75b87' + # clientID: "union-authz-client" + # clientSecretName: 'union/client_secret' + # enableLogging: true authorizer: - # Type is driven by global.AUTHZ_TYPE: "union" → UserClouds, otherwise Noop. - # The flyte-core subchart evaluates template expressions via tpl, so the global - # flag is visible here even though flyteadmin is rendered by the subchart. - type: '{{ if eq .Values.global.AUTHZ_TYPE "union" }}UserClouds{{ else }}Noop{{ end }}' - internalCommunicationConfig: - enabled: false - userCloudsClient: - tenantUrl: 'http://{{ .Release.Name }}-union-authz.{{ .Release.Namespace }}.svc.cluster.local:8080' - tenantID: '623771e7-ddd6-4575-bedb-7c970ec75b87' - clientID: "union-authz-client" - # flyteadmin: service-shared-secret is mounted at /etc/secrets/union/ via - # additionalVolumes/additionalVolumeMounts above. client_secret resolves to - # /etc/secrets/union/client_secret (same credential used by all union services). - clientSecretName: 'union/client_secret' - enableLogging: true + type: "Authorizer" + authorizerClient: + grpcConfig: + host: 'dns:///authorizer.{{ .Release.Namespace }}.svc.cluster.local:80' + insecure: true + forwardHeaders: + - authorization + - flyte-authorization cloudEvents: enable: false connection: @@ -1151,17 +1181,17 @@ flyte: internalConnectionConfig: enabled: true urlPattern: '{{ printf "_SERVICE_.%s.svc.cluster.local:80" .Release.Namespace }}' + # cacheservice routes authorization to the in-cluster authorizer service. + # For Union Cloud with UserClouds, override with the same pattern as flyteadmin above. authorizer: - # Type is driven by global.AUTHZ_TYPE: "union" → UserClouds, otherwise Noop. - type: '{{ if eq .Values.global.AUTHZ_TYPE "union" }}UserClouds{{ else }}Noop{{ end }}' - internalCommunicationConfig: - enabled: false - userCloudsClient: - tenantUrl: 'http://{{ .Release.Name }}-union-authz.{{ .Release.Namespace }}.svc.cluster.local:8080' - tenantID: '623771e7-ddd6-4575-bedb-7c970ec75b87' - clientID: "union-authz-client" - clientSecretName: 'union/client_secret' - enableLogging: true + type: "Authorizer" + authorizerClient: + grpcConfig: + host: 'dns:///authorizer.{{ .Release.Namespace }}.svc.cluster.local:80' + insecure: true + forwardHeaders: + - authorization + - flyte-authorization cacheservice: storage-prefix: cached_outputs metrics-scope: flyte @@ -1354,9 +1384,8 @@ scylla-operator: # union.authz # ---------------------------------------------------------------------------- # Deploys the union-authz (userclouds-lite) service for RBAC authorization. -# Activation is controlled by global.AUTHZ_TYPE (see global section above). -# Set global.AUTHZ_TYPE: "union" in an env overlay to activate the full RBAC -# stack: union-authz pods, all four authorizer blocks, and service-to-service auth. +# Automatically activated when services.authorizer.configMap.authorizer.type +# is set to "UserClouds". No separate enable flag needed. # Database settings reference the global controlplane DB by default. # Override database.host/name/user/password for a dedicated database. union: diff --git a/tests/generated/controlplane.aws.billing-enable.yaml b/tests/generated/controlplane.aws.billing-enable.yaml index b08823cb..141e0ef3 100644 --- a/tests/generated/controlplane.aws.billing-enable.yaml +++ b/tests/generated/controlplane.aws.billing-enable.yaml @@ -419,15 +419,14 @@ data: - profile - openid authorizer: - internalCommunicationConfig: - enabled: false - type: 'Noop' - userCloudsClient: - clientID: union-authz-client - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cloudEvents: enable: false connection: @@ -547,15 +546,14 @@ data: level: null server.yaml: | authorizer: - internalCommunicationConfig: - enabled: false - type: 'Noop' - userCloudsClient: - clientID: union-authz-client - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache-server: grpcPort: 8089 grpcServerReflection: true @@ -605,7 +603,20 @@ metadata: data: config.yaml: | authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true type: Noop + userCloudsClient: + clientID: 'union-authz-client' + clientSecretName: union/client_secret + enableLogging: true + tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 + tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 cache: identity: enabled: false @@ -653,7 +664,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -716,7 +734,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -767,7 +792,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -837,7 +869,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -894,7 +933,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -951,7 +997,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer billing: enable: true cache: @@ -3900,6 +3953,269 @@ data: } ], "description": "Percentage of authorization decisions that denied access. Spikes indicate policy changes or auth issues. [Metrics pending: requires cloud service instrumentation to be deployed]" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [ + { + "type": "value", + "options": { + "noop": { "text": "Noop", "index": 0 }, + "userclouds": { "text": "UserClouds", "index": 1 }, + "external": { "text": "External", "index": 2 }, + "authorizer": { "text": "Authorizer", "index": 3 } + } + } + ] + } + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 0, + "y": 23 + }, + "id": 760, + "options": { + "colorMode": "background", + "graphMode": "none", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^type$/" + }, + "textMode": "value" + }, + "title": "Authorizer Mode", + "type": "stat", + "targets": [ + { + "expr": "authorizer:cloudauthorizer:authz_type_info{namespace=\"$namespace\"} == 1", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "description": "Currently active authorizer backend type (Noop, UserClouds, External, Authorizer)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ms" + } + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 4, + "y": 23 + }, + "id": 761, + "title": "External Backend Latency", + "type": "timeseries", + "targets": [ + { + "expr": "histogram_quantile(0.50, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p50", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.95, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p95", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p99", + "refId": "C" + } + ], + "description": "Latency of calls to the external authorization backend (p50/p95/p99)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 23 + }, + "id": 762, + "title": "External Errors by gRPC Code", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (grpc_code) (rate(authorizer:cloudauthorizer:external:errors{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ grpc_code }}", + "refId": "A" + } + ], + "description": "Error rate from the external authorization backend, broken down by gRPC status code." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 23 + }, + "id": 763, + "title": "Fail-Open Activations", + "type": "timeseries", + "targets": [ + { + "expr": "rate(authorizer:cloudauthorizer:external:fail_open_activated{namespace=\"$namespace\"}[$__rate_interval])", + "legendFormat": "Fail-Open", + "refId": "A" + } + ], + "description": "Rate of fail-open activations. Non-zero means the external backend is unreachable and requests are being allowed without authorization." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 764, + "title": "Decisions by Action", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_allowed{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "allowed: {{ action }}", + "refId": "A" + }, + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_denied{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "denied: {{ action }}", + "refId": "B" + } + ], + "description": "Authorization decisions broken down by action (e.g. read, write, execute). Stacked to show total volume." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 765, + "title": "Error Attribution", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (error_source) (rate(authorizer:cloudauthorizer:authorize_errors_total{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ error_source }}", + "refId": "A" + } + ], + "description": "Authorization errors attributed by source (e.g. identity resolution, backend, policy evaluation)." } ] }, @@ -5337,6 +5653,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5372,6 +5692,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5547,6 +5871,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5587,7 +5915,7 @@ spec: template: metadata: annotations: - configChecksum: "b509f2650de48d5f4e931d1494a4871db2c0fb3db30ce957593c84712e6db7c" + configChecksum: "dfd6624df8ba9f5d5ca6fd6c5bb8c04f6caaa038a79043a6d545384a00ff261" kubectl.kubernetes.io/default-container: flyteadmin labels: app.kubernetes.io/name: flyteadmin @@ -5966,7 +6294,7 @@ spec: template: metadata: annotations: - configChecksum: "fb5bd9900a4b2f1bed4038dfdbd4184d7a8aac5bb50ba8061d39f2d888dd363" + configChecksum: "4faf73330109ffb030ace3e963be59139b834fc0b88a14740de4f6bbe0f8d84" linkerd.io/inject: disabled prometheus.io/path: /metrics prometheus.io/port: "10254" diff --git a/tests/generated/controlplane.aws.yaml b/tests/generated/controlplane.aws.yaml index 0fbae1f1..00ef2194 100644 --- a/tests/generated/controlplane.aws.yaml +++ b/tests/generated/controlplane.aws.yaml @@ -419,15 +419,14 @@ data: - profile - openid authorizer: - internalCommunicationConfig: - enabled: false - type: 'Noop' - userCloudsClient: - clientID: union-authz-client - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cloudEvents: enable: false connection: @@ -547,15 +546,14 @@ data: level: null server.yaml: | authorizer: - internalCommunicationConfig: - enabled: false - type: 'Noop' - userCloudsClient: - clientID: union-authz-client - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache-server: grpcPort: 8089 grpcServerReflection: true @@ -605,7 +603,20 @@ metadata: data: config.yaml: | authorizer: + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true type: Noop + userCloudsClient: + clientID: 'union-authz-client' + clientSecretName: union/client_secret + enableLogging: true + tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 + tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 cache: identity: enabled: false @@ -653,7 +664,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -716,7 +734,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -767,7 +792,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -837,7 +869,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -894,7 +933,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -951,7 +997,14 @@ metadata: data: config.yaml: | authorizer: - type: Noop + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer billing: enable: false cache: @@ -3900,6 +3953,269 @@ data: } ], "description": "Percentage of authorization decisions that denied access. Spikes indicate policy changes or auth issues. [Metrics pending: requires cloud service instrumentation to be deployed]" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [ + { + "type": "value", + "options": { + "noop": { "text": "Noop", "index": 0 }, + "userclouds": { "text": "UserClouds", "index": 1 }, + "external": { "text": "External", "index": 2 }, + "authorizer": { "text": "Authorizer", "index": 3 } + } + } + ] + } + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 0, + "y": 23 + }, + "id": 760, + "options": { + "colorMode": "background", + "graphMode": "none", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^type$/" + }, + "textMode": "value" + }, + "title": "Authorizer Mode", + "type": "stat", + "targets": [ + { + "expr": "authorizer:cloudauthorizer:authz_type_info{namespace=\"$namespace\"} == 1", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "description": "Currently active authorizer backend type (Noop, UserClouds, External, Authorizer)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ms" + } + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 4, + "y": 23 + }, + "id": 761, + "title": "External Backend Latency", + "type": "timeseries", + "targets": [ + { + "expr": "histogram_quantile(0.50, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p50", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.95, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p95", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p99", + "refId": "C" + } + ], + "description": "Latency of calls to the external authorization backend (p50/p95/p99)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 23 + }, + "id": 762, + "title": "External Errors by gRPC Code", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (grpc_code) (rate(authorizer:cloudauthorizer:external:errors{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ grpc_code }}", + "refId": "A" + } + ], + "description": "Error rate from the external authorization backend, broken down by gRPC status code." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 23 + }, + "id": 763, + "title": "Fail-Open Activations", + "type": "timeseries", + "targets": [ + { + "expr": "rate(authorizer:cloudauthorizer:external:fail_open_activated{namespace=\"$namespace\"}[$__rate_interval])", + "legendFormat": "Fail-Open", + "refId": "A" + } + ], + "description": "Rate of fail-open activations. Non-zero means the external backend is unreachable and requests are being allowed without authorization." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 764, + "title": "Decisions by Action", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_allowed{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "allowed: {{ action }}", + "refId": "A" + }, + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_denied{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "denied: {{ action }}", + "refId": "B" + } + ], + "description": "Authorization decisions broken down by action (e.g. read, write, execute). Stacked to show total volume." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 765, + "title": "Error Attribution", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (error_source) (rate(authorizer:cloudauthorizer:authorize_errors_total{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ error_source }}", + "refId": "A" + } + ], + "description": "Authorization errors attributed by source (e.g. identity resolution, backend, policy evaluation)." } ] }, @@ -5337,6 +5653,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5372,6 +5692,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5547,6 +5871,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5587,7 +5915,7 @@ spec: template: metadata: annotations: - configChecksum: "b509f2650de48d5f4e931d1494a4871db2c0fb3db30ce957593c84712e6db7c" + configChecksum: "dfd6624df8ba9f5d5ca6fd6c5bb8c04f6caaa038a79043a6d545384a00ff261" kubectl.kubernetes.io/default-container: flyteadmin labels: app.kubernetes.io/name: flyteadmin @@ -5966,7 +6294,7 @@ spec: template: metadata: annotations: - configChecksum: "fb5bd9900a4b2f1bed4038dfdbd4184d7a8aac5bb50ba8061d39f2d888dd363" + configChecksum: "4faf73330109ffb030ace3e963be59139b834fc0b88a14740de4f6bbe0f8d84" linkerd.io/inject: disabled prometheus.io/path: /metrics prometheus.io/port: "10254" diff --git a/tests/generated/controlplane.userclouds.yaml b/tests/generated/controlplane.userclouds.yaml index 829904cb..a51a5bb5 100644 --- a/tests/generated/controlplane.userclouds.yaml +++ b/tests/generated/controlplane.userclouds.yaml @@ -31,24 +31,6 @@ spec: app.kubernetes.io/name: webhook-server app.kubernetes.io/instance: webhook-server --- -# Source: controlplane/templates/authz/pdb.yaml -apiVersion: policy/v1 -kind: PodDisruptionBudget -metadata: - name: release-name-union-authz - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -spec: - minAvailable: 2 - selector: - matchLabels: - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name ---- # Source: controlplane/templates/console/pdb.yaml apiVersion: policy/v1 kind: PodDisruptionBudget @@ -222,18 +204,6 @@ metadata: app.kubernetes.io/name: webhook-server app.kubernetes.io/instance: webhook-server --- -# Source: controlplane/templates/authz/serviceaccount.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: release-name-union-authz - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm ---- # Source: controlplane/templates/cacheservice/rbac.yaml apiVersion: v1 kind: ServiceAccount @@ -449,15 +419,14 @@ data: - profile - openid authorizer: - internalCommunicationConfig: - enabled: false - type: 'UserClouds' - userCloudsClient: - clientID: union-authz-client - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cloudEvents: enable: false connection: @@ -551,52 +520,6 @@ data: BASE_URL: /console CONFIG_DIR: /etc/flyte/config --- -# Source: controlplane/templates/authz/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: release-name-union-authz-config - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -data: - config.yaml: | - database: - host: "" - port: 5432 - name: "userclouds" - user: "" - password: "file:///etc/db/pass.txt" - sslMode: "require" - mode: "normal" - - auth: - issuer: "http://release-name-union-authz.union.svc.cluster.local:8080" - signingKey: "kube://secrets/userclouds-signing-key?key=signing_key" - apps: - - credentials: - - clientId: 'union-authz-client' - clientSecret: kube://secrets/?key=client_secret - id: union-controlplane - name: union-controlplane - - cache: - enabled: true - type: "memory" - ttl: "60m" - memory: - maxEntries: 100000 - shards: 128 - depShards: 128 - - services: - checkAttributeEndpoint: "http://localhost:8080" - idpEndpoint: "http://localhost:8080" - authzEndpoint: "http://localhost:8080" ---- # Source: controlplane/templates/cacheservice/configmap.yaml apiVersion: v1 kind: ConfigMap @@ -623,15 +546,14 @@ data: level: null server.yaml: | authorizer: - internalCommunicationConfig: - enabled: false - type: 'UserClouds' - userCloudsClient: - clientID: union-authz-client - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache-server: grpcPort: 8089 grpcServerReflection: true @@ -681,7 +603,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Noop userCloudsClient: clientID: 'union-authz-client' clientSecretName: union/client_secret @@ -735,13 +664,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds - userCloudsClient: - clientID: 'union-authz-client' - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -804,13 +734,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds - userCloudsClient: - clientID: 'union-authz-client' - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -861,13 +792,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds - userCloudsClient: - clientID: 'union-authz-client' - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -937,13 +869,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds - userCloudsClient: - clientID: 'union-authz-client' - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -1000,13 +933,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds - userCloudsClient: - clientID: 'union-authz-client' - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer cache: identity: enabled: false @@ -1063,13 +997,14 @@ metadata: data: config.yaml: | authorizer: - type: UserClouds - userCloudsClient: - clientID: 'union-authz-client' - clientSecretName: union/client_secret - enableLogging: true - tenantID: 623771e7-ddd6-4575-bedb-7c970ec75b87 - tenantUrl: http://release-name-union-authz.union.svc.cluster.local:8080 + authorizerClient: + forwardHeaders: + - authorization + - flyte-authorization + grpcConfig: + host: dns:///authorizer.union.svc.cluster.local:80 + insecure: true + type: Authorizer billing: enable: false cache: @@ -4018,6 +3953,269 @@ data: } ], "description": "Percentage of authorization decisions that denied access. Spikes indicate policy changes or auth issues. [Metrics pending: requires cloud service instrumentation to be deployed]" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "mappings": [ + { + "type": "value", + "options": { + "noop": { "text": "Noop", "index": 0 }, + "userclouds": { "text": "UserClouds", "index": 1 }, + "external": { "text": "External", "index": 2 }, + "authorizer": { "text": "Authorizer", "index": 3 } + } + } + ] + } + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 0, + "y": 23 + }, + "id": 760, + "options": { + "colorMode": "background", + "graphMode": "none", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^type$/" + }, + "textMode": "value" + }, + "title": "Authorizer Mode", + "type": "stat", + "targets": [ + { + "expr": "authorizer:cloudauthorizer:authz_type_info{namespace=\"$namespace\"} == 1", + "legendFormat": "{{ type }}", + "refId": "A" + } + ], + "description": "Currently active authorizer backend type (Noop, UserClouds, External, Authorizer)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ms" + } + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 4, + "y": 23 + }, + "id": 761, + "title": "External Backend Latency", + "type": "timeseries", + "targets": [ + { + "expr": "histogram_quantile(0.50, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p50", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.95, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p95", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum by (le) (rate(authorizer:cloudauthorizer:external:authorize_duration_bucket{namespace=\"$namespace\"}[$__rate_interval])))", + "legendFormat": "p99", + "refId": "C" + } + ], + "description": "Latency of calls to the external authorization backend (p50/p95/p99)." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 23 + }, + "id": 762, + "title": "External Errors by gRPC Code", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (grpc_code) (rate(authorizer:cloudauthorizer:external:errors{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ grpc_code }}", + "refId": "A" + } + ], + "description": "Error rate from the external authorization backend, broken down by gRPC status code." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 23 + }, + "id": 763, + "title": "Fail-Open Activations", + "type": "timeseries", + "targets": [ + { + "expr": "rate(authorizer:cloudauthorizer:external:fail_open_activated{namespace=\"$namespace\"}[$__rate_interval])", + "legendFormat": "Fail-Open", + "refId": "A" + } + ], + "description": "Rate of fail-open activations. Non-zero means the external backend is unreachable and requests are being allowed without authorization." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never", + "stacking": { + "mode": "normal" + } + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 764, + "title": "Decisions by Action", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_allowed{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "allowed: {{ action }}", + "refId": "A" + }, + { + "expr": "sum by (action) (rate(authorizer:cloudauthorizer:authz_denied{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "denied: {{ action }}", + "refId": "B" + } + ], + "description": "Authorization decisions broken down by action (e.g. read, write, execute). Stacked to show total volume." + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "fillOpacity": 10, + "lineWidth": 1, + "showPoints": "never" + }, + "unit": "ops" + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 765, + "title": "Error Attribution", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (error_source) (rate(authorizer:cloudauthorizer:authorize_errors_total{namespace=\"$namespace\"}[$__rate_interval]))", + "legendFormat": "{{ error_source }}", + "refId": "A" + } + ], + "description": "Authorization errors attributed by source (e.g. identity resolution, backend, policy evaluation)." } ] }, @@ -5250,22 +5448,6 @@ subjects: name: scylla-operator namespace: scylla-operator --- -# Source: controlplane/templates/authz/rbac.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: release-name-union-authz-secrets-manager - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -rules: - - apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list", "watch", "create", "update", "delete"] ---- # Source: controlplane/templates/flyte-core-app.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -5297,26 +5479,6 @@ rules: verbs: - '*' --- -# Source: controlplane/templates/authz/rbac.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: release-name-union-authz-secrets-manager - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: release-name-union-authz-secrets-manager -subjects: - - kind: ServiceAccount - name: release-name-union-authz - namespace: union ---- # Source: controlplane/templates/flyte-core-app.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding @@ -5414,28 +5576,6 @@ spec: app.kubernetes.io/name: webhook-server app.kubernetes.io/instance: webhook-server --- -# Source: controlplane/templates/authz/service.yaml -apiVersion: v1 -kind: Service -metadata: - name: release-name-union-authz - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -spec: - type: ClusterIP - ports: - - port: 8080 - targetPort: http - protocol: TCP - name: http - selector: - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name ---- # Source: controlplane/templates/cacheservice/service.yaml apiVersion: v1 kind: Service @@ -5513,6 +5653,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5548,6 +5692,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5723,6 +5871,10 @@ spec: port: 80 protocol: TCP targetPort: connect + - name: grpc-native + port: 8080 + protocol: TCP + targetPort: grpc - name: connect port: 83 protocol: TCP @@ -5763,7 +5915,7 @@ spec: template: metadata: annotations: - configChecksum: "4150b5c1afad3c32533edd9d6effda17a60a694dbb986cce396960d517fda47" + configChecksum: "dfd6624df8ba9f5d5ca6fd6c5bb8c04f6caaa038a79043a6d545384a00ff261" kubectl.kubernetes.io/default-container: flyteadmin labels: app.kubernetes.io/name: flyteadmin @@ -6122,119 +6274,6 @@ spec: topologyKey: kubernetes.io/hostname weight: 1 --- -# Source: controlplane/templates/authz/deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: release-name-union-authz - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -spec: - strategy: - rollingUpdate: - maxSurge: 1 - maxUnavailable: 0 - type: RollingUpdate - selector: - matchLabels: - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - template: - metadata: - annotations: - checksum/config: af438a6ec6210e9b743a843f136d5cc25d942a7f66b308a24068b4b3bbe7f425 - linkerd.io/inject: disabled - prometheus.io/path: /metrics - prometheus.io/port: "10254" - labels: - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - spec: - serviceAccountName: release-name-union-authz - terminationGracePeriodSeconds: 45 - securityContext: - fsGroup: 1000 - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - containers: - - name: userclouds-lite - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - image: 643379628101.dkr.ecr.us-east-1.amazonaws.com/union-cp/services:2026.3.7 - imagePullPolicy: IfNotPresent - command: - - userclouds-lite - args: - - serve - - all - - --config=/etc/userclouds/config.yaml - - --addr=:8080 - - --static=/usr/share/userclouds/static - ports: - - name: http - containerPort: 8080 - protocol: TCP - livenessProbe: - httpGet: - path: /healthz - port: http - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 3 - readinessProbe: - httpGet: - path: /readyz - port: http - initialDelaySeconds: 5 - periodSeconds: 5 - timeoutSeconds: 3 - failureThreshold: 3 - resources: - limits: - cpu: "1" - memory: 512Mi - requests: - cpu: 250m - memory: 256Mi - lifecycle: - preStop: - exec: - command: ["sleep", "5"] - volumeMounts: - - name: config - mountPath: /etc/userclouds - readOnly: true - - name: db-pass - mountPath: /etc/db - - name: tmp - mountPath: /tmp - volumes: - - name: config - configMap: - name: release-name-union-authz-config - - name: db-pass - secret: - secretName: - - name: tmp - emptyDir: {} - affinity: - podAntiAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app.kubernetes.io/name: union-authz - topologyKey: kubernetes.io/hostname ---- # Source: controlplane/templates/cacheservice/deployment.yaml apiVersion: apps/v1 kind: Deployment @@ -6255,7 +6294,7 @@ spec: template: metadata: annotations: - configChecksum: "51558f4520a9d7ed5a0ad0f0dcad38250772b05e41f793c421be04bce90149e" + configChecksum: "4faf73330109ffb030ace3e963be59139b834fc0b88a14740de4f6bbe0f8d84" linkerd.io/inject: disabled prometheus.io/path: /metrics prometheus.io/port: "10254" @@ -7284,32 +7323,6 @@ spec: type: Utilization type: Resource --- -# Source: controlplane/templates/authz/hpa.yaml -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: release-name-union-authz - labels: - helm.sh/chart: controlplane-2026.3.10 - app.kubernetes.io/name: union-authz - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "2026.3.7" - app.kubernetes.io/managed-by: Helm -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: release-name-union-authz - minReplicas: 3 - maxReplicas: 10 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 ---- # Source: controlplane/templates/console/hpa.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler