title: Shadow discovery quickstart description: Deploy a shadow Bouncer with values-shadow.yaml and verify SHADOW_WOULD_DENY telemetry in under 15 minutes. audience: Platform engineers timeEstimate: 15 minutes prerequisites:
- Control Plane reachable in sandbox
- Helm chart available (cc-infra/helm-chart/controlcore)
Shadow discovery quickstart
Deploy Control Core in shadow mode and confirm the Compliance Dashboard receives telemetry. Shadow evaluates controls via OPA but never blocks upstream traffic.
Helm one-liner (Quick Deploy)
From your cluster context, with the Control Core Helm chart checked out:
helm upgrade --install controlcore ./cc-infra/helm-chart/controlcore \
-f values.yaml \
-f values-shadow.yaml \
--set global.shadowPilot.enabled=true
values-shadow.yaml sets BOUNCER_ENFORCEMENT_MODE=shadow on the sandbox Bouncer and enables Integrity pilot / compliance dashboard feature flags. Production Bouncer remains enforce unless you intentionally override it.
Compose alternative:
environment:
BOUNCER_ENFORCEMENT_MODE: shadow
Steps
- Apply the shadow overlay (~2 min) — run the Helm one-liner above (or Compose override).
- Confirm feature flags (~2 min) — Settings → Feature Flags: Integrity pilot mode, Sovereign compliance dashboard, Shadow enforcement mode (Bouncer). The overlay sets these when
global.shadowPilot.enabled=true; verify in UI if flags were customized. - Health checks (~3 min) — see below.
- Send test traffic (~5 min) — route authenticated requests through the sandbox Bouncer against a path with an activated deny control.
- Confirm first shadow event (~2 min) — expect a
SHADOW_WOULD_DENYwithin 60 seconds of traffic.
Health checks
1. Bouncer readiness
kubectl exec deploy/cc-bouncer-sandbox -- wget -qO- http://127.0.0.1:8080/health/ready
# Expected: HTTP 200 / ready payload
kubectl exec deploy/cc-bouncer-sandbox -- printenv BOUNCER_ENFORCEMENT_MODE
# Expected: shadow
2. Policy Bridge (OPAL) sync
# Control Plane OPAL bridge health
curl -s "$PAP_API/health/opal-bridge" -H "Authorization: Bearer $TOKEN" | jq '{status, pending_in_progress_sync_rows, audit_trail}'
# Recent OPAL sync audit (expect OPAL_SYNC_COMPLETED for the sandbox bouncer)
curl -s "$PAP_API/v1/audit?event_type=OPAL_SYNC_COMPLETED&limit=5" \
-H "Authorization: Bearer $TOKEN" | jq '.items[0] | {event_type, bouncer_id, created_at}'
Healthy: status is healthy or degraded with zero stuck pending_in_progress_sync_rows, and a recent OPAL_SYNC_COMPLETED for your Bouncer.
3. First shadow event within 60s
curl -s "$PAP_API/v1/compliance/shadow-telemetry?environment=sandbox" \
-H "Authorization: Bearer $TOKEN" | jq '.items | length'
Or open Compliance & Gaps (/compliance) and filter for SHADOW_WOULD_DENY.
Sample SHADOW_WOULD_DENY JSON
{
"event_type": "SHADOW_WOULD_DENY",
"mode": "shadow",
"evaluation": "would_deny",
"matched_rule": "data.controlcore.wire_cert.allow",
"risk_level": "high",
"details": {
"path": "/api/v1/wires",
"method": "POST",
"decision_id": "dec_01J9EXAMPLE",
"reason": "employment_status not Active or aml_cert expired",
"control_id": "OSFI-B13-IA-WIRE-01",
"upstream_forwarded": true
},
"environment": "sandbox",
"correlation_id": "req_01J9EXAMPLE"
}
| Field | Meaning |
|---|---|
mode | Always shadow for these events |
evaluation | would_deny or would_allow — what enforce would do |
matched_rule | Rego rule path that produced the decision |
risk_level | Severity hint for gap scoring (low / medium / high / critical) |
details | Non-PII context: path, method, control id, reason; upstream_forwarded: true proves shadow never blocked |
Troubleshooting: If shadow telemetry is empty after 60s: (1) confirm
BOUNCER_ENFORCEMENT_MODE=shadowand/health/readyis 200; (2) confirm an activated control would deny the test path; (3) confirmOPAL_SYNC_COMPLETEDso the control bundle is loaded; (4) confirm feature flags expose/compliance. Upstream must still return success — shadow never blocks. See Troubleshooting.
Verification checklist
- Helm one-liner with
values-shadow.yamlandglobal.shadowPilot.enabled=true -
/health/readyreturns 200 -
OPAL_SYNC_COMPLETED(or healthy/health/opal-bridge) for sandbox Bouncer - At least one
SHADOW_WOULD_DENYwithin 60s of test traffic - Upstream API returns 200 for the would-deny path
Next steps: Fingerprint & discover