For Salesforce · Agentforce 360 · Agentforce Builder · Flow & Apex actions · MuleSoft Agent Fabric · MCP

Every Agentforce action,
independently judged before it executes.

Three CRM actions below are shaped exactly as they leave an Agentforce agent — an Apex invocable action, a Flow record change, an MCP tool call — and each one goes through the live Veridect system on this page. On your side the integration is one Apex class, one Flow element, or a URL change in the MCP connection. Behind it is the whole control plane: consensus from frontier models across independent vendors, deterministic policy classes, risk routing, a hash-chained ledger, and an Ed25519-signed decision record you can verify right here.

Open the full live tour
3 seams
an Apex action, a Flow element, or one MCP URL — your agents, topics, instructions and models stay exactly as they are
1 judgment
POST /pre-action — behind every path (the MCP gateway makes that call for you); the answer is a verdict plus a signed record
1 record each
every decision — pass, hold or refusal — is a signed record, exportable as newline-delimited JSON beside your event monitoring
0 trust required
every decision re-derives from its recorded inputs and verifies against a published key — try it below
Where it sits

Between the agent’s plan and the record change.

Salesforce runs the agent: Agentforce Builder defines topics and instructions, Agent Script shapes the behaviour, Data 360 supplies the context, and the agent acts through Flow, Apex, MuleSoft APIs and MCP tools. Veridect sits at the one moment none of those were built to own: the instant before an action with consequences executes — a case closed, an opportunity changed, a contact’s details rewritten, a credit issued — when an independent judgment — not the model that proposed the action, not the platform that hosts it — decides whether it goes, waits for a person, or never happens, and signs the record either way.

Your agent on Agentforce

Proposes an action

  • Service, sales and commerce agents proposing record changes and customer actions
  • Flow and Apex invocable actions that create, update, close, credit or send
  • Any MCP tool the native MCP client reaches — on Salesforce or outside it
Veridect · live control plane

Judges it before it runs

  • Deterministic scope check against the agent’s configured authority
  • Policy classes in code — money thresholds, protected data, regulated data, cumulative exposure
  • Multi-vendor model consensus with calibrated confidence and a dissent register
  • Risk routing: greenlight, escalate to a named human queue, or block
  • Hash-chained, Ed25519-signed record — written whether it passes or not
Outcome

Three doors, one record

greenlightthe record change runs or the tool call is forwarded; the verdict and record id travel with it
escalateheld for a person in the queue the policy names — the action returns the verdict to the agent, the record stays as it was
blocknever executes — and the refusal is on the ledger too
Three thin paths

The integration is thin. The system behind it is not.

Each path maps the call your agent was already making onto one judgment — POST /api/ai/consensus/pre-action, made by your Apex action, your Flow, or the MCP gateway on your behalf: the verb, the target object, the fields, which agent is asking, and what that agent is authorized to do. Nothing about the agent, the topic, the model or the instructions changes. The verdict decides whether the original action proceeds.

PATH 01 · APEX · INVOCABLE ACTION

A judgment at the top of the action the agent already calls

Agentforce agents act through invocable Apex. One governed @InvocableMethod takes the object, the record and the fields, asks Veridect first, and performs the DML only for the greenlit rows — all callouts before any DML, as Apex requires. It returns the verdict and the record id to the agent either way, so the agent can tell the customer the change is waiting for a person instead of pretending it happened. One class covers every object and every agent that uses the action.

~35 lines · one Apex class for every object · one Named Credential

Fail-closed by construction: a callout exception, a timeout or a malformed response never reaches the DML branch. The Veridect key lives in a Named Credential, never in code or in the agent’s instructions.

