Getting Started

Two commands to a protected cluster. Expand from there at your own pace.

Docs / Getting Started

Getting Started

PandoCore ships as a Kubernetes admission webhook that injects a behavioral monitoring sidecar into labeled pods. No application code changes, no SDK, no rules to write.

Prerequisites
  • Kubernetes 1.25+ with kubectl configured
  • Helm 3.0+
  • A PandoCore license key and registry credentials from portal.pandocore.io

2-Command Install

This is the minimum path to a protected workload. Grab the helm install line from your portal dashboard (it comes pre-filled with your license key), then label a deployment.

# 1. Install the admission webhook (one-time, cluster-wide)
helm install pando-webhook \
  oci://us-central1-docker.pkg.dev/pandocore-prod/charts/pando-webhook \
  --set licenseKey="YOUR_LICENSE_KEY"

# 2. Protect a deployment
kubectl label deployment your-app pandocore.io/protect=true
kubectl rollout restart deployment/your-app

The webhook injects the sidecar on the next pod start. Run kubectl get pods and you'll see 2/2 containers.

One-time setup per app namespace

The webhook itself runs in pando-system, but your protected workloads live in their own namespaces. For each namespace where you'll protect apps, you need a copy of the license Secret and a pando-sidecar ServiceAccount. Run this once per app namespace:

NS=your-app-namespace

# Copy the license secret into the app namespace
kubectl get secret pando-license -n pando-system -o yaml \
  | sed "s/namespace: pando-system/namespace: $NS/" \
  | kubectl apply -f -

# Create the sidecar service account + role binding
kubectl create serviceaccount pando-sidecar -n $NS
kubectl create rolebinding pando-sidecar \
  --clusterrole=pando-sidecar \
  --serviceaccount=$NS:pando-sidecar -n $NS

Then label the deployment as normal. See Webhook Reference for details.

What Just Happened

After step 1, you have a mutating admission webhook watching for pods with the pandocore.io/protect=true label. When one starts:

  1. The webhook injects a pando-sidecar container alongside your app container
  2. The sidecar attaches to the shared process namespace and runs a short learning window (30 minutes by default) to build a per-workload operational profile
  3. Once learning is complete, the sidecar begins detecting and (depending on mode) alerting or enforcing
Safe by default

New installs ship in monitor mode. The sidecar observes and logs but never terminates pods until you explicitly opt into enforcement. This lets you validate on real workloads with zero production risk.

Verify It's Working

# Confirm sidecar injected (should show 2/2)
kubectl get pods -l app=your-app

# Watch the sidecar come up
kubectl logs -f <pod-name> -c pando-sidecar

# Check readiness (503 during learning, 200 after)
kubectl exec <pod-name> -c pando-sidecar -- wget -qO- http://localhost:9090/readyz

# Detection metrics
kubectl exec <pod-name> -c pando-sidecar -- wget -qO- http://localhost:9090/metrics

If the sidecar doesn't inject or the logs show license errors, see Troubleshooting.


Progressive Rollout

Everything above gets you to "installed and observing." The sections below walk you from passive monitoring to full production hardening, in the order most teams adopt them. Apply as much as matches your comfort level.

1. Enable Enforcement

Once you've watched a workload in monitor mode for a few days and are satisfied with the detections, flip it to enforce mode. The sidecar will now terminate pods on enforcement-level detections.

# Per-deployment: annotation overrides cluster default
kubectl annotate deployment your-app pandocore.io/mode=enforce --overwrite
kubectl rollout restart deployment/your-app

# Or cluster-wide: change the default for newly-created pods
helm upgrade pando-webhook \
  oci://us-central1-docker.pkg.dev/pandocore-prod/charts/pando-webhook \
  --reuse-values \
  --set defaultMode=enforce

Most teams run monitor → alert → isolate → enforce over the course of a few weeks per workload — each step adds one automated response action on top of the prior. See Operating Modes for the full mode ladder.

Intermediate step: Isolate mode

