all insights

Data 360 governance: making sure your agent only sees what the user is allowed to see

An Agentforce agent is exactly as trustworthy as the identity it runs as. Here's how object, record, and field access — plus attribute-based policies and dynamic masking — decide what a grounded agent can retrieve, and the retrieval gap that leaks a record no human would ever see.

Data 360 governance: making sure your agent only sees what the user is allowed to see — article illustration

The scariest Agentforce demo I’ve watched wasn’t one that hallucinated. It was one that answered correctly. A service agent, asked a routine account question, cheerfully surfaced a compensation note from an HR document that had been dumped into the same knowledge library months earlier. Nothing was invented. The retrieval was perfect. The problem was that the agent could see it at all.

That’s the failure mode nobody rehearses. Everyone stress-tests agents for hallucination — narrow the topics, ground the answers, add an “I don’t know” path. Far fewer teams stress-test them for over-permission, and it’s the more dangerous of the two, because a wrong answer embarrasses you while a leaked answer gets reported to a regulator. An agent grounded on your data inherits your data’s access model, whatever that model happens to be. If that model is sloppy, the agent industrialises the sloppiness: it will retrieve, summarise, and cheerfully volunteer anything the identity it runs as is allowed to touch, at machine speed, to whoever asked.

So the governance question for a grounded agent isn’t “what did it say?” It’s “as whom did it say it, and what could that identity see?” This post is about answering that question in Data 360 — the object, record, and field controls that decide the blast radius, the attribute-based policies and masking that Salesforce layers on top, and the one retrieval gap that quietly undoes all of it if you don’t close it deliberately.

An agent has no permissions of its own — it borrows a user’s

Start with the single fact that reframes everything: an Agentforce agent does not have its own access to data. It acts as a running user, and its reach is that user’s reach. Salesforce is explicit that agents inherit user permissions, role hierarchy, and field-level security, so they only access and act on data that identity is authorised to use.

Which identity, exactly, depends on the agent:

  • An employee-facing agent — the kind you put in Slack or on an internal record page — typically runs in the context of the logged-in user. Its access is that employee’s access. A rep who can’t see other reps’ opportunities gets an agent that can’t either. That’s the safe, intuitive case.
  • A customer-facing service agent — the one on your website or messaging channel talking to an unauthenticated stranger — runs as a configured agent user, not as the customer. There is no logged-in human to inherit from. The guardrail is entirely whatever you scoped that agent user to see, and getting it wrong is how the compensation note escapes.

This is the first design decision, and most teams skip past it. Before you scope a single topic, decide the running identity and treat it like any other integration user: a dedicated user, a purpose-built permission set, profile access trimmed to the objects the use case genuinely needs, and nothing inherited “for convenience.” The blunt version: your agent’s data governance is a permission-set review, and if you haven’t done that review, you don’t have governance — you have optimism. We make the same argument about grounding quality in does Agentforce need Data Cloud; access is the other half of the same coin.

Because the running user is a real Salesforce user, everything you already know about the platform’s access model still applies — and still matters.

The three classic controls still do the heavy lifting

Object, record, and field access are not legacy concerns that Data 360 replaces. They are the load-bearing layer, and Salesforce’s own security guidance for the agentic era leans on exactly them: all permissions explicitly granted, least privilege by design, from day zero.

  • Object-level (CRUD). Can the running user read the object at all? An agent that never needs to touch Case shouldn’t have Read on Case. This is the cheapest, coarsest, most effective control, and it’s the one most often left wide because the agent user was cloned from an over-powered profile.
  • Record-level (sharing). Of the records on an object the user can read, which ones? Org-wide defaults, role hierarchy, and sharing rules decide this. For a customer-facing agent, the honest default is Private with a narrow, deliberate sharing model — you do not want an agent user that can see every account in the org because someone set the OWD to Public Read.
  • Field-level (FLS). Of the fields on a record the user can see, which columns? FLS is where the compensation-note class of leak lives: the record is legitimately visible, but a sensitive field on it should never reach a prompt. Hide it at the field level and it never enters the grounding context in the first place.

The reason to get these right at the platform layer, rather than trying to instruct the agent not to reveal things, is that instructions are probabilistic and permissions are deterministic. “Don’t share salary data” is a prompt the model may or may not honour under adversarial pressure — the exact pressure covered in AI agent security and prompt injection. A field the running user cannot read is a field the model never receives. One is a request; the other is physics.

If your agent’s actions run through Apex — and any non-trivial agent’s do — enforce the same model in the code, not just the config. Apex runs in system mode by default and will happily ignore the FLS you just set up, so make the action honour the running user explicitly:

public with sharing class AccountSummaryAction {
    @InvocableMethod(label='Get account summary for agent')
    public static List<Result> run(List<Request> requests) {
        Id accountId = requests[0].accountId;

        // USER_MODE enforces the running user's CRUD, FLS, and sharing.
        // A field the agent user can't read simply doesn't come back.
        List<Account> rows = [
            SELECT Id, Name, Industry, AnnualRevenue
            FROM Account
            WHERE Id = :accountId
            WITH USER_MODE
        ];

        Result r = new Result();
        r.summary = rows.isEmpty()
            ? 'No accessible account for this request.'
            : rows[0].Name + ' — ' + rows[0].Industry;
        return new List<Result>{ r };
    }
    // Request/Result inner classes with @InvocableVariable omitted for brevity.
}

WITH USER_MODE is the whole point of that snippet. Without it, the query runs as God and the FLS you configured is theatre. With it, an inaccessible field is silently dropped from the result and a restricted record throws before it can be summarised. It’s the difference between an action that respects governance and one that narrates around it. We go deeper on this in custom Apex actions for Agentforce — the description matters, but so does the mode.

What Data 360 adds: attribute-based policies and masking

The three classic controls answer “can this identity touch this object/record/field?” as a yes/no on identity alone. Data 360’s governance layer adds two things that yes/no can’t express: policy based on attributes, and masking that reveals a field’s shape without its value.

Salesforce has adopted attribute-based access control (ABAC) as the core authorisation model in Data 360. Where classic sharing keys off who you are (your role, your ownership), ABAC keys off a combination of attributes that can belong to the user, the data, or the environment. “Marketing analysts may see engagement data, but only for contacts in regions they’re assigned to, and never fields tagged Sensitive” is one policy in ABAC terms; in classic sharing it’s a tangle of roles, rules, and restriction sets. Data 360’s policy types let you author field-, object-, and record-level policies centrally, and — this is the part that matters for agents — those policies apply everywhere Data 360 feeds, including Agentforce grounding, analytics, and segmentation. You write the rule once; the agent, the dashboard, and the segment all inherit it.

The mechanism that makes ABAC practical is tagging. Data 360 can detect and tag sensitive information during ingestion, across both structured and unstructured data, so that field- and record-level policies key off the tag rather than a hand-maintained list of column names. That’s what lets a policy say “never expose anything classified PII to this data space” and have it hold as new sources arrive, instead of decaying the moment someone adds a table nobody re-reviewed.

Then there’s dynamic data masking, the control that’s easy to underrate. Masking shields a value based on the requesting identity’s permissions without altering the underlying record — the field is present, its shape is intact, its content is redacted. For an agent this is often exactly the right granularity: a fraud-triage agent may legitimately need to reason about the existence and format of a card number without ever receiving the digits, so it can say “the card on file ends 4402 and matches the billing profile” without the full PAN ever entering the model context. Masking gives you the utility of the field without the liability of the value.

Data spaces sit underneath all of this as the coarse partition — a marketing data space and a finance data space are separated at a foundational level, and an agent grounded in one shouldn’t be reaching into the other. Think of the layers as concentric: the data space decides which world the agent lives in, object/record/field access decides what it can touch in that world, and ABAC policies plus masking decide the exceptions and the redactions. Governance is all four working together, not any one of them alone.

The retrieval gap: unstructured grounding is where leaks actually happen

Here’s the part that undoes teams who did everything above correctly for structured data. Structured queries — SOQL, Data 360 SQL, an Apex action with WITH USER_MODE — respect the access model by construction. Unstructured retrieval doesn’t, unless you make it.

When an agent grounds on knowledge — PDFs, help articles, uploaded documents through the Data Library or a search index — it isn’t running a sharing-aware query. It’s doing similarity search over an index of chunks. The index will happily return the most relevant chunk to the question, and relevance has no opinion about whether the asker is allowed to see it. If a document with sensitive content got indexed into a library the agent can search, semantic search will find it precisely because it’s relevant — which is the exact opposite of the behaviour you want. That’s the compensation-note leak, mechanically: not a permissions bug, an indexing decision nobody governed.

Salesforce’s answer is that the same tagging and masking must apply at retrieval — sensitive information detected at ingestion, policies enforced when the chunk is served, documents masked based on the requesting user’s permissions. But that protection is a configuration you turn on and verify, not a default that saves you. The discipline is threefold:

  1. Govern what gets indexed, not just who can query. The cheapest control is to never index a document into an agent-reachable library if the agent’s users shouldn’t see it. Segregate knowledge sources by audience the way you segregate data spaces. An HR handbook and a public returns policy do not belong in the same retriever.
  2. Tag and mask at ingestion so policy travels with the content. Classification applied when the document lands is classification that holds when it’s retrieved. Applied after the fact, it’s a race you lose.
  3. Test retrieval as an adversary, not as an author. This is the step that’s always skipped. Log in as the lowest-privilege user the agent serves and try to make it surface something restricted — ask sideways, ask about the person rather than the policy, ask for a summary rather than the document. If a low-privilege session can retrieve a high-privilege chunk, you have a live leak, and no amount of correct object/record/field config on the structured side closed it.