// Apex invocable action "Governed Update" — the only path from an agent to this DML, for any object
public with sharing class GovernedUpdate {
  public class Req { @InvocableVariable public String objectApiName; @InvocableVariable public Id recordId;
                     @InvocableVariable public String fieldsJson;      // {"Status":"Escalated","Priority":"High"}
                     @InvocableVariable public String agentName; @InvocableVariable public String agentScope; }
  public class Res { @InvocableVariable public String verdict; @InvocableVariable public String recordId; @InvocableVariable public Boolean executed; }

  @InvocableMethod(label='Update Record (governed)' callout=true)
  public static List<Res> run(List<Req> reqs) {
    List<Res> out = new List<Res>(); List<SObject> toUpdate = new List<SObject>();
    for (Req r : reqs) {                                                   // pass 1: every callout, no DML yet (Apex forbids callouts after DML)
      Res res = new Res(); res.verdict = 'unavailable'; res.executed = false;   // closed until proven open
      Map<String,Object> fields = (Map<String,Object>) JSON.deserializeUntyped(r.fieldsJson);
      try {
        HttpRequest h = new HttpRequest();
        h.setEndpoint('callout:Veridect/api/ai/consensus/pre-action');          // Named Credential holds the key
        h.setMethod('POST'); h.setHeader('Content-Type', 'application/json'); h.setTimeout(60000);
        h.setBody(JSON.serialize(new Map<String,Object>{
          'action' => 'update_' + r.objectApiName.toLowerCase(), 'target' => 'salesforce:' + r.objectApiName.toLowerCase(),
          'parameters' => fields,                                                     // field names drive the policy classes
          'callingAgent' => r.agentName, 'callingAgentScope' => r.agentScope,     // its configured authority, in words
          'department' => 'customer_service' }));
        Map<String,Object> d = (Map<String,Object>) JSON.deserializeUntyped(new Http().send(h).getBody());
        res.verdict = (String) d.get('verdict'); res.recordId = (String) d.get('auditBundleId');
      } catch (Exception e) { /* network, timeout, parse: all stay closed */ }
      if (res.verdict == 'greenlight') {
        SObject rec = Schema.getGlobalDescribe().get(r.objectApiName).newSObject(r.recordId);
        for (String f : fields.keySet()) rec.put(f, fields.get(f));
        rec.put('Veridect_Record__c', res.recordId);                              // the record id travels on the row
        toUpdate.add(rec); res.executed = true;
      }
      out.add(res);
    }
    if (!toUpdate.isEmpty()) update toUpdate;                                   // pass 2: one DML, only the greenlit rows
    return out;
  }
}
PATH 02 · FLOW · DECISION ELEMENT

A decision before the record element, no code

Where the agent’s action is a Flow, add an HTTP Callout action to Veridect and a Decision element in front of the Create, Update or Delete Records element. The record element runs only on the greenlight path; the other path writes the verdict and the record id back to the agent and notifies the queue. Flow builders change nothing about the agent.

2 elements · one callout + one decision · no code

Where the authority lives: the scope string is the agent’s configured authority. A read-only pipeline-summary agent that proposes to change an opportunity is a categorical no-authority action — the deterministic layer blocks it before any model is asked to weigh in. Watch it below. The policy classes work over field names; send values only for the fields your policy needs.

# Agentforce → Flow action "Update Opportunity (governed)" — schematic; the same two elements fit any object
Start: invoked by the agent (inputs: opportunityId, newStage, agentName, agentScope)

Action: HTTP Callout → Veridect pre-action      # External Service on the Named Credential
  body:
    action:            "update_opportunity"
    target:            "salesforce:opportunity"
    parameters:        { opportunity_id: {!opportunityId}, stage: {!newStage} }
    callingAgent:      {!agentName}
    callingAgentScope: {!agentScope}                   # its configured authority, in words
  timeout: 60 s

Decision: {!Veridect.verdict} equals "greenlight"   # a faulted callout never satisfies this
  yes → Update Records: Opportunity.StageName = {!newStage}; Opportunity.Veridect_Record__c = {!Veridect.auditBundleId}
  no  → Assign: outcome = "Not executed — Veridect " + {!Veridect.verdict} + " · record " + {!Veridect.auditBundleId}
        Action: notify the queue the policy named; return outcome to the agent
PATH 03 · MCP · BOTH DIRECTIONS

One MCP URL, whichever way the call flows

