Skip to content

Configuration

All configuration goes through Helm values. Create a values.yaml with your overrides and apply it:

helm upgrade kubesentry kubesentry/kubesentry \
  --namespace kubesentry \
  -f values.yaml

Notifications

KubeSentry sends instant email on high-severity alerts (Critical/Emergency/Alert) and a daily digest of activity. It can also POST alerts to Slack, Discord, or Microsoft Teams webhooks. Every channel is off by default and enabled independently.

Email

Email is delivered through Resend. You need a Resend API key and a verified sender. to is a list.

notifications:
  email:
    enabled: true
    from: "alerts@your-domain.com"   # must be a verified sender in Resend
    to:
      - "you@your-team.com"
      - "security@your-team.com"
    resendApiKey: "re_xxxxxxxx"      # testing only — prefer existingSecret in production

Keep secrets out of values.yaml

Don't commit real API keys. Instead of inlining resendApiKey, create a Kubernetes Secret with the key resend-api-key and reference it:

notifications:
  email:
    enabled: true
    from: "alerts@your-domain.com"
    to: ["you@your-team.com"]
    existingSecret: "kubesentry-email"   # Secret with key: resend-api-key

Slack / Discord / Teams

Each chat channel takes a webhook URL. Inline webhookUrl is fine for testing; in production reference an existingSecret instead (keys: slack-webhook-url, discord-webhook-url, teams-webhook-url).

notifications:
  slack:
    enabled: true
    webhookUrl: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
    # or: existingSecret: "kubesentry-slack"   # key: slack-webhook-url
  discord:
    enabled: false
    webhookUrl: ""
  teams:
    enabled: false
    webhookUrl: ""

Daily digest

A once-a-day summary email of the last 24 hours. Enabled by default at 09:00 UTC; it uses the same email channel configured above.

digest:
  enabled: true
  cron: "0 9 * * *"
  timezone: "UTC"        # e.g. "Europe/Zagreb"

Storage

Alert history is written to a PersistentVolume so it survives pod restarts and reinstalls.

collector:
  persistence:
    enabled: true
    size: 1Gi
    storageClass: ""     # empty = cluster default

The collector stores events in an embedded SQLite database on this volume. For most small teams the default size is plenty; increase it if you retain a lot of history.

Dashboard exposure

By default the dashboard Service is ClusterIP — reachable only in-cluster. The dashboard has no built-in authentication, so never expose it directly to the internet.

To make it reachable, front it with your own ingress or reverse proxy with authentication (e.g. an OAuth proxy or basic-auth annotations on your ingress controller), pointing at the kubesentry-collector Service on port 8080. So links in emails and webhooks use the right address, set the public URL:

dashboard:
  url: "https://kubesentry.internal.your-domain.com/dashboard"

Resource requests

The collector is lightweight (the image is a ~15 MB distroless build). Falco is the heavier component since it runs on every node. Defaults are sensible for small clusters; tune if needed:

collector:
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

Cluster identity

Name shown in the dashboard top bar, email subjects, and webhook payloads:

cluster:
  name: "prod-us-east"

Tuning detection noise

Every cluster has legitimate activity that looks suspicious to default rules (init scripts, debugging, CI jobs). Falco rules are customizable — add exceptions or custom rules through the falco values block in the chart. See the Falco rules documentation for rule syntax.

Applying changes

Any config change is applied the same way:

helm upgrade kubesentry kubesentry/kubesentry -n kubesentry -f values.yaml

Pods roll automatically. Alert history on the PVC is preserved across upgrades.