That adversarial retrieval test belongs in your standard agent test suite next to the utterance batches and conversation simulations we cover in how to test an Agentforce agent. “Can it answer?” and “can it be made to over-answer?” are different tests, and only the first one is fun to run.

A pre-launch governance checklist

Before a grounded agent goes anywhere near production traffic, walk this once. None of it is exotic; all of it is skipped.

LayerThe questionThe failure it prevents
Running identityAs which user does the agent execute? Is it dedicated and least-privilege?An agent cloned from an admin-adjacent profile seeing the whole org
Object (CRUD)Does the agent user have Read on objects it truly needs — and no others?Reaching an object the use case never justified
Record (sharing)Is the OWD private enough that the agent user sees only in-scope records?A Public Read default exposing every account
Field (FLS)Are sensitive fields hidden from the running user, not just discouraged in the prompt?A salary or SSN field entering the grounding context
Apex actionsDo queries run WITH USER_MODE / stripInaccessible?System-mode code ignoring the FLS you configured
ABAC policiesAre field/record policies authored on tags, applied across Data 360?Policy decaying as new sources arrive unreviewed
MaskingAre high-sensitivity fields masked rather than fully exposed where shape is enough?Full PANs/PII in model context when a suffix would do
Unstructured retrievalHave you audited what’s indexed, and adversarially tested retrieval as a low-privilege user?The relevant-therefore-leaked knowledge chunk

If you can answer all eight with evidence, you have governance. If you’re answering any of them with “the agent is instructed not to,” you have a prompt, and prompts are not a security boundary.

The reframe: governance is what makes autonomy safe to grant

It’s tempting to read all of this as friction — controls that slow down the fun part. It’s the opposite. The reason you can hand an agent genuine autonomy, let it retrieve and summarise and act without a human reading over its shoulder, is precisely that the access model underneath it is deterministic. Every restriction you enforce at the object, record, field, and policy layer is one more thing the agent cannot do wrong no matter how the conversation goes, no matter what a hostile user tries, no matter what the model decides is relevant. Deterministic guardrails are what earn probabilistic systems the right to run unattended.

The teams that get this build the permission review into the agent’s definition of done, not into a security sign-off that happens after the demo impressed everyone. They pick the running identity first, scope it hard, enforce it in Apex, express the exceptions as tagged policies, mask what only needs its shape seen, and test retrieval like someone trying to break in. Do that and the agent inherits a data model you’d be comfortable handing to a new employee on day one — which is the only data model you should be comfortable handing to something that acts at machine speed. Skip it, and the first perfectly-retrieved answer to the wrong question is the one you’ll be explaining to your DPO. Getting the foundation right is exactly the kind of work our Integration & Data Cloud practice exists to do before an agent ever grounds on it.

Understanding the basics

Do Agentforce agents respect Salesforce permissions?

Yes — an Agentforce agent has no independent access to data. It executes as a running user and inherits that user’s object (CRUD) permissions, record-level sharing, and field-level security, so it can only retrieve and act on data that identity is authorised to see. For employee-facing agents the running user is usually the logged-in employee; for customer-facing service agents it’s a configured agent user, which is why scoping that user tightly is the single most important governance step. The caveat is that unstructured knowledge retrieval doesn’t enforce sharing the way a structured query does, so you must govern what gets indexed and test it.

What is attribute-based access control in Data 360?

Attribute-based access control (ABAC) is the core authorisation model in Salesforce Data 360. Instead of granting access purely on who a user is (role, ownership), ABAC evaluates a combination of attributes belonging to the user, the data, and the environment — for example, allowing access to a field only for users in a given region and only when the field isn’t tagged sensitive. Data 360 lets you author these as field-, object-, and record-level policies centrally, and the same policies apply everywhere Data 360 feeds, including Agentforce grounding, analytics, and segmentation, so you define a rule once and every consumer inherits it.

How do you stop an AI agent from leaking sensitive data?

Enforce access deterministically rather than instructing the model to be discreet. Run the agent as a dedicated least-privilege user, restrict objects to what the use case needs, keep org-wide defaults private, and hide sensitive fields with field-level security so they never enter the prompt. In Apex actions, query WITH USER_MODE so system-mode code doesn’t bypass FLS. Use Data 360’s tagging, ABAC policies, and dynamic masking to redact values while keeping usable shape. Critically, govern unstructured retrieval separately — control what documents get indexed and adversarially test that a low-privilege user can’t make the agent surface a restricted chunk.


Not sure what your agent user can actually see? Talk to us — a running-identity and retrieval audit is a very normal first week before we let an agent ground on anything.

Keep reading

All insights