Compare commits

...

12 Commits

Author SHA1 Message Date
Volodymyr Stoiko
e948637f79 Revert "auth: emit CHART_VERSION into hub ConfigMap (Phase V)"
This reverts c21e4c42. Companion to hub revert 61a275b6 — the hub no
longer reads CHART_VERSION, so emitting it serves no purpose.
2026-05-19 06:23:16 +00:00
Volodymyr Stoiko
c21e4c4276 auth: emit CHART_VERSION into hub ConfigMap (Phase V)
Hub commit 51abc954 reads this key on first SyncConfig and warns when
its embedded version.Ver disagrees with the chart at the major
component. Provided alongside as the chart-side companion to keep
both sides on one PR per repo on the permissions-refactoring branch.
2026-05-18 22:11:34 +00:00
Volodymyr Stoiko
9445806002 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.
2026-05-18 21:35:13 +00:00
Volodymyr Stoiko
90a6fb3d40 auth: set helm default role to kubeshark-viewer
Per round-2 permissions clarifications: SSO users whose claim doesn't
match any built-in role and isn't in AUTH_GROUP_MAPPING should fall
back to a read-only baseline instead of strict-deny ("").

defaultRole="" causes the dashboard to 403-storm gated endpoints from
unmatched users; viewer (snapshot:read only) gives them a sensible
read-only UX while still preventing any state change.
2026-05-17 21:34:50 +00:00
Volodymyr Stoiko
fd5bf8c1b5 auth: drop AUTH_ROLES; add AUTH_GROUP_MAPPING + built-in defaultRole
Companion to kubeshark/hub#permissions-refactoring. Aligns the CLI
config struct, chart values, and rendered ConfigMap with the
post-refactor hub.

config/configStructs/tapConfig.go:
  - Drop AuthConfig.Roles (admin-authored map[string]Role) and the
    Role + ScriptingPermissions structs they referenced.
  - Drop AuthConfig.DefaultFilter (no namespace scoping in v1).
  - Add AuthConfig.GroupMapping (map[string]string) — SSO group name
    → built-in role translation.
  - Tighten DefaultRole godoc to reference the four built-in role
    constants (kubeshark-admin / kubeshark-realtime /
    kubeshark-snapshot / kubeshark-viewer) and the strict-deny
    semantics on empty.

config/configStruct.go:
  - Drop the legacy "admin" entry from the AuthConfig default —
    operators now configure DefaultRole + GroupMapping instead.
  - Default RolesClaim is now "groups" (Okta/OIDC convention; was
    "role"), matching the hub's runtime default.

helm-chart/templates/12-config-map.yaml:
  - Drop AUTH_ROLES emission (key no longer read by hub).
  - Add AUTH_GROUP_MAPPING emission from tap.auth.groupMapping (JSON
    map; hub validates each value against the built-in role names at
    sync time).

helm-chart/values.yaml: regenerated from the Go config — drops the
tap.auth.roles block, adds tap.auth.groupMapping with the new
documentation header for DefaultRole.

