Agentforce deterministic guardrails
An Agentforce agent acts on behalf of whoever prompts it, and the agent itself cannot be trusted to self-limit. The only reliable control is a deterministic guardrail: a check enforced in the code and configuration behind the agent, not a prompt instruction the model may or may not follow. Vulkro inspects the Apex classes and actions an agent can reach and flags the places where the deterministic guardrail is missing.
These findings sit alongside the broader Agentforce detector family but focus specifically on the enforcement boundary between an agent action and the data it touches.
SF-AGENT-GUARD-001: agent-reachable Apex carrying elevated permissions
Triggers when an Apex class reachable from an agent action carries an elevated permission such as Modify All, View All, or Author Apex (granted through its assigned profile or permission set).
Why it matters: the agent runs the class with those elevated permissions. Modify All or View All on an agent-reachable class means any user who can prompt the agent reaches data across the entire org, bypassing the record-visibility model entirely.
How to fix: remove the elevated permission from the principal behind the agent-reachable class, and grant only the specific object and field access the action legitimately needs.
SF-AGENT-GUARD-002: agent action with unconstrained object scope
Triggers when an agent action operates over an unconstrained object scope, querying or modifying records without a bounding filter that limits the action to the records the caller is entitled to.
Why it matters: an unconstrained scope lets the agent reach every record of the object type, not just the records relevant to the verified caller. That is the broad-read shape behind agent data-leak incidents.
How to fix: constrain the action to a bounded set of records (for example by owner, by a verified customer identifier, or by an explicit allowlisted filter) so the agent can only act within the caller's entitlement.
SF-AGENT-GUARD-003: missing deterministic guardrail or sharing enforcement
Triggers when an agent-reachable code path has no deterministic guardrail:
no with sharing enforcement and no explicit authorization check between
the agent action and the data it reaches.
Why it matters: with no deterministic guardrail, the only thing standing between the agent and the data is the model's behavior, which is not an authorization control. The agent runs in the implicit system context and sees records the caller never could.
How to fix: enforce with sharing on the agent-reachable class and add an
explicit authorization check (verify the caller's entitlement before the
action proceeds). The guardrail must live in code, not in the prompt.
SF-AGENT-FLS-001: agent-invoked DML with no CRUD check
Triggers when an agent-invoked code path performs DML (insert, update,
delete, or upsert) without a CRUD permission check (no
isCreateable / isUpdateable / isDeletable and no user-mode DML
enforcement).
Why it matters: agent-invoked DML with no CRUD check lets the agent write or delete records the caller has no permission to modify, because the write runs in system context with no object-level gate.
How to fix: enforce CRUD before the DML (check the object-level permission or run the DML in user mode) so the write respects the caller's object permissions.
SF-AGENT-FLS-002: agent-invoked SOQL with no FLS enforcement
Triggers when an agent-invoked SOQL query returns fields without
field-level security enforcement (no user-mode read, no
Security.stripInaccessible, and no per-field accessibility check).
Why it matters: agent-invoked SOQL with no FLS enforcement returns restricted field values to the agent context, so the agent can surface fields the caller is not permitted to see.
How to fix: enforce field-level security on the read (run the query in user mode or strip inaccessible fields before the values reach the agent) so the agent only ever sees fields the caller is entitled to.