🔒 Policy and Control Plane Hardening

Control Core applies hardening by default to protect the Control Plane, policy management, GitHub integration, and Bouncer connectivity. This behavior is always on and is not configurable. Understanding what it does helps you avoid unexpected 401/403 responses and authorization denials, and makes troubleshooting straightforward.

🔒 What Hardening Protects

Hardening enforces authentication and authorization at several layers:

Control Plane (Policy Administration API)

  • Policy and settings mutations require an authenticated user with admin role (require_policy_admin). Only admins can create, update, or delete policies and change GitHub or general settings.
  • Bouncer-facing operations (heartbeat, policy sync, registration, activation) require a valid Bouncer API key (Bearer or X-API-Key). There is no “no API key” bypass.
  • When SPIRE/Work ID is enabled, the Control Plane also validates SPIFFE identity for Bouncer traffic. Requests without a valid workload identity are rejected when that mode is in use.

Bouncer

  • Management and sync APIs (e.g. policy sync, context, metrics, policy cache) are behind API key middleware. Only requests that present the configured Bouncer API key (Bearer or X-API-Key) are accepted.
  • The Bouncer does not expose these endpoints without authentication.

Bouncer plugin (Sidecar / Network Bouncer)

  • Deny-by-default: If there is no authorization policy, or the policy is missing, undefined, or errors during evaluation, the request is denied. There are no “public endpoints” or “allow if no policy” options.
  • Ext authz / ext_proc use failure_mode_allow: false: policy evaluation failures result in deny, not allow.

Together, these measures protect:

  • Policy and GitHub/settings from non-admin users.
  • Bouncer ↔ Control Plane communication with API keys (and optionally SPIRE).
  • Traffic through the Bouncer with strict, policy-driven authorization and no silent fallback to allow.

🛠️ Potential Effects and Issues

You may see the following as a result of hardening:

EffectCause
401 Unauthorized on Control Plane APIMissing or invalid API key, or (when SPIRE is used) missing or invalid SPIFFE identity.
403 Forbidden on policy/settings changesUser is not an admin; only admins can mutate policies and settings.
403 Forbidden on Bouncer management endpointsWrong or missing Bouncer API key.
Access denied on application traffic through BouncerNo policy loaded for the path, policy evaluation error, or policy explicitly denies. Deny-by-default and failure_mode_allow=false mean “no policy” or “error” → deny.
Heartbeat or registration failuresBouncer API key not set, incorrect, or (with SPIRE) SPIRE/SPIFFE headers or identity not valid.
Policies not syncing to BouncerBouncer cannot authenticate to Control Plane (API key or SPIRE), or network/connectivity issues.

🛠️ Troubleshooting

Use the following checks in the same way you would for other Control Core issues (see the Troubleshooting Guide and Admin Troubleshooting).

401/403 on Control Plane API

  1. Confirm caller identity
    • For user-driven requests (e.g. Policy Builder, settings): ensure the user is logged in and has admin role for policy/settings changes.
    • For Bouncer requests (heartbeat, Policy Bridge, registration): ensure the request includes a valid Bouncer API key (Bearer token or X-API-Key header). There is no bypass for “no API key.”
  2. If SPIRE/Work ID is enabled
    • Verify the Bouncer has a valid SPIFFE identity and that the Control Plane is receiving and validating the expected identity (e.g. in logs or middleware). Missing or wrong SPIFFE identity will result in 401/403.
  3. Check API key configuration
    • Control Plane: ensure Bouncer API keys are created and assigned to the correct Bouncer/resource.
    • Bouncer: ensure CONTROL_PLANE_API_KEY (or equivalent) matches the key configured for that Bouncer on the Control Plane. Check for typos, extra spaces, or wrong environment (e.g. test vs production key).

Access Denied at Bouncer (Enforcement)

  1. Policy existence and scope
    • Ensure at least one enabled policy applies to the resource/path. With deny-by-default, no policy means deny.
    • In the Control Plane, confirm the policy is bound to the correct resource and Bouncer and is in the right environment (e.g. sandbox vs production).
  2. Policy evaluation errors
    • Check Bouncer logs for policy evaluation errors (e.g. Rego runtime errors, missing data). With failure_mode_allow: false, any evaluation failure results in deny.
  3. Path and policy alignment
    • Verify the request path is in scope for your Rego rules (e.g. path whitelists or prefix rules). See PBAC Best Practices for path-in-policy patterns.

Heartbeat / Registration / Sync Failures

  1. Bouncer API key
    • Ensure the Bouncer is configured with the correct Control Plane API key and that it is sent on heartbeat, policy sync, and registration calls (Bearer or X-API-Key as configured).
  2. SPIRE/Work ID
    • If enabled, confirm the Bouncer has completed attestation and has a valid SPIFFE ID, and that the Control Plane accepts that identity. Check SPIRE agent logs and Control Plane auth logs.
  3. Network and connectivity
    • From the Bouncer host, verify reachability to the Control Plane (e.g. curl to health and API endpoints). Check firewalls, proxies, and TLS if applicable.
  4. Control Plane logs
    • Look for 401/403 or “unauthorized”/“forbidden” for the Bouncer’s IP or identity; that usually indicates wrong or missing API key or SPIRE identity.

Quick Reference

SymptomWhat to check
401/403 when changing policies or settingsUser has admin role; token/session is valid.
401/403 on Bouncer → Control Plane callsBouncer API key present and correct; if SPIRE is on, SPIFFE identity valid.
All requests denied through BouncerPolicy exists, is enabled, and applies to the path; no Rego errors in logs.
Policy evaluation error → denyFix Rego or data; ensure no runtime errors (see Bouncer logs).
Heartbeat/sync/registration failsAPI key and (if used) SPIRE identity; network and Control Plane logs.

For more general diagnostics, see the Troubleshooting Guide. For admin-specific issues (settings, Bouncer linking, policies not enforcing), see Admin Troubleshooting.