Apex security firewall for AI agents

The enforcement layer between AI agents and your Salesforce data.

Agentforce, MCP-connected assistants, and custom LLM integrations all end up calling the same Apex actions. AgentGuard wraps them in one line and treats every agent-issued call as untrusted input until it clears five gates — schema, access, rate, rollback, audit.

5enforcement gates
67unit tests
0external dependencies
MITlicensed

The problem

Three failure modes stop security teams from saying yes

Existing Salesforce controls operate at other layers — the Einstein Trust Layer governs prompts, Agentforce Command Center reports outcomes after the fact. Neither enforces anything at the moment an Apex action actually executes.

Spoofing / tampering

Prompt injection

An instruction hidden in a record, email, or knowledge article causes an agent to issue an action nobody asked for.

Disclosure

CRUD/FLS bypass

Apex invocables run in system context by default — an agent reads or mutates fields its requesting user was never permissioned to touch.

Repudiation / DoS

Unaudited mutation

A misbehaving agent fires DML in a loop with no throttle, no rollback boundary, and no real-time record of what it did.

How it works

Every wrapped call passes through the same chain — there is no bypass path

Policies are declarative. A Guard_Policy__mdt record per action defines schema contracts, rate budgets, allowed profiles/permission sets, and record ceilings — tuned without an Apex deployment.

01

SchemaValidator

Validates the raw payload against the policy's declared JSON schema contract before anything else runs. Unknown keys, missing required fields, and type mismatches are rejected outright.

Defends against — Tampering: a payload reshaped into a bulk or out-of-contract mutation.

02

AccessGate

Evaluates CRUD/FLS in the real running-user context with WITH USER_MODE and Security.stripInaccessible() — never an elevated or claimed context. Enforces profile and permission-set scoping.

Defends against — Spoofing & information disclosure: an agent claiming higher privilege, or reading fields the user can't see.

03

RateLimiter

Sliding-window budget per user, per action, backed by Platform Cache. Falls back to allow-and-flag if the cache partition is unavailable, so a cache outage degrades to logging rather than an outright deny.

Defends against — Denial of service: a flooded action exhausting downstream limits.

04

RollbackGuard

Opens a Savepoint and enforces a hard ceiling on records-per-call before your business logic runs. Any exception mid-execution rolls back atomically — nothing partial survives.

Defends against — Elevation of privilege: a partial bulk mutation leaving inconsistent state.

05

AuditPublisher

Every decision from every gate — ALLOW, BLOCK, or THROTTLED — publishes as an AgentGuard_Audit__e Platform Event, outside the transaction boundary, so the record survives even a rollback.

Defends against — Repudiation: a destructive call with no record of what happened.

Design guarantees

Restrictive by default, fails closed, one line to integrate

Fail closed

Any exception inside a gate is a BLOCK, never an ALLOW.

Restrictive by default

Every policy field defaults to its most restrictive safe value; nothing is permitted unless explicitly configured.

Running-user context only

Access checks run WITH USER_MODE against the real user — never an elevated or claimed context.

Audit survives rollback

Decisions publish as Platform Events, outside the transaction's rollback boundary.

One-line integration

"Integrated correctly" and "integrated at all" are the same thing — one facade, per-gate toggles via policy metadata.

Quick start

Set up in four steps

STEP 01

Authenticate & scratch org

sf org login web \ --set-default-dev-hub sf org create scratch \ --alias agentguard-dev
STEP 02

Deploy metadata

sf project deploy start \ --target-org agentguard-dev
STEP 03

Create the cache partition

Setup → Platform Cache → New Partition → name: AgentGuard
STEP 04

Run the test suite

sf apex run test \ --code-coverage \ --wait 30

Wrap an existing invocable

One check before your business logic runs — validated, access-checked, throttled, inside a Savepoint boundary, and audited.

Full walkthrough with troubleshooting and a worked example: the Getting Started section of the guide.

@InvocableMethod(label='Update Account Territory')
public static List<Result> execute(List<Request> requests) {

  GuardResult check = AgentGuard.wrap(
    'UpdateAccountTerritory',
    JSON.serialize(requests)
  );

  if (!check.isAllowed) {
    throw new AgentGuard.BlockedException(
      check.reason, check.decision, check.gateName
    );
  }

  return YourBusinessLogic.execute(requests); // your existing code, unchanged
}

Threat coverage

Mapped to STRIDE, not marketing categories

STRIDE category Mitigating component
Spoofing — agent claims a higher-privileged context AccessGate evaluates against the real running-user context only
Tampering — injected payload reshaped into bulk / out-of-contract mutation SchemaValidator rejects payloads violating the declared contract
Repudiation — destructive call with no record AuditPublisher logs every decision with actor, payload hash, timestamp
Information disclosure — fields the user cannot see AccessGate strips/blocks inaccessible fields on read paths
Denial of service — flooded actions exhausting limits RateLimiter sliding-window per-agent/per-action budgets
Elevation of privilege — partial bulk mutations leave inconsistent state RollbackGuard Savepoint boundary and record ceiling

Full model, explicit non-goals, and the maintained risk register live in the Threat Model & Compliance section of the guide.

Honest scope

What AgentGuard SF does not do

  • Not a prompt-level control. It does not mask data sent to an LLM — pair it with the Einstein Trust Layer at the prompt boundary.
  • Not a scanner. It governs only calls that opt in via AgentGuard.wrap().
  • No semantic injection detection. Enforcement is structural, not a content classifier.
  • Not durable rate-limit state. Platform Cache counters can reset on eviction; pair with Shield Event Monitoring for a durable audit trail.
  • No cross-org policy sync in v1. Policies deploy per-org like any metadata.

Read the full guide before your first deploy

What it is, how to set it up, and how to use it — end to end.