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