Before flipping straight to enforce, consider isolate. On a trip, PandoCore applies a NetworkPolicy that blocks pod egress (except DNS) — contains the attack without killing the pod. If drift subsides, the policy is removed automatically. This is the right durable mode for stateful workloads (databases, caches, queues) where pod restart is expensive.

kubectl annotate deployment your-app pandocore.io/mode=isolate --overwrite
kubectl rollout restart deployment/your-app

2. Wire Up Slack Alerts

Real-time notifications on detection. Set PANDO_MODE=alert or enforce and provide a Slack incoming webhook URL:

helm upgrade pando-webhook \
  oci://us-central1-docker.pkg.dev/pandocore-prod/charts/pando-webhook \
  --reuse-values \
  --set defaultMode=alert \
  --set slackWebhookURL="https://hooks.slack.com/services/T.../B.../xxx"

Alerts are color-coded by severity (critical, high, warning, info) and include pod name, severity, and the action taken.

3. Tune Sensitivity

Most workloads don't need any tuning. When they do, the single lever is PANDO_SENSITIVITY. Higher = more permissive, lower = more sensitive.

# Workload is too chatty, reduce false positives
kubectl set env deployment/your-app -c pando-sidecar PANDO_SENSITIVITY=3.0

# Workload is tightly deterministic, catch subtler anomalies
kubectl set env deployment/your-app -c pando-sidecar PANDO_SENSITIVITY=1.5

The webhook also applies runtime-aware defaults for common runtime families. See Configuration Reference.

4. Graduated Response

Instead of jumping straight to pod termination, configure a response chain that isolates the pod first (via an emergency NetworkPolicy) and only terminates if detection persists.

# Alert, then isolate, then escalate to terminate if the pod doesn't recover
kubectl set env deployment/your-app -c pando-sidecar \
  PANDO_RESPONSE_ACTIONS="alert,isolate,terminate"

If the pod returns to baseline during the recovery window, isolation is lifted automatically. See Operating Modes.

5. GitOps via CRD Policy

For anything beyond a handful of deployments, manage configuration declaratively with the PandoCorePolicy CRD. One YAML file in your GitOps repo controls mode, sensitivity, and response chains across multiple namespaces.

apiVersion: pandocore.io/v1alpha1
kind: PandoCorePolicy
metadata:
  name: default
  namespace: production
spec:
  mode: enforce
  sensitivity: medium
  response:
    actions: [alert, isolate, terminate]
  integrations:
    slack: https://hooks.slack.com/services/...

See CRD Policy for the full schema.

6. SIEM / Evidence Pipeline

Every detection emits a structured JSON evidence envelope. By default it's posted to the PandoCore portal, but you can point the webhook at any endpoint that accepts JSON POSTs: SIEM, incident management, custom pipeline, whatever.

kubectl set env deployment/your-app -c pando-sidecar \
  PANDO_EVIDENCE_WEBHOOK_URL="https://your-siem.example.com/ingest"

See Evidence Format for the full schema.


Alternative: Manual Injection

If you can't install the admission webhook (restricted clusters, air-gapped environments), use the standalone injection script:

# Install sidecar infrastructure only
helm install pando \
  oci://us-central1-docker.pkg.dev/pandocore-prod/charts/pando-sidecar \
  --set licenseKey="YOUR_LICENSE_KEY"

# Inject into a specific deployment
PANDO_LICENSE_KEY="YOUR_LICENSE_KEY" \
  ./inject-pandocore.sh your-app your-namespace

Quick Reference

Task Command
View sidecar logs kubectl logs <pod> -c pando-sidecar
Check health kubectl exec <pod> -c pando-sidecar -- wget -qO- http://localhost:9090/healthz
View metrics kubectl exec <pod> -c pando-sidecar -- wget -qO- http://localhost:9090/metrics
Switch to enforce mode kubectl set env deployment/<name> -c pando-sidecar PANDO_MODE=enforce
Trigger re-learning kubectl exec <pod> -c pando-sidecar -- wget -qO- --post-data='' http://localhost:9090/relearn
Disable for a pod kubectl label pod <name> pandocore.io/protect-

Next Steps