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.
- Create a
pando-policy.yamlfile - Run
kubectl apply -f pando-policy.yaml - 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:
- Store policy YAML in your Git repository alongside application manifests
- Review policy changes in pull requests
- Apply via ArgoCD, Flux, or any
kubectl applypipeline - Track policy history with
git log
Next Steps
- Configuration — Full env var and Helm reference
- Operating Modes — Understand monitor vs enforce
- Admission Webhook — Per-pod annotation overrides