Agentforce ships a native MCP client — admins register external MCP servers, including MuleSoft MCP servers, and allowlist their tools. Register the real server as a Veridect upstream once and give Agentforce the Veridect gateway URL instead. Every tools/call is judged in flight; tools/list, initialize and everything else pass straight through. A refused call is never forwarded. Agentforce capabilities exposed as an MCP server to outside agents can sit behind the same gateway, the other way round.

0 lines of agent code · one registration, one URL

Identity on the wire: the agent’s identity, session and business context ride in params._meta["veridect/…"] — unsigned, that is the caller’s own claim, and the decision record marks it as such; a tenant can require a signed Ed25519 identity envelope on every call, and an unsigned call is then refused inside the protocol. Both outcomes run live below.

# 1) once — register the real tool server as an upstream (admin call)
POST /api/ai/consensus/mcp/upstreams/{tenant}
{ "upstreamId": "mulesoft-orders-prod", "url": "https://<your-mulesoft-mcp-server>/mcp", "enabled": true }

# 2a) Agentforce → external tools: the server URL in the MCP connection (Setup → MCP for Agentforce)
before:  https://<your-mulesoft-mcp-server>/mcp
after:   https://<your-veridect-host>/api/mcp/gateway/mulesoft-orders-prod

# 2b) outside agents → Agentforce capabilities exposed over MCP: the same change, the other way round
before:  https://<your-agentforce-mcp-server>/mcp
after:   https://<your-veridect-host>/api/mcp/gateway/agentforce-mcp-prod
HEADERS = {
  "Authorization":            "Bearer <VERIDECT_API_KEY>",            # your Veridect tenant
  "X-Upstream-Authorization": "Bearer <Salesforce or MuleSoft OAuth token>",   # forwarded to the upstream as Authorization
}

# 3) what the agent sees on a greenlight: the upstream's own result, plus
#    result._meta["veridect/verdict"] and result._meta["veridect/bundleId"]
#    on escalate / block: a JSON-RPC error (-32003 / -32004) carrying the
#    verdict and the record id — and the server never receives the call.
Run it live

Four Agentforce-shaped actions, through the live system, now.

Each card sends the exact request the Apex action, the Flow callout, or the MCP connection would send, to the live Veridect system on a shared sandbox tenant. The verdicts are real multi-model decisions made while you wait; the records are written to the ledger and signed; the Verify button re-derives the verdict from the recorded inputs and checks the signature against the published key. Expected outcomes are stated in advance — the engine decides.

Ready. Each decision takes a few seconds while the model roster deliberates.
LIVE 01 · PATH 01 · APEX ACTION

Escalate a case to Tier 2 and raise its priority

A service agent proposes update_case on an open billing case: status escalated, priority high, owner the Tier 2 queue, with a note. Its configured authority: “may read cases and may update case status, priority and owner.”

Expected: greenlight — inside authority, no policy class fires, the roster agrees. The Apex method performs the DML and the record id lands on the case.

Waiting. Request shape: the Apex action’s body, verbatim.
LIVE 02 · PATH 02 · FLOW DECISION

A read-only pipeline agent tries to close an opportunity

A pipeline-summary agent proposes update_opportunity on a late-stage deal: stage set to Closed Won and the close date pulled into this quarter, after reading an email thread it judged conclusive. Its configured authority: “read-only: may read opportunities, accounts and activity history to draft pipeline summaries.”

Expected: block — a read-only agent proposing a record change is a categorical no-authority action; the deterministic scope check decides, the models are consulted for the record, and the Flow’s decision element never reaches the record element.

Waiting. Request shape: the Flow callout’s body, verbatim.
LIVE 03 · PATH 01 · APEX ACTION

Rewrite a contact’s phone and email after a verified request

A service agent, inside its authority (“may read contacts and may update contact details after identity verification”), calls update_contact for a verified caller with a new phone_number and email_address.

Expected: escalate — the deterministic protected_personal_data_modification policy class fires on the field names alone — the values are never inspected — and routes the action to the queue the policy names. Authorized but consequential actions escalate to a person; they are never silently blocked and never silently allowed.

Waiting. Request shape: the Apex action’s body, verbatim.
LIVE 04 · PATH 03 · MCP

The same tools/call, two tenants, two outcomes

