diff --git a/config/configStruct.go b/config/configStruct.go
index c587eb6c8..e5640c200 100644
--- a/config/configStruct.go
+++ b/config/configStruct.go
@@ -102,23 +102,21 @@ func CreateDefaultConfig() ConfigStruct {
},
},
Auth: configStructs.AuthConfig{
- Saml: configStructs.SamlConfig{
- RoleAttribute: "role",
- Roles: map[string]configStructs.Role{
- "admin": {
- Filter: "",
- CanDownloadPCAP: true,
- CanUseScripting: true,
- ScriptingPermissions: configStructs.ScriptingPermissions{
- CanSave: true,
- CanActivate: true,
- CanDelete: true,
- },
- CanUpdateTargetedPods: true,
- CanStopTrafficCapturing: true,
- CanControlDissection: true,
- ShowAdminConsoleLink: true,
+ RolesClaim: "role",
+ Roles: map[string]configStructs.Role{
+ "admin": {
+ Filter: "",
+ CanDownloadPCAP: true,
+ CanUseScripting: true,
+ ScriptingPermissions: configStructs.ScriptingPermissions{
+ CanSave: true,
+ CanActivate: true,
+ CanDelete: true,
},
+ CanUpdateTargetedPods: true,
+ CanStopTrafficCapturing: true,
+ CanControlDissection: true,
+ ShowAdminConsoleLink: true,
},
},
},
diff --git a/config/configStructs/tapConfig.go b/config/configStructs/tapConfig.go
index 6cd8164bf..fcd6cca46 100644
--- a/config/configStructs/tapConfig.go
+++ b/config/configStructs/tapConfig.go
@@ -173,17 +173,29 @@ type Role struct {
}
type SamlConfig struct {
- IdpMetadataUrl string `yaml:"idpMetadataUrl" json:"idpMetadataUrl"`
- X509crt string `yaml:"x509crt" json:"x509crt"`
- X509key string `yaml:"x509key" json:"x509key"`
- RoleAttribute string `yaml:"roleAttribute" json:"roleAttribute"`
- Roles map[string]Role `yaml:"roles" json:"roles"`
+ IdpMetadataUrl string `yaml:"idpMetadataUrl" json:"idpMetadataUrl"`
+ X509crt string `yaml:"x509crt" json:"x509crt"`
+ X509key string `yaml:"x509key" json:"x509key"`
}
type AuthConfig struct {
- Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
- Type string `yaml:"type" json:"type" default:"saml"`
- Saml SamlConfig `yaml:"saml" json:"saml"`
+ Enabled bool `yaml:"enabled" json:"enabled" default:"false"`
+ // Type selects the authentication backend. Valid values:
+ // saml — SAML 2.0 SSO
+ // oidc — generic OIDC (Dex, Okta, Auth0, Keycloak, Azure AD, …)
+ // dex — permanent alias of oidc (kept for back-compat)
+ // descope — Descope SDK
+ // default — also routes to Descope (kept, not deprecated)
+ //
+ // NOTE: prior releases routed `oidc` to Descope. If you were using `oidc`
+ // to mean Descope, switch to `descope` (or `default`). The rename is a
+ // breaking change documented in the release notes.
+ Type string `yaml:"type" json:"type" default:"saml"`
+ Roles map[string]Role `yaml:"roles" json:"roles"`
+ RolesClaim string `yaml:"rolesClaim" json:"rolesClaim"`
+ DefaultRole string `yaml:"defaultRole" json:"defaultRole"`
+ DefaultFilter string `yaml:"defaultFilter" json:"defaultFilter"`
+ Saml SamlConfig `yaml:"saml" json:"saml"`
}
type IngressConfig struct {
diff --git a/helm-chart/README.md b/helm-chart/README.md
index 1c03373c6..ba6636d59 100644
--- a/helm-chart/README.md
+++ b/helm-chart/README.md
@@ -212,14 +212,15 @@ Example for overriding image names:
| `tap.tolerations.hub` | Tolerations for hub component | `[]` |
| `tap.tolerations.front` | Tolerations for front-end component | `[]` |
| `tap.auth.enabled` | Enable authentication | `false` |
-| `tap.auth.type` | Authentication type (1 option available: `saml`) | `saml` |
+| `tap.auth.type` | Authentication backend. Valid values: `saml`, `oidc` (generic OIDC — Dex, Okta, Auth0, Keycloak, Azure AD, Google, …), `dex` (permanent alias of `oidc`), `descope`, `default` (also routes to Descope). **Breaking**: prior releases routed `oidc` to Descope — if you were using it for Descope, switch to `descope` or `default`. | `saml` |
| `tap.auth.approvedEmails` | List of approved email addresses for authentication | `[]` |
| `tap.auth.approvedDomains` | List of approved email domains for authentication | `[]` |
-| `tap.auth.saml.idpMetadataUrl` | SAML IDP metadata URL
(effective, if `tap.auth.type = saml`) | `` |
+| `tap.auth.rolesClaim` | Name of the JWT claim (OIDC) or SAML attribute carrying role memberships. | `role` |
+| `tap.auth.defaultRole` | Optional role name inside `tap.auth.roles` applied as fallback when an authenticated user has no matching role. Empty string = no fallback, zero-valued permissions. | `""` |
+| `tap.auth.roles` | Backend-neutral role map shared by SAML and OIDC. Each role's `namespaces` is a comma-separated list controlling which Kubernetes namespaces the role's users see traffic for: `""` = deny all, `"*"` = allow all, `"foo"` = literal namespace, `"foo,bar"` = OR over literals, `"foo-*"` = glob expansion against the cluster's known namespaces. Empty/unset `tap.auth.roles` grants nothing — admins opt into elevated access by populating this map. | `{"admin":{"namespaces":"*","canDownloadPCAP":true,"canUpdateTargetedPods":true,"canUseScripting":true,"scriptingPermissions":{"canSave":true,"canActivate":true,"canDelete":true},"canStopTrafficCapturing":true,"canControlDissection":true,"showAdminConsoleLink":true}}` |
+| `tap.auth.saml.idpMetadataUrl` | SAML IDP metadata URL
(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509crt` | A self-signed X.509 `.cert` contents
(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509key` | A self-signed X.509 `.key` contents
(effective, if `tap.auth.type = saml`) | `` |
-| `tap.auth.saml.roleAttribute` | A SAML attribute name corresponding to user's authorization role
(effective, if `tap.auth.type = saml`) | `role` |
-| `tap.auth.saml.roles` | A list of SAML authorization roles and their permissions
(effective, if `tap.auth.type = saml`) | `{"admin":{"canDownloadPCAP":true,"canUpdateTargetedPods":true,"canUseScripting":true, "scriptingPermissions":{"canSave":true, "canActivate":true, "canDelete":true}, "canStopTrafficCapturing":true, "canControlDissection":true, "filter":"","showAdminConsoleLink":true}}` |
| `tap.ingress.enabled` | Enable `Ingress` | `false` |
| `tap.ingress.className` | Ingress class name | `""` |
| `tap.ingress.host` | Host of the `Ingress` | `ks.svc.cluster.local` |
@@ -377,8 +378,8 @@ Add these helm values to set up OIDC authentication powered by your Dex IdP:
tap:
auth:
enabled: true
- type: dex
- dexOidc:
+ type: oidc # canonical; `dex` is accepted as a permanent alias
+ oidc:
issuer:
clientId: kubeshark
clientSecret: create your own client password
@@ -390,7 +391,7 @@ tap:
---
**Note:**
-Set `tap.auth.dexOidc.bypassSslCaCheck: true`
+Set `tap.auth.oidc.bypassSslCaCheck: true`
to allow Kubeshark communication with Dex IdP having an unknown SSL Certificate Authority.
This setting allows you to prevent such SSL CA-related errors:
@@ -429,7 +430,7 @@ The following Dex settings will have these values:
| Setting | Value |
|-------------------------------------------------------|----------------------------------------------|
-| `tap.auth.dexOidc.issuer` | `https://ks.example.com/dex` |
+| `tap.auth.oidc.issuer` | `https://ks.example.com/dex` |
| `tap.auth.dexConfig.issuer` | `https://ks.example.com/dex` |
| `tap.auth.dexConfig.staticClients -> redirectURIs` | `https://ks.example.com/api/oauth2/callback` |
| `tap.auth.dexConfig.connectors -> config.redirectURI` | `https://ks.example.com/dex/callback` |
@@ -447,16 +448,16 @@ Please, make sure to prepare the following things first.
- You will need to specify storage settings in `tap.auth.dexConfig.storage`
- default: `memory`
3. Decide on the OAuth2 `?state=` param expiration time:
- - field: `tap.auth.dexOidc.oauth2StateParamExpiry`
+ - field: `tap.auth.oidc.oauth2StateParamExpiry`
- default: `10m` (10 minutes)
- valid time units are `s`, `m`, `h`
4. Decide on the refresh token expiration:
- - field 1: `tap.auth.dexOidc.expiry.refreshTokenLifetime`
+ - field 1: `tap.auth.oidc.expiry.refreshTokenLifetime`
- field 2: `tap.auth.dexConfig.expiry.refreshTokens.absoluteLifetime`
- default: `3960h` (165 days)
- valid time units are `s`, `m`, `h`
5. Create a unique & secure password to set in these fields:
- - field 1: `tap.auth.dexOidc.clientSecret`
+ - field 1: `tap.auth.oidc.clientSecret`
- field 2: `tap.auth.dexConfig.staticClients -> secret`
- password must be the same for these 2 fields
6. Discover more possibilities of **[Dex Configuration](https://dexidp.io/docs/configuration/)**
@@ -478,8 +479,8 @@ Helm `values.yaml`:
tap:
auth:
enabled: true
- type: dex
- dexOidc:
+ type: oidc # canonical; `dex` is accepted as a permanent alias
+ oidc:
issuer: https:///dex
# Client ID/secret must be taken from `tap.auth.dexConfig.staticClients -> id/secret`
diff --git a/helm-chart/templates/06-front-deployment.yaml b/helm-chart/templates/06-front-deployment.yaml
index ab30f22a6..9d94ca7cf 100644
--- a/helm-chart/templates/06-front-deployment.yaml
+++ b/helm-chart/templates/06-front-deployment.yaml
@@ -26,12 +26,12 @@ spec:
- env:
- name: REACT_APP_AUTH_ENABLED
value: '{{- if or (and .Values.cloudLicenseEnabled (not (empty .Values.license))) (not .Values.internetConnectivity) -}}
- {{ (default false .Values.demoModeEnabled) | ternary true ((and .Values.tap.auth.enabled (eq .Values.tap.auth.type "dex")) | ternary true false) }}
+ {{ (default false .Values.demoModeEnabled) | ternary true ((and .Values.tap.auth.enabled (or (eq .Values.tap.auth.type "oidc") (eq .Values.tap.auth.type "dex"))) | ternary true false) }}
{{- else -}}
{{ .Values.cloudLicenseEnabled | ternary "true" ((default false .Values.demoModeEnabled) | ternary "true" .Values.tap.auth.enabled) }}
{{- end }}'
- name: REACT_APP_AUTH_TYPE
- value: '{{- if and .Values.cloudLicenseEnabled (not (eq .Values.tap.auth.type "dex")) -}}
+ value: '{{- if and .Values.cloudLicenseEnabled (not (or (eq .Values.tap.auth.type "oidc") (eq .Values.tap.auth.type "dex"))) -}}
default
{{- else -}}
{{ (default false .Values.demoModeEnabled) | ternary "default" .Values.tap.auth.type }}
diff --git a/helm-chart/templates/12-config-map.yaml b/helm-chart/templates/12-config-map.yaml
index bdb40f90b..dc7f15641 100644
--- a/helm-chart/templates/12-config-map.yaml
+++ b/helm-chart/templates/12-config-map.yaml
@@ -19,27 +19,28 @@ data:
INGRESS_HOST: '{{ .Values.tap.ingress.host }}'
PROXY_FRONT_PORT: '{{ .Values.tap.proxy.front.port }}'
AUTH_ENABLED: '{{- if and .Values.cloudLicenseEnabled (not (empty .Values.license)) -}}
- {{ (default false .Values.demoModeEnabled) | ternary true ((and .Values.tap.auth.enabled (eq .Values.tap.auth.type "dex")) | ternary true false) }}
+ {{ (default false .Values.demoModeEnabled) | ternary true ((and .Values.tap.auth.enabled (or (eq .Values.tap.auth.type "oidc") (eq .Values.tap.auth.type "dex"))) | ternary true false) }}
{{- else -}}
{{ .Values.cloudLicenseEnabled | ternary "true" ((default false .Values.demoModeEnabled) | ternary "true" .Values.tap.auth.enabled) }}
{{- end }}'
- AUTH_TYPE: '{{- if and .Values.cloudLicenseEnabled (not (eq .Values.tap.auth.type "dex")) -}}
+ AUTH_TYPE: '{{- if and .Values.cloudLicenseEnabled (not (or (eq .Values.tap.auth.type "oidc") (eq .Values.tap.auth.type "dex"))) -}}
default
{{- else -}}
{{ (default false .Values.demoModeEnabled) | ternary "default" .Values.tap.auth.type }}
{{- end }}'
AUTH_SAML_IDP_METADATA_URL: '{{ .Values.tap.auth.saml.idpMetadataUrl }}'
- AUTH_SAML_ROLE_ATTRIBUTE: '{{ .Values.tap.auth.saml.roleAttribute }}'
- AUTH_SAML_ROLES: '{{ .Values.tap.auth.saml.roles | toJson }}'
- AUTH_OIDC_ISSUER: '{{ default "not set" (((.Values.tap).auth).dexOidc).issuer }}'
- AUTH_OIDC_REFRESH_TOKEN_LIFETIME: '{{ default "3960h" (((.Values.tap).auth).dexOidc).refreshTokenLifetime }}'
- AUTH_OIDC_STATE_PARAM_EXPIRY: '{{ default "10m" (((.Values.tap).auth).dexOidc).oauth2StateParamExpiry }}'
+ AUTH_ROLES: '{{ .Values.tap.auth.roles | toJson }}'
+ AUTH_ROLES_CLAIM: '{{ .Values.tap.auth.rolesClaim }}'
+ AUTH_DEFAULT_ROLE: '{{ default "" .Values.tap.auth.defaultRole }}'
+ AUTH_OIDC_ISSUER: '{{ default "not set" (((.Values.tap).auth).oidc).issuer }}'
+ AUTH_OIDC_REFRESH_TOKEN_LIFETIME: '{{ default "3960h" (((.Values.tap).auth).oidc).refreshTokenLifetime }}'
+ AUTH_OIDC_STATE_PARAM_EXPIRY: '{{ default "10m" (((.Values.tap).auth).oidc).oauth2StateParamExpiry }}'
AUTH_OIDC_BYPASS_SSL_CA_CHECK: '{{- if and
(hasKey .Values.tap "auth")
- (hasKey .Values.tap.auth "dexOidc")
- (hasKey .Values.tap.auth.dexOidc "bypassSslCaCheck")
+ (hasKey .Values.tap.auth "oidc")
+ (hasKey .Values.tap.auth.oidc "bypassSslCaCheck")
-}}
- {{ eq .Values.tap.auth.dexOidc.bypassSslCaCheck true | ternary "true" "false" }}
+ {{ eq .Values.tap.auth.oidc.bypassSslCaCheck true | ternary "true" "false" }}
{{- else -}}
false
{{- end }}'
diff --git a/helm-chart/templates/13-secret.yaml b/helm-chart/templates/13-secret.yaml
index cf6f92c15..059732fd0 100644
--- a/helm-chart/templates/13-secret.yaml
+++ b/helm-chart/templates/13-secret.yaml
@@ -9,8 +9,8 @@ metadata:
stringData:
LICENSE: '{{ .Values.license }}'
SCRIPTING_ENV: '{{ .Values.scripting.env | toJson }}'
- OIDC_CLIENT_ID: '{{ default "not set" (((.Values.tap).auth).dexOidc).clientId }}'
- OIDC_CLIENT_SECRET: '{{ default "not set" (((.Values.tap).auth).dexOidc).clientSecret }}'
+ OIDC_CLIENT_ID: '{{ default "not set" (((.Values.tap).auth).oidc).clientId }}'
+ OIDC_CLIENT_SECRET: '{{ default "not set" (((.Values.tap).auth).oidc).clientSecret }}'
---
diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml
index 302bafc2b..9fe77e5f5 100644
--- a/helm-chart/values.yaml
+++ b/helm-chart/values.yaml
@@ -152,25 +152,44 @@ tap:
front: []
auth:
enabled: false
+ # Valid values: saml, oidc (generic OIDC — Dex, Okta, Auth0, Keycloak,
+ # Azure AD, Google, …), dex (permanent alias of oidc), descope, default
+ # (also Descope). Was previously misnamed: prior releases routed `oidc`
+ # to Descope. See release notes for migration.
type: saml
+ # Name of the JWT claim (OIDC) or SAML attribute carrying role memberships.
+ rolesClaim: role
+ # Optional: role name inside `roles` applied as a fallback when an
+ # authenticated user has no matching role in their token/assertion.
+ # Empty string means no fallback (authenticated but no elevated permissions).
+ defaultRole: ""
+ # Backend-neutral role map shared by SAML and OIDC. Empty/unset grants
+ # nothing — admins opt into elevated access by populating this map.
+ #
+ # Per-role `namespaces` controls which Kubernetes namespaces the role's
+ # users are allowed to see traffic for. Comma-separated list:
+ # "" — deny all (explicit deny-default for this role).
+ # "*" — allow every namespace (no scope filter applied).
+ # "foo" — only the literal namespace "foo" (src or dst).
+ # "foo,bar" — OR over both literal namespaces.
+ # "foo-*" — glob expansion against the cluster's known namespaces.
+ roles:
+ admin:
+ namespaces: "*"
+ canDownloadPCAP: true
+ canUseScripting: true
+ scriptingPermissions:
+ canSave: true
+ canActivate: true
+ canDelete: true
+ canUpdateTargetedPods: true
+ canStopTrafficCapturing: true
+ canControlDissection: true
+ showAdminConsoleLink: true
saml:
idpMetadataUrl: ""
x509crt: ""
x509key: ""
- roleAttribute: role
- roles:
- admin:
- filter: ""
- canDownloadPCAP: true
- canUseScripting: true
- scriptingPermissions:
- canSave: true
- canActivate: true
- canDelete: true
- canUpdateTargetedPods: true
- canStopTrafficCapturing: true
- canControlDissection: true
- showAdminConsoleLink: true
ingress:
enabled: false
className: ""