CRD-Based Policy

Manage PandoCore configuration declaratively with Kubernetes custom resources.

Docs / CRD Policy

CRD-Based Policy

Instead of scattering environment variables across deployments, define a single PandoCorePolicy custom resource per namespace and apply it with kubectl. Policy values override environment variables automatically.

Three-Step Setup
  1. Create a pando-policy.yaml file
  2. Run kubectl apply -f pando-policy.yaml
  3. Done — sidecars pick up the policy within 30 seconds

Quick Start

Create a file called pando-policy.yaml:

apiVersion: pandocore.xyz/v1alpha1
kind: PandoCorePolicy
metadata:
  name: default
  namespace: production
spec:
  mode: enforce
  sensitivity: high

Apply it:

kubectl apply -f pando-policy.yaml

Verify:

kubectl get pcp -n production

NAME      MODE      SENSITIVITY   AGE
default   enforce   high          5s

Full Policy Reference

Every field is optional. The sidecar falls back to environment variables (or built-in defaults) for any field not specified.

apiVersion: pandocore.xyz/v1alpha1
kind: PandoCorePolicy
metadata:
  name: default            # must be "default" — one policy per namespace
  namespace: production
spec:
  # Operating mode
  mode: enforce            # monitor | alert | enforce | debug

  # Sensitivity preset (maps to threshold multipliers)
  # Ignored if explicit thresholds are set below
  sensitivity: medium      # low | medium | high

  # Graduated response chain
  response:
    actions:
      - alert
      - isolate
      - terminate
    escalationDelaySec: 60

  # Explicit drift thresholds (override sensitivity preset)
  thresholds:
    incremental: 0.15      # sample-to-sample drift (0.0–1.0)
    cumulative: 0.45       # total drift from baseline (0.0–1.0)

  # Feature toggles
  features:
    mlDetection: true
    networkAudit: true
    attestation: true

  # Alert integrations
  integrations:
    slack: "https://hooks.slack.com/services/T.../B.../xxx"
    pagerduty: "<routing-key>"

  # Exclusions (applied at webhook level)
  exclude:
    namespaces:
      - kube-system
      - monitoring
    labels:
      pandocore.xyz/skip: "true"

Sensitivity Presets

Sensitivity presets map to threshold values, making it easy to tune detection without specifying exact numbers:

Preset Incremental Threshold Cumulative Threshold Use Case
low 0.25 0.60 Noisy workloads, batch jobs
medium 0.15 0.45 General-purpose (default)
high 0.10 0.30 Security-critical services

Setting explicit thresholds overrides the sensitivity preset entirely.

Precedence

PandoCore uses a layered configuration model:

Priority Source Description
1 (highest) CRD Policy Values in PandoCorePolicy win
2 Environment Variables Fallback when no CRD field is set
3 (lowest) Built-in Defaults Hardcoded sane defaults

If the CRD is deleted, the sidecar reverts to env-var-based configuration on the next poll cycle.

Spec Fields

mode

Value Description
monitor Detect and log only — no enforcement action
alert Detect, log, and send alerts to integrations
enforce Full response chain: alert → isolate → terminate
debug Verbose logging for troubleshooting

response

Field Type Description
actions array of strings Ordered response chain: alert, isolate, terminate
escalationDelaySec integer (0–3600) Seconds after isolation before escalating to terminate

features

Field Type Description
mlDetection boolean Enable ML-based anomaly detection
networkAudit boolean Enable network connection auditing
attestation boolean Enable periodic attestation checks

integrations

Field Type Description
slack string Slack incoming webhook URL
pagerduty string PagerDuty routing key

Examples

Production Namespace

apiVersion: pandocore.xyz/v1alpha1
kind: PandoCorePolicy
metadata:
  name: default
  namespace: production
spec:
  mode: enforce
  sensitivity: high
  response:
    actions: [alert, isolate, terminate]
    escalationDelaySec: 60
  features:
    mlDetection: true
    networkAudit: true
  integrations:
    slack: "https://hooks.slack.com/services/T.../B.../xxx"

Staging Namespace (Monitor Only)

apiVersion: pandocore.xyz/v1alpha1
kind: PandoCorePolicy
metadata:
  name: default
  namespace: staging
spec:
  mode: monitor
  sensitivity: low

Custom Thresholds

apiVersion: pandocore.xyz/v1alpha1
kind: PandoCorePolicy
metadata:
  name: default
  namespace: payments
spec:
  mode: enforce
  thresholds:
    incremental: 0.12
    cumulative: 0.35
  response:
    actions: [alert, terminate]
    escalationDelaySec: 30

Verifying

Check that the CRD is registered:

kubectl get crd pandocorepolicies.pandocore.xyz

List policies across namespaces:

kubectl get pcp --all-namespaces

Check sidecar logs for policy pickup:

kubectl logs <pod> -c pando-sidecar | grep "PandoCorePolicy"

Expected output:

PandoCorePolicy CRD found  namespace=production name=default
Applied PandoCorePolicy  mode=enforce resource_version="12345"

Polling Interval

The sidecar polls for policy changes every 30 seconds by default. To customize, set PANDO_POLICY_POLL_INTERVAL_SECS on the sidecar container.

GitOps Integration

Because PandoCorePolicy is a standard Kubernetes resource, it integrates naturally with GitOps workflows:

Next Steps