Governing automations
Each automation you govern gets one small ControlLayer check. The default is always enforce - an automation is only suppressed while an active window explicitly lists its object.
ControlLayer installs as a managed package under the itcl namespace, so every example on this page carries it. In a formula the prefix appears twice - once on the custom setting and once on the field:
$Setup.itcl__vControl__c.itcl__Objects__c
Prefixing only the object is the most common mistake, and Salesforce rejects the formula when you save it. In Apex the namespace is a dot prefix on the class instead: itcl.automationBypass and itcl.bypassCategory.
ControlLayer maintains one enforcement setting per category - itcl__vControl__c (validation rules), itcl__fControl__c (flows), itcl__tControl__c (triggers). Each holds a semicolon-wrapped list of bypassed object API names in itcl__Objects__c (e.g. ;Account;Contact;), resolved through the org → profile → user hierarchy. Your check tests for the object's exact token. The wrapping semicolons make matching safe: ;Account; can never false-match Account_Plan__c. Matching is case-sensitive - use the exact API name.
Validation Rules
Wrap the rule's own logic in an AND() whose first clause is the ControlLayer check. The token is the object the rule lives on - it's the only per-rule variation.
AND(
NOT(CONTAINS($Setup.itcl__vControl__c.itcl__Objects__c, ";Account;")),
ISBLANK(Phone) /* the rule's original logic, unchanged */
)
Footprint: one merge field and one function call - well under a hundred characters of the 3,900-character formula limit.
Record-triggered Flows
Add the same clause to the flow's entry condition (formula). When a bypass is active the flow never starts - zero elements consumed.
AND(
NOT(CONTAINS({!$Setup.itcl__fControl__c.itcl__Objects__c}, ";Lead;")),
/* the flow's own entry logic */
)
Autolaunched & Screen Flows
Where entry-condition formulas aren't available, use the packaged invocable action "Is Automation Bypassed" (action category ControlLayer) followed by a Decision element at the top of the flow.
| Input / output | Value |
|---|---|
| Input: Category | Validation Rule, Flow, or Trigger - typed exactly, as a literal string |
| Input: Object API Name | e.g. Lead |
| Output: Is Bypassed | Boolean - route to an early exit when true |
A flow has no way to reference an Apex constant, so the category here is a string you type. Spell it exactly as shown - the action throws on an unrecognized category rather than guessing.
Apex Triggers
One guard line at the top of the handler:
if (itcl.automationBypass.isObjectBypassed(itcl.bypassCategory.APEX_TRIGGER, 'Account')) {
return; // ControlLayer: governed automation exits before doing any work
}
isObjectBypassed(category, objectApiName) resolves the running user's hierarchy via the platform's cached settings access - no SOQL, safe at any trigger volume. An unknown category string throws an exception on purpose: a typo should fail loudly in your first test run, not silently enforce forever.
Pass the category as an itcl.bypassCategory constant rather than a bare string, so a misspelling fails when you compile instead of when the trigger runs:
| Constant | Value | Governs |
|---|---|---|
itcl.bypassCategory.VALIDATION_RULE | Validation Rule | Validation rules |
itcl.bypassCategory.FLOW | Flow | Flows |
itcl.bypassCategory.APEX_TRIGGER | Trigger | Apex triggers |
The trigger constant is named APEX_TRIGGER, not TRIGGER, because TRIGGER is a reserved Apex keyword and cannot be used as an identifier. Its value is still 'Trigger' - only the constant's name differs, and only for this one category.
Formulas have no access to Apex constants. A validation rule or a flow entry condition can only compare text, so those examples match on the literal ";Account;" token and always will. Apex is the one place where the category can be a compile-checked constant, so that is the one place this page uses one. The difference is deliberate, not an inconsistency.
Behaviors worth knowing
- Inside Apex tests, governed validation rules and flows do not block. Formula-based checks read a per-transaction snapshot that test isolation hides, and the platform skips the formula entirely - so your test suites are never blocked by governed rules. Apex-governed triggers remain enforced in tests. This is platform behavior, documented so it never surprises you.
- The default is enforce. A missing setting row, a blank value, or an object that simply isn't in the list all evaluate to “not bypassed”. If ControlLayer is uninstalled or its engine stops, your automations go back to running normally - the failure direction is always toward enforcement, never toward silent suppression.
- Class names are lowerCamel. The runtime API is
itcl.automationBypassand the constants class isitcl.bypassCategory- both start with a lowercase letter. Apex itself is case-insensitive here, but the packaged spelling is what this documentation and the shipped demo code use. - Never edit the enforcement settings directly. They are recomputed from active windows and reconciled every cycle; manual edits are corrected automatically.
- Adopt incrementally. Ungoverned automations are completely unaffected. Start with the rules that block data work most often.