📘 Controls Manager Guide

Audience: Control authors, compliance officers, security engineers, CIAM administrators Time: ~30 min to complete your first production-ready control from scratch

📌 What is a control?

In Control Core, a control is an authorization rule that decides whether a request is allowed, denied, or requires additional action (such as approval or masking). Controls are the central product concept — everything you build, test, and enforce is a control.

Under the hood, each control is implemented as a Rego policy evaluated in real time by the policy engine. You don't need to write Rego to create controls: the Visual Builder and SCCA generate it automatically. But if you prefer to work directly in code, the Rego editor is always available.

Control lifecycle

Draft → Deployed (Sandbox) → Tested → Promoted (Production)
                ↑                              ↓
           (iterate)                    (rollback if needed)
  • Draft — saved but not enforcing
  • Sandbox — active in the test environment, no impact on production traffic
  • Production — enforcing on live traffic

What a control evaluates

Every control evaluates four dimensions of a request:

DimensionExamples
SubjectUser identity, role, department, device, AI agent, service account
Actionread, write, invoke, query, delete, approve
ResourceAPI endpoint, database, application, AI model, MCP server
Environment/ContextTime of day, location, risk score, business state, threat level

🏗️ Five core flows

Flow 1 — Create a control from a template

The fastest way to get your first control enforcing.

Time: ~5 min

  1. Go to Controls → Templates
  2. Browse the Scenario Starter Catalog — categories include:
    • AI Security and Governance
    • Data Governance and Privacy
    • API Security and Partner Access
    • Financial and Payments Risk Controls
    • Healthcare and Clinical Access
    • Identity, Workforce, and Zero Trust
    • (and more — see All Scenarios)
  3. Click a template → Use this template
  4. On page 1: select the Resource and Bouncer this control applies to
  5. Review and customise the pre-filled conditions (the template provides sensible defaults)
  6. Click SaveDeploy to Sandbox

Troubleshooting: Template not showing expected conditions? The template pre-fills based on the resource type and any PIP attributes already connected. If PIP attributes are missing, connect a data source first — see Connect Data Sources.


Flow 2 — Create a control using the Visual Builder (Wizard)

The Visual Builder is the recommended starting point for control authors who want to define rules without writing Rego.

Time: ~10 min

Step 1 — Create a new control

  1. Go to Controls → Create Control
  2. Choose Visual Builder
  3. Select Resource and Bouncer — this links your control to a specific protected resource. The Policy Bridge will sync this control only to the selected Bouncer(s), not every Bouncer in your environment.
  4. Fill in:
    • Name: descriptive, e.g. finance-read-production-data
    • Description: one sentence explaining intent
    • Environment: Sandbox (always start here)
    • Category: Access Control, Compliance, AI Governance, etc.

Step 2 — Build conditions

Conditions define when the control applies. Use AND/OR groups to compose complex logic:

Group 1 (AND):
  user.department  equals  "Finance"
  user.authenticated  equals  true

Group 2 (AND):
  action  equals  "read"
  resource.data_classification  in  ["internal", "confidential"]

Groups combined with: AND

Builder controls:

  • Add Condition — new attribute check
  • Group conditions — wrap in a group with AND/OR
  • Add Group — parallel logic path (OR between groups = "match any group")
  • Preview Rego — see the generated policy code at any time

Supported operators: equals, not_equals, contains, in, not_in, starts_with, ends_with, greater_than, less_than, regex

Troubleshooting: An attribute is not appearing in the attribute dropdown? The attribute comes from a connected PIP data source. If you don't see user.department, check Settings → Data Sources and confirm the connection is active and synced. See Connect Data Sources.

Step 3 — Configure post-decision actions (optional)

Actions run after the policy decision. They don't change the allow/deny outcome — they add side effects:

Action typeWhen to use
audit_logAlways — recommended for every control
notificationAlert a team or user on allow or deny
approval_gatePause the request and require human approval before proceeding
webhookCall an external service (SIEM, ticketing, workflow)
siem_logWrite a structured event to your SIEM
break_glass_notifyAlert on emergency access bypass

Troubleshooting: Action did not fire?

  • Confirm BOUNCER_ENABLE_POST_DECISION_ACTIONS is not set to false in Bouncer config
  • Verify the action trigger matches the outcome (on_allow, on_deny, always)
  • Check Bouncer logs for POST_DECISION_ACTION entries Full reference: Actions Guide

Step 4 — Review, save, deploy

  1. Click Preview Rego — review the generated Rego policy
  2. Click Save
  3. Click Deploy to Sandbox
  4. Confirm status shows Active

Flow 3 — Create a control using the Rego code editor

For control authors who prefer to write policy logic directly.

Time: ~10 min (assumes Rego familiarity)

Step 1 — Create and select code editor

  1. Controls → Create Control → Code Editor
  2. Select Resource, Bouncer, name, environment (same as Flow 2 Step 1)

Step 2 — Write the control

Minimal working control — allow requests where user has the analyst role:

package controlcore.controls.analyst_read_access

import rego.v1

# All controls must start fail-closed
default allow = false

# Allow: user is authenticated and has the analyst role
allow if {
    input.subject.authenticated == true
    "analyst" in input.subject.roles
    input.action == "read"
}

# Deny reason for explainability
deny_reason := "User does not have the analyst role or action is not read" if {
    not allow
}

Key input fields available in every control:

input.subject.user_id          # authenticated user identifier
input.subject.authenticated    # boolean
input.subject.roles            # array of roles
input.subject.<pip_attribute>  # any mapped PIP attribute (e.g. input.subject.department)
input.action                   # the operation (read, write, delete, etc.)
input.resource.name            # resource name
input.resource.type            # resource type
input.resource.path            # request path (for APIs)
input.environment.time         # ISO timestamp
input.environment.risk_score   # risk score from context

Troubleshooting: Control evaluates to undefined (neither allow nor deny)? The most common cause is a missing or mistyped input field. Add a print() statement to trace:

allow if {
    print("subject:", input.subject)
    input.subject.authenticated == true
}

For Rego debugging patterns, see Rego Guidelines.

Step 3 — Validate and save

  1. Click Validate — checks syntax and basic schema
  2. Click SaveDeploy to Sandbox

Flow 4 — Connect a PIP attribute and use it in a control

PIPs (Policy Information Points) are data sources that provide real context about subjects and resources — user department, employment status, customer tier, resource sensitivity, and more.

Time: ~15 min (first data source)

Step 1 — Connect a data source (~8 min)

  1. Go to Settings → Data Sources → Add Data Source
  2. Choose a provider (Okta, Auth0, Workday, Salesforce, SAP, or Custom)
  3. Fill in the connection credentials
  4. Click Test connectionSave

Troubleshooting: Connection test fails?

  • Check the credentials have read-only access to the identity attributes you need
  • For Okta: the API token needs okta.users.read scope
  • For custom HTTPS sources: verify TLS is valid and the Control Plane can reach the endpoint

Step 2 — Map an attribute (~5 min)

  1. Open the connected data source → Mappings
  2. Click Add Mapping
  3. Fill in:
    • Source attribute: the field name from the provider (e.g. profile.department)
    • Target attribute: the name your controls will use (e.g. user.department)
    • Runtime tier: snapshot (checked at sync — fastest) or decision_time (checked live — freshest)
  4. Save

Runtime tier in plain language:

  • snapshot — attribute is fetched at the last scheduled sync. Fast. May be minutes old.
  • warm — preloaded and refreshed on short intervals. Good for frequently-changing values.
  • decision_time — looked up live on every request. Always fresh. Adds ~10–20ms latency.
  • event_driven — refreshed automatically when the source notifies Control Core of a change.

Step 3 — Use the attribute in a control

In the Visual Builder, the mapped attribute (user.department) now appears in the attribute dropdown:

Condition: user.department  equals  "Finance"

Or in Rego:

allow if {
    input.subject.department == "Finance"
    input.action == "read"
}

Step 4 — Verify the attribute is resolving

  1. Go to Controls → Simulator
  2. Click Generate Test Case — it will pre-fill user.department with a discovered value
  3. Run the simulation and confirm the condition evaluates as expected

Troubleshooting: Attribute resolves as undefined in the simulator?

  • Check the last sync timestamp in Settings → Data Sources
  • Click Sync now to force a fresh pull
  • Confirm the mapping target attribute exactly matches what is used in the condition Full reference: PIP Getting Started

Flow 5 — Test, simulate, and promote a control

Never promote a control to production without testing it in sandbox first.

Time: ~10 min

Step 1 — Run the Simulator

  1. Go to Controls → Simulator (or open a specific control → Test)
  2. Click Generate Test Case — the simulator uses semantic schema from your connected data sources to pre-fill a realistic input payload
  3. Review the generated JSON input and adjust values as needed
  4. Click Run — view the decision: Allow / Deny and the matched condition path

Step 2 — Replay historical denials

  1. Click Fetch Last 100 Denials — loads real denied requests from audit history
  2. Run them against your new or modified control
  3. Review the traffic-light output:
    • 🟢 Would Allow — the control would let this through
    • 🔴 Would Deny — the control would block this
    • No Match — the control does not apply to this request

Use this to catch regressions before promoting.

Step 3 — Review deny explanations

For any DENY result, click Explain to see a natural-language summary:

"Request denied because user.department was 'Engineering' but the control requires 'Finance'."

Troubleshooting: "Generate Test Case" button is greyed out?

  • Ensure the control has at least one valid condition with an input attribute
  • Confirm at least one data source has synced (Settings → Data Sources → check last sync)
  • If still failing: check browser network panel for POST /v1/pis/policies/{id}/generate-test-case

Step 4 — Promote to Production

When satisfied with sandbox test results:

  1. Open the control → Promote to Production
  2. Confirm the promotion dialog — review the diff if shown
  3. Wait for the Policy Bridge to sync (typically 5–30 seconds)
  4. Verify in Settings → PEPs that the Production Bouncer shows an updated sync timestamp

Troubleshooting: Promote button is disabled?

  • Confirm License Server connection is active (Settings → General → Telemetry)
  • Ensure subscription tier is valid — see License Management

🗂️ Control versioning and rollback

Every promoted control creates a version entry. To rollback:

  1. Open the control → Version History
  2. Click the version to restore → Rollback
  3. Confirm — the previous version redeploys immediately

📌 Monitoring and ongoing management

  • Dashboard — see Controls Deployed, Authorisation Requests, Access Denials at a glance
  • Audit Logs — full decision trace per request: subject, resource, action, outcome, matched control
  • Control Map — visual overview of which controls protect which resources → Control Map
  • Anomalous Activity widget — security-relevant patterns flagged in last 24 hours

📌 Next steps