Breaking change: deployments carrying tap.auth.roles in their values
will silently lose those role definitions. Migration is to remove the
roles: block and either (a) name their SSO groups to match the four
built-in role constants, or (b) populate tap.auth.groupMapping with
explicit translations.
2026-05-14 21:04:48 +00:00
Volodymyr Stoiko
7b5954ea00 helm: grant hub tokenreviews and label worker pods for internal auth (#1926)
* helm: grant hub tokenreviews and pass trusted controllers

Adds RBAC for hub to call the authentication.k8s.io/v1 TokenReview
endpoint, used by the new internalauth middleware to validate projected
ServiceAccountTokens presented by in-cluster gRPC callers.

Adds tap.internalAuth.trustedControllers value (empty by default),
threaded through to hub's -trusted-controllers flag as a CSV. Listing
a controller here lets pods owned by it authenticate to hub via the
projected SA token (audience kubeshark-hub). Hub-spawned Jobs are
always trusted regardless of this list. Hub matches OwnerReferences
by name AND UID, so a name-only forgery does not grant trust.

Sub-issue of kubeshark/hub#656.

* helm: inline trusted controllers in hub deployment template

The chart already knows its own controller names (worker DaemonSet
metadata.name is the literal "kubeshark-worker-daemon-set" in
09-worker-daemon-set.yaml). Pasting the same literal into a user-facing
tap.internalAuth.trustedControllers value adds a step without buying
anything — if the worker DS rename, the deployment template would have
to change in lockstep regardless.

Drop the values knob, render the flag unconditionally with the literal
worker DS name (matching the convention used elsewhere in this chart,
e.g. the hub deployment's {{ include "kubeshark.name" . }}-hub).

* helm: drop redundant comment on tokenreviews RBAC

* helm: drop -trusted-controllers flag (no caller today)

The flag was wiring forward-prep for a hypothetical worker->hub gRPC
caller from the DaemonSet. Hub-spawned Jobs (dissection-job) are
admitted via internalauth.RegisterSpawnedJob, not via this flag.
Re-add when an actual DaemonSet-deployed caller materializes.

* helm: label worker DS pods for hub internal auth

Worker pods don't call hub gRPC today, but pre-labeling the DS pod
template means a future worker->hub gRPC caller is one PR (worker-side)
away from working — no chart change required. Matches the generic
label-driven trust model in hub#783.

* helm: rename trust label to kubeshark.io/internal-auth

Matches the hub rename. Generic name so the same label can mark pods
trusted by future kubeshark services beyond hub.
2026-05-13 10:53:20 -07:00
Volodymyr Stoiko
8186b7891b Authz refactoring (helm chart + CLI) (#1921)
* Migrate auth.saml.roles to unified auth.roles

Follows the hub-side introduction of the backend-neutral AUTH_ROLES /
AUTH_ROLES_CLAIM / AUTH_DEFAULT_ROLE config (hub commit 51177bcb).
CLI and Helm chart now surface the unified location:

  tap.auth.roles         — map of role -> permissions (shared SAML/OIDC)
  tap.auth.rolesClaim    — token/assertion claim name carrying roles
  tap.auth.defaultRole   — fallback role for authenticated users with
                           no matching role in their token

Helm ConfigMap template emits AUTH_ROLES / AUTH_ROLES_CLAIM /
AUTH_DEFAULT_ROLE and no longer emits AUTH_SAML_ROLES or
AUTH_SAML_ROLE_ATTRIBUTE. Hub's back-compat fallback still reads those
keys from any existing ConfigMap that hasn't been helm-upgraded.

Legacy struct fields (SamlConfig.Roles, SamlConfig.RoleAttribute) stay
in place so existing values.yaml files with auth.saml.roles still parse
without errors, but the CLI and the chart ignore them. Follow-up release
can remove the struct fields once telemetry confirms migration.

Breaking for users with customized auth.saml.roles in their values.yaml
— the customization is masked by the new default auth.roles.admin and
must be migrated to auth.roles for the custom permissions to take
effect. Documented in the chart README and release notes.

Part of authz-refactoring (Step 2 of hub-oidc-rbac.md, CLI side).

* Remove legacy

* Align CLI + Helm chart with hub AUTH_TYPE rename

Follows hub commit 11564fef. The canonical AUTH_TYPE is now `oidc` for
generic OIDC; `dex` is a permanent alias; `descope` is a new explicit
label. This change surfaces the new vocabulary in the CLI config struct
and the Helm chart, and renames the nested `auth.dexOidc` values.yaml
field to `auth.oidc` for consistency.

Helm chart:
- 12-config-map.yaml: AUTH_OIDC_* keys now read `.Values.tap.auth.oidc.*`
  instead of `auth.dexOidc.*`. The cloud-license override that forced
  AUTH_TYPE=default unless the admin picked `dex` now accepts `oidc` too.
- 13-secret.yaml: OIDC_CLIENT_ID / OIDC_CLIENT_SECRET read from
  `auth.oidc.*` (was `auth.dexOidc.*`).
- 06-front-deployment.yaml: REACT_APP_AUTH_ENABLED / REACT_APP_AUTH_TYPE
  conditionals accept both `oidc` and `dex` where they previously only
  matched `dex`.
- values.yaml: comment on `tap.auth.type` lists valid values and flags
  the breaking change.
- README.md: `tap.auth.type` row lists valid values. All `dexOidc`
  references renamed to `oidc`. Sample values.yaml blocks now show
  `type: oidc` as the canonical form.

CLI:
- config/configStructs/tapConfig.go: AuthConfig.Type documented with the
  full list of valid values and the migration hint.

Breaking changes (repeated in release notes):
1. `tap.auth.type: oidc` now routes to the generic OIDC middleware
   (previously Descope). Switch to `tap.auth.type: descope` or `default`
   if you were using `oidc` for Descope.
2. `tap.auth.dexOidc.*` values are no longer read. Rename to
   `tap.auth.oidc.*`. No fallback.
3. `tap.auth.type: dex` continues to work — permanent alias of `oidc`.

Part of authz-refactoring (Step 4 of hub-oidc-rbac.md, CLI/Helm side).

* default kfl

* Authz Refactoring: Step 8: namespaces-list role filter

Align with hub PR kubeshark/hub#756. Per-role auth.roles[].filter (KFL)
is replaced by auth.roles[].namespaces (comma-separated list with "*",
literal, and glob semantics). Standalone tap.auth.defaultFilter knob
removed.

helm-chart/values.yaml
- admin role example uses namespaces: "*" instead of filter: "".
- Comment block explains the new namespaces semantics.
- defaultFilter: "" entry + accompanying comment block deleted.

helm-chart/templates/12-config-map.yaml
- AUTH_DEFAULT_FILTER ConfigMap entry removed (hub no longer reads it).

helm-chart/README.md
- tap.auth.defaultFilter row removed.
- tap.auth.roles default value example updated: filter: "" → namespaces: "*";
  description gains the per-role namespaces semantics legend.
2026-05-06 09:08:21 -07:00
Alon Girmonsky
ab81b0c3a7 🔖 Bump the Helm chart version to 53.2.5 (#1920)
Co-authored-by: Alon Girmonsky <alongir@Alons-Mac-Studio.local>
2026-05-01 13:36:38 -07:00
Alon Girmonsky
9f5a1a41c0 fix(release-pr): sync bumped Chart.yaml to kubeshark.github.io (#1913)
* fix(release-pr): sync bumped Chart.yaml to kubeshark.github.io

The release-pr target was switching back to master (and pulling)
BEFORE copying helm-chart/ into ../kubeshark.github.io/charts/chart.
That reverted the working tree to the pre-bump Chart.yaml, so the
kubeshark.github.io PR shipped the previous version and the
chart-releaser action failed trying to recreate an existing tag.

Copy the bumped chart from the release/vX.Y.Z working tree, then
switch kubeshark back to master at the end of the target.

Also consolidate iterative robustness improvements: VERSION
validation, idempotent sibling-repo tagging, idempotent branch /
commit / push / PR creation, and a "nothing to commit" guard so
reruns of release-pr do not fail.

* refactor(release): split release-pr into three rerunnable targets

Before, release-pr did three things in one recipe: tag sibling
repos, create the kubeshark release PR, and create the helm chart
PR. If any step failed, the whole target had to be rerun, even for
the parts that had already succeeded, and some sub-steps (like
tagging worker/hub/front after a docker-image-only rebuild) had no
standalone entry point.

Split into:
  - release-siblings     : tag worker, hub, front
  - release-pr-kubeshark : bump Chart.yaml, build, open kubeshark PR
  - release-pr-helm      : sync chart to kubeshark.github.io, open helm PR
  - release-pr           : orchestrates all three in order

Each is idempotent and can be rerun independently. release-siblings
is now the canonical entry point for tagging sibling repos when
refreshing docker images without a full release.

release-pr-helm checks out release/v$(VERSION) (fetching from origin
if absent) before copying helm-chart/, so it has the bumped Chart.yaml
regardless of whether it runs right after release-pr-kubeshark or
days later in a separate invocation.

A shared _release-check-version prerequisite validates VERSION once
per target invocation.

* fix(release): make branch creation and push truly idempotent

Delete and recreate local release/helm branches instead of conditionally
checking out, and use --force-with-lease push to handle local/remote
divergence on reruns.

---------

Co-authored-by: Alon Girmonsky <alongir@Alons-Mac-Studio.local>
2026-05-01 10:07:20 -07:00
Alon Girmonsky
fef3e8fb05 Add PostgreSQL protocol configuration (#1919)
* Add MySQL protocol to default configuration

Closes #1915

* Add PostgreSQL protocol configuration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Alon Girmonsky <alongir@Alons-Mac-Studio.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 12:59:11 +03:00
Alon Girmonsky
7ae81ccc4b Add MySQL protocol to default configuration (#1916)
Closes #1915

Co-authored-by: Alon Girmonsky <alongir@Alons-Mac-Studio.local>
2026-04-28 15:49:44 +03:00
Serhii Ponomarenko
27111e48d3 🔨 Create dashboard entries-limit helm value (#1914)
* 🔨 Create dashboard entries-limit helm value

* 🔨 Set default value for entries-limit env
2026-04-23 18:20:22 +03:00
14 changed files with 381 additions and 183 deletions

123
Makefile
View File

@@ -253,52 +253,111 @@ port-forward:
kubectl port-forward $$(kubectl get pods | awk '$$1 ~ /^$(POD_PREFIX)/' | awk 'END {print $$1}') $(SRC_PORT):$(DST_PORT)
release: ## Print release workflow instructions.
@echo "Release workflow (2 steps):"
@echo "Release workflow — each step is idempotent and can be rerun on its own:"
@echo ""
@echo " 1. make release-pr VERSION=x.y.z"
@echo " Tags sibling repos, bumps version, creates PRs"
@echo " (kubeshark + kubeshark.github.io helm chart)."
@echo " Review and merge both PRs manually."
@echo " 1. make release-siblings VERSION=x.y.z"
@echo " Tag worker, hub, front with vx.y.z. Also run standalone when"
@echo " rebuilding docker images without cutting a full release."
@echo ""
@echo " 2. (automatic) Tag is created when release PR merges."
@echo " Fallback: make release-tag VERSION=x.y.z"
@echo " 2. make release-pr-kubeshark VERSION=x.y.z"
@echo " Bump Helm Chart.yaml, build, open release PR on kubeshark."
@echo ""
@echo " 3. make release-pr-helm VERSION=x.y.z"
@echo " Sync helm-chart/ into kubeshark.github.io, open helm PR."
@echo " Requires release/vx.y.z branch (created by step 2)."
@echo ""
@echo " Shortcut: make release-pr VERSION=x.y.z runs 1 → 2 → 3."
@echo ""
@echo " After both PRs merge: tag is created automatically,"
@echo " or run: make release-tag VERSION=x.y.z"
release-pr: ## Step 1: Tag sibling repos, bump version, create release PR.
@cd ../worker && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../hub && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
@cd ../front && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
# Internal: validate VERSION before any release-* target runs.
_release-check-version:
@if [ -z "$(VERSION)" ]; then echo "ERROR: VERSION is required. Usage: make <target> VERSION=x.y.z"; exit 1; fi
@echo "$(VERSION)" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+' || { echo "ERROR: VERSION must be semver (e.g. 53.2.4)"; exit 1; }
release-siblings: _release-check-version ## Tag worker, hub, front with v$(VERSION). Idempotent; standalone for docker-image-only updates.
@for repo in worker hub front; do \
echo "==> $$repo: ensuring v$(VERSION) tag"; \
(cd ../$$repo && git checkout master && git pull) || exit 1; \
if (cd ../$$repo && git ls-remote --tags origin "refs/tags/v$(VERSION)" | grep -q .); then \
echo " v$(VERSION) already on origin — skipping"; \
else \
(cd ../$$repo && git tag -d v$(VERSION) 2>/dev/null; git tag v$(VERSION) && git push origin "refs/tags/v$(VERSION)") || exit 1; \
fi; \
done
release-pr-kubeshark: _release-check-version ## Bump Chart.yaml, build, open release PR on kubeshark.
@cd ../kubeshark && git checkout master && git pull
@sed -i '' "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml
@NEW=$$(echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/'); \
CUR=$$(awk '/^version:/ {gsub(/"/,"",$$2); print $$2; exit}' helm-chart/Chart.yaml); \
if [ "$$CUR" != "$$NEW" ]; then \
sed -i '' "s/^version:.*/version: \"$$NEW\"/" helm-chart/Chart.yaml; \
else \
echo "Chart.yaml already at $$NEW"; \
fi
@$(MAKE) build VER=$(VERSION)
@if [ "$(shell uname)" = "Darwin" ]; then \
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime ./bin/kubeshark__; \
fi
@$(MAKE) generate-helm-values && $(MAKE) generate-manifests
@if git show-ref --verify --quiet refs/heads/release/v$(VERSION); then \
git branch -D release/v$(VERSION); \
fi
@git checkout -b release/v$(VERSION)
@git add -A .
@git commit -m ":bookmark: Bump the Helm chart version to $(VERSION)"
@git push -u origin release/v$(VERSION)
@gh pr create --title ":bookmark: Release v$(VERSION)" \
--body "Automated release PR for v$(VERSION)." \
--base master \
--reviewer corest
@git checkout master && git pull
@cd ../kubeshark.github.io \
&& git checkout master && git pull \
&& rm -rf charts/chart \
&& mkdir charts/chart \
&& cp -r ../kubeshark/helm-chart/ charts/chart/ \
&& git checkout -b helm-v$(VERSION) \
&& git add -A . \
&& git commit -m ":sparkles: Update the Helm chart to v$(VERSION)" \
&& git push -u origin helm-v$(VERSION) \
&& gh pr create --title ":sparkles: Helm chart v$(VERSION)" \
@if ! git diff --cached --quiet; then \
git commit -m ":bookmark: Bump the Helm chart version to $(VERSION)"; \
else \
echo "nothing to commit"; \
fi
@git push --force-with-lease -u origin release/v$(VERSION)
@if gh pr view release/v$(VERSION) --json number >/dev/null 2>&1; then \
echo "PR already exists for release/v$(VERSION)"; \
else \
gh pr create --title ":bookmark: Release v$(VERSION)" \
--body "Automated release PR for v$(VERSION)." \
--base master \
--reviewer corest; \
fi
release-pr-helm: _release-check-version ## Sync helm-chart/ to kubeshark.github.io and open the helm PR. Requires release/v$(VERSION) branch (step 2).
@git fetch origin "refs/heads/release/v$(VERSION):refs/heads/release/v$(VERSION)" 2>/dev/null || true
@if ! git show-ref --verify --quiet refs/heads/release/v$(VERSION); then \
echo "ERROR: release/v$(VERSION) branch not found locally or on origin."; \
echo "Run 'make release-pr-kubeshark VERSION=$(VERSION)' first."; \
exit 1; \
fi
@git checkout release/v$(VERSION)
@cd ../kubeshark.github.io && git checkout master && git pull \
&& rm -rf charts/chart && mkdir -p charts/chart \
&& cp -r ../kubeshark/helm-chart/ charts/chart/
@cd ../kubeshark.github.io && \
if git show-ref --verify --quiet refs/heads/helm-v$(VERSION); then \
git branch -D helm-v$(VERSION); \
fi && \
git checkout -b helm-v$(VERSION) && \
git add -A . && \
if ! git diff --cached --quiet; then \
git commit -m ":sparkles: Update the Helm chart to v$(VERSION)"; \
else \
echo "nothing to commit"; \
fi && \
git push --force-with-lease -u origin helm-v$(VERSION) && \
if ! gh pr view helm-v$(VERSION) --json number >/dev/null 2>&1; then \
gh pr create --title ":sparkles: Helm chart v$(VERSION)" \
--body "Update Helm chart for release v$(VERSION)." \
--base master \
--reviewer corest \
&& git checkout master
--reviewer corest; \
else \
echo "PR already exists for helm-v$(VERSION)"; \
fi && \
git checkout master
@cd ../kubeshark && git checkout master && git pull
release-pr: release-siblings release-pr-kubeshark release-pr-helm ## Run release-siblings, release-pr-kubeshark, and release-pr-helm in sequence.
@echo ""
@echo "Release PRs created:"
@echo "Release PRs created (or already present):"
@echo " - kubeshark: Review and merge the release PR."
@echo " - kubeshark.github.io: Review and merge the helm chart PR."
@echo "Tag will be created automatically, or run: make release-tag VERSION=$(VERSION)"

View File

@@ -102,25 +102,10 @@ 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: "groups",
DefaultRole: "kubeshark-viewer",
GroupMapping: map[string]string{},
Roles: map[string]configStructs.RoleConfig{},
},
EnabledDissectors: []string{
"amqp",
@@ -129,6 +114,8 @@ func CreateDefaultConfig() ConfigStruct {
"icmp",
"kafka",
"mongodb",
"mysql",
"postgresql",
"redis",
// "sctp",
// "syscall",
@@ -149,7 +136,9 @@ func CreateDefaultConfig() ConfigStruct {
AMQP: []uint16{5671, 5672},
KAFKA: []uint16{9092},
MONGODB: []uint16{27017},
REDIS: []uint16{6379},
MYSQL: []uint16{3306},
POSTGRESQL: []uint16{5432},
REDIS: []uint16{6379},
LDAP: []uint16{389},
DIAMETER: []uint16{3868},
},

View File

@@ -155,35 +155,58 @@ type ProbeConfig struct {
FailureThreshold int `yaml:"failureThreshold" json:"failureThreshold" default:"3"`
}
type ScriptingPermissions struct {
CanSave bool `yaml:"canSave" json:"canSave" default:"true"`
CanActivate bool `yaml:"canActivate" json:"canActivate" default:"true"`
CanDelete bool `yaml:"canDelete" json:"canDelete" default:"true"`
}
type Role struct {
Filter string `yaml:"filter" json:"filter" default:""`
CanDownloadPCAP bool `yaml:"canDownloadPCAP" json:"canDownloadPCAP" default:"false"`
CanUseScripting bool `yaml:"canUseScripting" json:"canUseScripting" default:"false"`
ScriptingPermissions ScriptingPermissions `yaml:"scriptingPermissions" json:"scriptingPermissions"`
CanUpdateTargetedPods bool `yaml:"canUpdateTargetedPods" json:"canUpdateTargetedPods" default:"false"`
CanStopTrafficCapturing bool `yaml:"canStopTrafficCapturing" json:"canStopTrafficCapturing" default:"false"`
CanControlDissection bool `yaml:"canControlDissection" json:"canControlDissection" default:"false"`
ShowAdminConsoleLink bool `yaml:"showAdminConsoleLink" json:"showAdminConsoleLink" default:"false"`
}
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"`
RolesClaim string `yaml:"rolesClaim" json:"rolesClaim"`
// 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), 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 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"`
// 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 {
@@ -203,6 +226,7 @@ type DashboardConfig struct {
StreamingType string `yaml:"streamingType" json:"streamingType" default:"connect-rpc"`
CompleteStreamingEnabled bool `yaml:"completeStreamingEnabled" json:"completeStreamingEnabled" default:"true"`
ClusterWideMapEnabled bool `yaml:"clusterWideMapEnabled" json:"clusterWideMapEnabled" default:"false"`
EntriesLimit string `yaml:"entriesLimit" json:"entriesLimit" default:"300000"`
}
type FrontRoutingConfig struct {
@@ -283,7 +307,9 @@ type PortMapping struct {
AMQP []uint16 `yaml:"amqp" json:"amqp"`
KAFKA []uint16 `yaml:"kafka" json:"kafka"`
MONGODB []uint16 `yaml:"mongodb" json:"mongodb"`
REDIS []uint16 `yaml:"redis" json:"redis"`
MYSQL []uint16 `yaml:"mysql" json:"mysql"`
POSTGRESQL []uint16 `yaml:"postgresql" json:"postgresql"`
REDIS []uint16 `yaml:"redis" json:"redis"`
LDAP []uint16 `yaml:"ldap" json:"ldap"`
DIAMETER []uint16 `yaml:"diameter" json:"diameter"`
}

View File

@@ -1,6 +1,6 @@
apiVersion: v2
name: kubeshark
version: "53.2.3"
version: "53.2.5"
description: The API Traffic Analyzer for Kubernetes
home: https://kubeshark.com
keywords:

View File

@@ -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 <br/>(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 <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509crt` | A self-signed X.509 `.cert` contents <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.x509key` | A self-signed X.509 `.key` contents <br/>(effective, if `tap.auth.type = saml`) | `` |
| `tap.auth.saml.roleAttribute` | A SAML attribute name corresponding to user's authorization role <br/>(effective, if `tap.auth.type = saml`) | `role` |
| `tap.auth.saml.roles` | A list of SAML authorization roles and their permissions <br/>(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: <put Dex IdP issuer URL here>
clientId: kubeshark
clientSecret: create your own client password
@@ -390,7 +391,7 @@ tap:
---
**Note:**<br/>
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:<br/>
@@ -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://<your-ingress-hostname>/dex
# Client ID/secret must be taken from `tap.auth.dexConfig.staticClients -> id/secret`

View File

@@ -44,6 +44,12 @@ rules:
- create
- update
- delete
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role

View File

@@ -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 }}
@@ -92,6 +92,8 @@ spec:
value: '{{ default false (((.Values).tap).dashboard).clusterWideMapEnabled }}'
- name: REACT_APP_RAW_CAPTURE_ENABLED
value: '{{ .Values.tap.capture.raw.enabled | ternary "true" "false" }}'
- name: REACT_APP_ENTRIES_LIMIT
value: '{{ default 300000 (((.Values).tap).dashboard).entriesLimit }}'
- name: REACT_APP_SENTRY_ENABLED
value: '{{ (include "sentry.enabled" .) }}'
- name: REACT_APP_SENTRY_ENVIRONMENT

View File

@@ -21,6 +21,7 @@ spec:
metadata:
labels:
app.kubeshark.com/app: worker
kubeshark.io/internal-auth: "true"
{{- include "kubeshark.labels" . | nindent 8 }}
name: kubeshark-worker-daemon-set
namespace: kubeshark

View File

@@ -19,27 +19,29 @@ 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_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 }}'
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 }}'

View File

@@ -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 }}'
---

View File

@@ -153,24 +153,14 @@ tap:
auth:
enabled: false
type: saml
rolesClaim: groups
defaultRole: kubeshark-viewer
groupMapping: {}
roles: {}
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: ""
@@ -188,6 +178,7 @@ tap:
streamingType: connect-rpc
completeStreamingEnabled: true
clusterWideMapEnabled: false
entriesLimit: "300000"
telemetry:
enabled: true
resourceGuard:
@@ -208,6 +199,8 @@ tap:
- icmp
- kafka
- mongodb
- mysql
- postgresql
- redis
- ws
- ldap
@@ -229,6 +222,10 @@ tap:
- 9092
mongodb:
- 27017
mysql:
- 3306
postgresql:
- 5432
redis:
- 6379
ldap:

View File

@@ -4,10 +4,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-hub-network-policy
namespace: default
@@ -33,10 +33,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-front-network-policy
@@ -60,10 +60,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-dex-network-policy
@@ -87,10 +87,10 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-worker-network-policy
@@ -116,10 +116,10 @@ apiVersion: v1
kind: ServiceAccount
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-service-account
namespace: default
@@ -132,10 +132,10 @@ metadata:
namespace: default
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
stringData:
LICENSE: ''
@@ -151,10 +151,10 @@ metadata:
namespace: default
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
stringData:
AUTH_SAML_X509_CRT: |
@@ -167,10 +167,10 @@ metadata:
namespace: default
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
stringData:
AUTH_SAML_X509_KEY: |
@@ -182,10 +182,10 @@ metadata:
name: kubeshark-nginx-config-map
namespace: default
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
data:
default.conf: |
@@ -252,10 +252,10 @@ metadata:
namespace: default
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
data:
POD_REGEX: '.*'
@@ -293,7 +293,7 @@ data:
TIMEZONE: ' '
CLOUD_LICENSE_ENABLED: 'true'
DUPLICATE_TIMEFRAME: '200ms'
ENABLED_DISSECTORS: 'amqp,dns,http,icmp,kafka,mongodb,redis,ws,ldap,radius,diameter,udp-flow,tcp-flow,udp-conn,tcp-conn'
ENABLED_DISSECTORS: 'amqp,dns,http,icmp,kafka,mongodb,mysql,postgresql,redis,ws,ldap,radius,diameter,udp-flow,tcp-flow,udp-conn,tcp-conn'
CUSTOM_MACROS: '{"https":"tls and (http or http2)"}'
DISSECTORS_UPDATING_ENABLED: 'true'
SNAPSHOTS_UPDATING_ENABLED: 'true'
@@ -303,7 +303,7 @@ data:
PCAP_TIME_INTERVAL: '1m'
PCAP_MAX_TIME: '1h'
PCAP_MAX_SIZE: '500MB'
PORT_MAPPING: '{"amqp":[5671,5672],"diameter":[3868],"http":[80,443,8080],"kafka":[9092],"ldap":[389],"mongodb":[27017],"redis":[6379]}'
PORT_MAPPING: '{"amqp":[5671,5672],"diameter":[3868],"http":[80,443,8080],"kafka":[9092],"ldap":[389],"mongodb":[27017],"mysql":[3306],"postgresql":[5432],"redis":[6379]}'
RAW_CAPTURE_ENABLED: 'true'
RAW_CAPTURE_STORAGE_SIZE: '1Gi'
---
@@ -312,10 +312,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-cluster-role-default
namespace: default
@@ -359,10 +359,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-cluster-role-binding-default
namespace: default
@@ -380,10 +380,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-self-config-role
@@ -439,10 +439,10 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
name: kubeshark-self-config-role-binding
@@ -462,10 +462,10 @@ kind: Service
metadata:
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-hub
namespace: default
@@ -483,10 +483,10 @@ apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-front
namespace: default
@@ -504,10 +504,10 @@ kind: Service
apiVersion: v1
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
prometheus.io/scrape: 'true'
@@ -517,10 +517,10 @@ metadata:
spec:
selector:
app.kubeshark.com/app: worker
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
ports:
- name: metrics
@@ -533,10 +533,10 @@ kind: Service
apiVersion: v1
metadata:
labels:
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
annotations:
prometheus.io/scrape: 'true'
@@ -546,10 +546,10 @@ metadata:
spec:
selector:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
ports:
- name: metrics
@@ -564,10 +564,10 @@ metadata:
labels:
app.kubeshark.com/app: worker
sidecar.istio.io/inject: "false"
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-worker-daemon-set
namespace: default
@@ -581,10 +581,10 @@ spec:
metadata:
labels:
app.kubeshark.com/app: worker
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-worker-daemon-set
namespace: kubeshark
@@ -805,10 +805,10 @@ kind: Deployment
metadata:
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-hub
namespace: default
@@ -823,10 +823,10 @@ spec:
metadata:
labels:
app.kubeshark.com/app: hub
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
spec:
dnsPolicy: ClusterFirstWithHostNet
@@ -936,10 +936,10 @@ kind: Deployment
metadata:
labels:
app.kubeshark.com/app: front
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
name: kubeshark-front
namespace: default
@@ -954,10 +954,10 @@ spec:
metadata:
labels:
app.kubeshark.com/app: front
helm.sh/chart: kubeshark-53.2.3
helm.sh/chart: kubeshark-53.2.5
app.kubernetes.io/name: kubeshark
app.kubernetes.io/instance: kubeshark
app.kubernetes.io/version: "53.2.3"
app.kubernetes.io/version: "53.2.5"
app.kubernetes.io/managed-by: Helm
spec:
containers:
@@ -1006,6 +1006,8 @@ spec:
value: 'false'
- name: REACT_APP_RAW_CAPTURE_ENABLED
value: 'true'
- name: REACT_APP_ENTRIES_LIMIT
value: '300000'
- name: REACT_APP_SENTRY_ENABLED
value: 'false'
- name: REACT_APP_SENTRY_ENVIRONMENT

View File

@@ -88,13 +88,15 @@ filter term — they're fast and narrow the search space immediately.
|------|----------|------|----------|
| `http` | HTTP/1.1, HTTP/2 | `redis` | Redis |
| `dns` | DNS | `kafka` | Kafka |
| `tls` | TLS/SSL | `amqp` | AMQP |
| `tls` | eBPF TLS interception | `amqp` | AMQP |
| `tcp` | TCP | `ldap` | LDAP |
| `udp` | UDP | `ws` | WebSocket |
| `sctp` | SCTP | `gql` | GraphQL (v1+v2) |
| `icmp` | ICMP | `gqlv1` / `gqlv2` | GraphQL version-specific |
| `radius` | RADIUS | `conn` / `flow` | L4 connection/flow tracking |
| `diameter` | Diameter | `tcp_conn` / `udp_conn` | Transport-specific connections |
| `grpc` | gRPC (HTTP/2 sub-protocol) | `mongodb` | MongoDB |
| `mysql` | MySQL | `radius` | RADIUS |
| `diameter` | Diameter | `conn` / `flow` | L4 connection/flow tracking |
| | | `tcp_conn` / `udp_conn` | Transport-specific connections |
## Kubernetes Context
@@ -112,6 +114,17 @@ dst.service.namespace == "payments"
Pod fields fall back to service data when pod info is unavailable, so
`dst.pod.namespace` works even for service-level entries.
### Summary Name and Namespace
Convenience variables that pick the best available identity for a peer:
```
src.name == "api-gateway" // pod > service > dns > process
dst.name.contains("payment") // works across identity types
src.namespace == "production" // pod namespace, falls back to service
dst.namespace != "kube-system" // exclude system namespace
```
### Aggregate Collections
Match against any direction (src or dst):
@@ -192,8 +205,14 @@ http && request.headers["content-type"] == "application/json"
// GraphQL (subset of HTTP)
gql && method == "POST" && status_code >= 400
// Only eBPF-intercepted TLS traffic (decrypted HTTPS)
tls && http && status_code >= 500
```
> **Note on `tls`**: The `tls` flag is an alias for `capture_source == "ebpf_tls"`.
> It indicates traffic captured via eBPF TLS interception, not TLS protocol dissection.
## DNS Filtering
DNS issues are often the hidden root cause of outages.
@@ -235,6 +254,40 @@ kafka && kafka_request_summary.contains("orders") // Topic filtering
kafka && kafka_size > 10000 // Large messages
```
### MongoDB
```
mongodb && mongodb_command == "find" // Find operations
mongodb && mongodb_collection == "users" // Collection filtering
mongodb && mongodb_database == "mydb" // Database filtering
mongodb && !mongodb_success // Failed operations
mongodb && mongodb_error_code != 0 // Error code filtering
mongodb && mongodb_total_size > 10000 // Large operations
```
### MySQL
```
mysql && mysql_command == "COM_QUERY" // SQL queries
mysql && mysql_query.contains("SELECT") // SELECT statements
mysql && mysql_database == "orders_db" // Database filtering
mysql && !mysql_success // Failed queries
mysql && mysql_error_code != 0 // Error code filtering
mysql && mysql_total_size > 10000 // Large queries
```
### gRPC
gRPC is a sub-protocol of HTTP/2. All HTTP variables are also available on gRPC entries.
```
grpc && grpc_method == "SayHello" // Method filtering
grpc && grpc_status != 0 // Non-OK status codes
grpc && grpc_status == 14 // UNAVAILABLE
grpc && grpc_method.contains("Create") // Method pattern
grpc && elapsed_time > 1000000 // Slow gRPC calls (>1s)
```
### AMQP, LDAP, RADIUS, Diameter
```
@@ -288,7 +341,7 @@ dst.port >= 8000 && dst.port <= 9000
timestamp > timestamp("2026-03-14T22:00:00Z")
timestamp >= timestamp("2026-03-14T22:00:00Z") && timestamp <= timestamp("2026-03-14T23:00:00Z")
timestamp > now() - duration("5m") // Last 5 minutes
elapsed_time > 2000000 // Older than 2 seconds
elapsed_time > 2000000 // Latency > 2 seconds
```
## Building Filters: Progressive Narrowing

View File

@@ -39,7 +39,7 @@ These are the variables you'll reach for in 90% of investigations:
| `index` | int | Entry index for stream uniqueness |
| `stream` | string | Stream identifier (hex string) |
| `timestamp` | timestamp | Event time (UTC), use with `timestamp()` function |
| `elapsed_time` | int | Age since timestamp in microseconds |
| `elapsed_time` | int | Response-request latency in microseconds |
| `worker` | string | Worker identifier |
## Cross-Reference Variables
@@ -67,13 +67,15 @@ Boolean variables indicating detected protocol. Use as first filter term for per
|----------|----------|----------|----------|
| `http` | HTTP/1.1, HTTP/2 | `redis` | Redis |
| `dns` | DNS | `kafka` | Kafka |
| `tls` | TLS/SSL handshake | `amqp` | AMQP messaging |
| `tls` | eBPF TLS interception | `amqp` | AMQP messaging |
| `tcp` | TCP transport | `ldap` | LDAP directory |
| `udp` | UDP transport | `ws` | WebSocket |
| `sctp` | SCTP streaming | `gql` | GraphQL (v1 or v2) |
| `icmp` | ICMP | `gqlv1` | GraphQL v1 only |
| `radius` | RADIUS auth | `gqlv2` | GraphQL v2 only |
| `diameter` | Diameter | `conn` | L4 connection tracking |
| `grpc` | gRPC (HTTP/2 sub-protocol) | `gqlv2` | GraphQL v2 only |
| `mongodb` | MongoDB | `mysql` | MySQL |
| `radius` | RADIUS auth | `diameter` | Diameter |
| | | `conn` | L4 connection tracking |
| `flow` | L4 flow tracking | `tcp_conn` | TCP connection tracking |
| `tcp_flow` | TCP flow tracking | `udp_conn` | UDP connection tracking |
| `udp_flow` | UDP flow tracking | | |
@@ -123,7 +125,7 @@ Supported question types: A, AAAA, NS, CNAME, SOA, MX, TXT, SRV, PTR, ANY.
| Variable | Type | Description | Example |
|----------|------|-------------|---------|
| `tls` | bool | TLS payload detected | |
| `tls` | bool | eBPF TLS interception (alias for `capture_source == "ebpf_tls"`) | |
| `tls_summary` | string | TLS handshake summary | `"ClientHello"`, `"ServerHello"` |
| `tls_info` | string | TLS connection details | `"TLS 1.3, AES-256-GCM"` |
| `tls_request_size` | int | TLS request size in bytes | |
@@ -263,6 +265,55 @@ Supported question types: A, AAAA, NS, CNAME, SOA, MX, TXT, SRV, PTR, ANY.
| `diameter_response_length` | int | Response size (0 if absent) |
| `diameter_total_size` | int | Sum of request + response |
## MongoDB Variables
| Variable | Type | Description | Example |
|----------|------|-------------|---------|
| `mongodb` | bool | MongoDB payload detected | |
| `mongodb_command` | string | Operation type | `"find"`, `"insert"`, `"update"`, `"delete"` |
| `mongodb_database` | string | Database name | `"mydb"` |
| `mongodb_collection` | string | Collection name | `"users"` |
| `mongodb_opcode` | string | Operation opcode name | |
| `mongodb_request_size` | int | Request size in bytes | |
| `mongodb_response_size` | int | Response size in bytes | |
| `mongodb_total_size` | int | Combined request + response size | |
| `mongodb_success` | bool | Operation success status | |
| `mongodb_error_code` | int | Error code | |
| `mongodb_error_message` | string | Error description | |
| `mongodb_error_code_name` | string | Named error code | |
**Example**: `mongodb && mongodb_command == "find" && mongodb_collection == "users"`
## MySQL Variables
| Variable | Type | Description | Example |
|----------|------|-------------|---------|
| `mysql` | bool | MySQL payload detected | |
| `mysql_command` | string | SQL command name | `"COM_QUERY"`, `"COM_STMT_PREPARE"` |
| `mysql_query` | string | Full SQL query text | `"SELECT * FROM users"` |
| `mysql_database` | string | Active database name | `"orders_db"` |
| `mysql_statement_id` | int | Prepared statement identifier | |
| `mysql_request_size` | int | Request payload size in bytes | |
| `mysql_response_size` | int | Response payload size in bytes | |
| `mysql_total_size` | int | Combined request + response size | |
| `mysql_success` | bool | Response OK status | |
| `mysql_error_code` | int | MySQL error code | |
| `mysql_error_message` | string | Error description | |
**Example**: `mysql && mysql_query.contains("SELECT") && !mysql_success`
## gRPC Variables
gRPC is a sub-protocol of HTTP/2. When `grpc` is true, all HTTP variables are also available.
| Variable | Type | Description | Example |
|----------|------|-------------|---------|
| `grpc` | bool | gRPC payload detected | |
| `grpc_method` | string | Trailing method name from gRPC :path | `"SayHello"` (from `/helloworld.Greeter/SayHello`) |
| `grpc_status` | int | gRPC status code from Grpc-Status trailer | `0`=OK, `5`=NOT_FOUND, `14`=UNAVAILABLE; `-1` on non-gRPC |
**Example**: `grpc && grpc_status != 0 && grpc_method.contains("Create")`
## L4 Connection Tracking Variables
| Variable | Type | Description | Example |
@@ -320,6 +371,15 @@ even when only service-level resolution exists.
**Example**: `src.service.name == "api-gateway" && dst.pod.namespace == "production"`
### Summary Name and Namespace
| Variable | Type | Description |
|----------|------|-------------|
| `src.name` | string | Worker-enriched summary name of source (pod > service > dns > process) |
| `dst.name` | string | Worker-enriched summary name of destination |
| `src.namespace` | string | Source namespace with service fallback |
| `dst.namespace` | string | Destination namespace with service fallback |
### Aggregate Collections (Non-Directional)
| Variable | Type | Description |