A JSON-RPC tools/call for lookup_policy_limit goes through the live Veridect MCP gateway to a sample tool server that counts what it actually receives — the call an Agentforce MCP connection would make. First on the shared sandbox tenant; then on a tenant that requires a signed identity envelope, sent without one.

Expected: first call forwarded, the tool’s own hit counter goes up by one and the result carries _meta["veridect/bundleId"]; second call refused inside the protocol (-32004 identity_not_presented), counter unchanged, refusal on the ledger.

Waiting. Request shape: JSON-RPC 2.0, verbatim.

What on this page is live, and what is illustrative

Live: every verdict, confidence, dissent register, policy class, escalation route, ledger write, hash chain, Ed25519 signature, MCP forwarding decision and verification result above comes from the production Veridect system on a shared sandbox tenant — the same endpoints an integrator calls. The consensus roster is four frontier providers from independent vendors with a decisive-verdict early stop, so a decision on this surface typically records three; the models are named in each record’s dissent register. The protected-data classes are this sandbox tenant’s policy; in your tenant every threshold is yours.

Illustrative: the agent side. No Agentforce agent, Flow or Apex transaction executes from this page; each card sends the exact request the Apex action, the Flow callout or the MCP connection would send, so what you watch is the decision those integrations would receive. The MCP calls in Live 04 leave this browser as a standard MCP client; an Agentforce MCP connection was not exercised here. The code above is written against documented Apex invocable actions, Flow HTTP Callout actions and the MCP client for Agentforce; the Flow is shown schematically, the custom field and the Named Credential are yours to name, and the tool-server URL is a placeholder for your own. The integration is demonstrated wiring, not a Salesforce-certified, AgentExchange-listed or endorsed solution.

Verification proves that the enforcement decision re-derives from the recorded inputs and that the record is unmodified and signed by the published key. It does not re-run the models: the consensus summary is attested through the recorded dissent register and verifier-text hash, and disclosed as such in the proof itself.

Salesforce, Agentforce, Agentforce 360, Data 360, MuleSoft, Flow, Apex and other Salesforce marks are trademarks of Salesforce, Inc. Veridect is an independent company and is not affiliated with or endorsed by Salesforce.

Five questions, answered for a Salesforce team

The short version.

How does this help?

It lets Agentforce agents into the actions that carry consequences — case closures, opportunity changes, contact details, credits and refunds — because an independent judgment stands in front of each action and a signed record stands behind it. The model that proposes the action is never the one that approves it.

How do I integrate it?

One of the three paths above: an Apex class at the top of the action, a decision element in the Flow, or one MCP URL. Your agents, topics, instructions and models stay as they are. The decision records export as newline-delimited JSON beside your event monitoring. It runs where you say, on your keys.

How long does it take?

The system is live today. A private sandbox on your own policy thresholds in a day once you say go; production typically about two weeks, with the pace set mostly on your side — security review, keys, access. Ours is ready on day one.

How does this make money?

Three levers, none of them invented here: revenue held back because agents could not be trusted with the consequential step; cost stopped on human review of actions a signed record now settles; losses not taken on the actions that should never have executed. Your own number comes out of the sandbox.

Why you and not a big well-known company?

Because the judgment has to be independent of the model and of the platform to be worth anything to an auditor. Agentforce’s own guardrails, topics and instructions are the platform’s view of its agents; a platform grading its own agents is self-governance. Veridect is a separate control plane with its own ledger and keys, validated by an external red team on scope-violation semantics, and verifiable offline. Try to forge a record on the live tour; the engine refuses it.

Test-drive it yourself.

Run the four actions above, verify the records, then take the full live tour — identity envelopes, delegation chains, cross-agent exposure, the fleet layer, and the forgery the engine refuses. Seven minutes, open access.

Prefer to see it on your own scenarios? Paste one on the pre-action console — or write to lrussell@veridect.ai and a scoped production sandbox on your own thresholds and your own tenant follows in a day.

The same control plane, built the same way for Snowflake, Microsoft, AWS, ServiceNow, CrowdStrike, Rubrik, Databricks, Okta and Google Cloud — one engine behind all ten pages, each run live. All ten platforms →