auth: add tap.auth.roles operator-defined role catalogue

Chart-side companion to hub commit 67162b2e (Phase C of the permissions
refactor). Operators can now declare named roles with their own
capability set + namespace scope under tap.auth.roles; the
12-config-map renders these as AUTH_ROLES JSON for the hub to consume.

  - config/configStructs: AuthConfig.Roles map[string]RoleConfig with
    Capabilities + Namespaces; doc comments updated for groupMapping +
    defaultRole to reflect that user-defined names are now accepted.
  - config/configStruct.go: zero-value initializer for Roles so
    `kubeshark config` renders `roles: {}` consistently.
  - helm-chart/templates/12-config-map.yaml: AUTH_ROLES emits the
    full roles map as JSON; hub-side syncAuthRoles validates names
    (kubeshark-* prefix reserved) and capabilities (unknown caps
    warn-dropped).
  - helm-chart/values.yaml: regenerated. Diff is the single `roles: {}`
    line under tap.auth.

Spot-checked the rendered ConfigMap:

  AUTH_ROLES: '{"payments-viewer":{"capabilities":["snapshot:read",
                                                   "dissection:live"],
                                    "namespaces":"payments"}}'

which is exactly the shape the hub parser expects.
This commit is contained in:
Volodymyr Stoiko
2026-05-18 21:35:13 +00:00
parent 90a6fb3d40
commit 9445806002
4 changed files with 30 additions and 8 deletions

View File

@@ -105,6 +105,7 @@ func CreateDefaultConfig() ConfigStruct {
RolesClaim: "groups",
DefaultRole: "kubeshark-viewer",
GroupMapping: map[string]string{},
Roles: map[string]configStructs.RoleConfig{},
},
EnabledDissectors: []string{
"amqp",

View File

@@ -178,16 +178,35 @@ type AuthConfig struct {
// DefaultRole is applied when the authenticated user's SSO claim has no
// recognized group. Must be one of the four built-in roles
// (kubeshark-admin / kubeshark-realtime / kubeshark-snapshot /
// kubeshark-viewer) or empty for strict-deny. See hub plans/
// permissions-refactoring.md for the capability matrix per role.
// kubeshark-viewer), the name of an operator-defined role under
// `tap.auth.roles`, or empty for strict-deny.
DefaultRole string `yaml:"defaultRole" json:"defaultRole"`
// GroupMapping translates SSO group names into built-in role names.
// Optional — groups whose name already matches a built-in role are
// identity-matched and don't need an entry here. Use this map when SSO
// groups are named differently from the built-in roles (e.g. an existing
// AD group "engineering-leads" that should resolve to kubeshark-admin).
// GroupMapping translates SSO group names into role names (built-in or
// operator-defined). Optional — groups whose name already matches a
// built-in role are identity-matched and don't need an entry here.
// Operator-defined role names MUST appear here to participate in
// resolution (identity-match is built-in-only).
GroupMapping map[string]string `yaml:"groupMapping" json:"groupMapping"`
Saml SamlConfig `yaml:"saml" json:"saml"`
// Roles is the operator-defined role catalogue, keyed by role name.
// Each role has its own capability set + namespace scope. Names with
// the `kubeshark-` prefix are reserved for built-ins and will be
// rejected at hub startup. Unknown capability strings are dropped
// with a warning; empty / "*" namespace specs mean deny-all-data and
// allow-all respectively (see hub plans/permissions-decisions.md).
Roles map[string]RoleConfig `yaml:"roles" json:"roles"`
Saml SamlConfig `yaml:"saml" json:"saml"`
}
// RoleConfig is an operator-defined role declared under tap.auth.roles.
// Capabilities is the closed vocabulary documented in the hub project
// (snapshot:read / snapshot:write / snapshot:dissection / dissection:live /
// dissection:control / pods:target:write / settings:write); unknown
// capability strings are warn-dropped at hub startup. Namespaces is a
// comma-separated list with `*` (allow-all) and glob (`foo-*`, `*-bar`,
// `*mid*`) support; empty string means deny-all-data.
type RoleConfig struct {
Capabilities []string `yaml:"capabilities" json:"capabilities"`
Namespaces string `yaml:"namespaces" json:"namespaces"`
}
type IngressConfig struct {

View File

@@ -32,6 +32,7 @@ data:
AUTH_ROLES_CLAIM: '{{ .Values.tap.auth.rolesClaim }}'
AUTH_DEFAULT_ROLE: '{{ default "" .Values.tap.auth.defaultRole }}'
AUTH_GROUP_MAPPING: '{{ default (dict) .Values.tap.auth.groupMapping | toJson }}'
AUTH_ROLES: '{{ default (dict) .Values.tap.auth.roles | toJson }}'
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 }}'

View File

@@ -156,6 +156,7 @@ tap:
rolesClaim: groups
defaultRole: kubeshark-viewer
groupMapping: {}
roles: {}
saml:
idpMetadataUrl: ""
x509crt: ""