📘 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:
| Dimension | Examples |
|---|---|
| Subject | User identity, role, department, device, AI agent, service account |
| Action | read, write, invoke, query, delete, approve |
| Resource | API endpoint, database, application, AI model, MCP server |
| Environment/Context | Time 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
- Go to Controls → Templates
- 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)
- Click a template → Use this template
- On page 1: select the Resource and Bouncer this control applies to
- Review and customise the pre-filled conditions (the template provides sensible defaults)
- Click Save → Deploy 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
- Go to Controls → Create Control
- Choose Visual Builder
- 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.
- 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.
- Name: descriptive, e.g.
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 type | When to use |
|---|---|
audit_log | Always — recommended for every control |
notification | Alert a team or user on allow or deny |
approval_gate | Pause the request and require human approval before proceeding |
webhook | Call an external service (SIEM, ticketing, workflow) |
siem_log | Write a structured event to your SIEM |
break_glass_notify | Alert on emergency access bypass |
Troubleshooting: Action did not fire?
- Confirm
BOUNCER_ENABLE_POST_DECISION_ACTIONSis not set tofalsein Bouncer config- Verify the action trigger matches the outcome (
on_allow,on_deny,always)- Check Bouncer logs for
POST_DECISION_ACTIONentries Full reference: Actions Guide
Step 4 — Review, save, deploy
- Click Preview Rego — review the generated Rego policy
- Click Save
- Click Deploy to Sandbox
- 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
- Controls → Create Control → Code Editor
- 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
- Click Validate — checks syntax and basic schema
- Click Save → Deploy 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)
- Go to Settings → Data Sources → Add Data Source
- Choose a provider (Okta, Auth0, Workday, Salesforce, SAP, or Custom)
- Fill in the connection credentials
- Click Test connection → Save
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.readscope- For custom HTTPS sources: verify TLS is valid and the Control Plane can reach the endpoint
Step 2 — Map an attribute (~5 min)
- Open the connected data source → Mappings
- Click Add Mapping
- 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) ordecision_time(checked live — freshest)
- Source attribute: the field name from the provider (e.g.
- 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
- Go to Controls → Simulator
- Click Generate Test Case — it will pre-fill
user.departmentwith a discovered value - Run the simulation and confirm the condition evaluates as expected
Troubleshooting: Attribute resolves as
undefinedin 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
- Go to Controls → Simulator (or open a specific control → Test)
- Click Generate Test Case — the simulator uses semantic schema from your connected data sources to pre-fill a realistic input payload
- Review the generated JSON input and adjust values as needed
- Click Run — view the decision: Allow / Deny and the matched condition path
Step 2 — Replay historical denials
- Click Fetch Last 100 Denials — loads real denied requests from audit history
- Run them against your new or modified control
- 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.departmentwas'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:
- Open the control → Promote to Production
- Confirm the promotion dialog — review the diff if shown
- Wait for the Policy Bridge to sync (typically 5–30 seconds)
- 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:
- Open the control → Version History
- Click the version to restore → Rollback
- 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
Visual Builder Deep Dive
Full reference for condition groups, operators, actions, and context enrichment in the Visual Builder.
View guideControlsControl Scenarios
10 scenario starters: AI governance, financial risk, healthcare, API security, and more.
View guideDataConnect Data Sources
Connect Okta, Workday, SAP, and other providers to power context-aware controls.
View guideTestingSimulator & Testing
Generate test cases, replay denials, and validate controls before promoting to production.
View guide