Permissions and safety for CRM AI agents

· 7 min read· Salesforce · HubSpot· Platform behavior verified August 20, 2026

Object, field, and row scope; running as the asking user; why a permission-suppressed null looks exactly like a blank; who is allowed to edit the rules; and a five-level model for letting an agent act.

The permissions material on this site was buried inside a longer guide, and it's the part most likely to produce an answer that's wrong in a way nobody catches. So it gets its own page.

Three separate questions here, and they get conflated constantly:

  1. What can the agent read? Object, field, and row scope.
  2. Who can change what the agent believes? The rules store is application behavior, not data.
  3. What is the agent allowed to do? Reading is one thing. Acting is another.

Three scopes, and they're independent

ScopeControlsSalesforceHubSpot
ObjectWhich objects exist for this userCRUD via profile / permission setObject-level permissions per role
FieldWhich fields are visibleField-level securityProperty-level permissions
RowWhich records are visibleSharing rules, role hierarchy, ownershipTeam ownership and record access

A user can have object access, lack field access, and see a third of the rows. All three apply to your agent, because your agent is running as somebody.

Your allowlist sits on top of these, never instead of them. The allowlist is a semantic policy about what's worth sending the model. Platform permissions decide what the running user may see. Both have to exist, and where they disagree, the platform wins silently.

Run as the asking user

This is the central decision and it has a consequence people find surprising: the same question returns different answers for different people.

That's correct. A regional AE asking about pipeline should get their region. A CRO asking the identical question should get everything. The alternative, running as a privileged integration user, is simpler to build and turns every agent answer into a data-exfiltration path, because a rep can now ask questions that return records they could never open in the UI.

The problem is that the model has no idea it's looking at a partial org. It will report "we have 38 opportunities" with total confidence when the honest sentence is "you can see 38 opportunities."

Two global instructions fix it:

  • State whose permissions the query ran under, in the answer, every time.
  • Never conclude that no records exist from an empty result on a sharing-restricted object. "None visible to you" and "none exist" are different claims.

The suppressed null

My favorite gotcha on the whole site, because there's no signal at all.

When field-level security hides a field from the running user, the platform doesn't raise an error. It returns null. A permission-suppressed null and a genuinely empty field are byte-identical by the time the model sees them.

So the agent reads "this account has no renewal date" and reasons from there. The answer is fluent, the logic is sound, and the premise is an artifact of permissions.

Platform behavior

In Salesforce, WITH SECURITY_ENFORCED or Security.stripInaccessible turns that silence into something you can handle: the query raises an exception naming the inaccessible field instead of quietly returning null for it.

fls-aware-query.cls
// Without WITH SECURITY_ENFORCED, Renewal_Date__c comes back null for any user
// whose FLS hides it, and the caller cannot tell that from a real blank.
List<Account> accounts = [
    SELECT Id, Name, Renewal_Date__c, Renewal_Risk_Score__c
    FROM Account
    WHERE Id IN :accountIds
    WITH SECURITY_ENFORCED
];

The general rule, on any platform: if you can't distinguish "hidden" from "empty," you can't let the agent interpret the blank. Either surface the difference or instruct the agent to treat blanks on sensitive fields as unknown rather than as absent.

Deploying a field grants nobody access

Small, universal, and it costs everyone an afternoon exactly once. Deploying a field or an object does not give anyone permission to read it. Access is a separate permission-set or profile step.

You will build the guidance object, deploy it, query it, get zero rows, and start debugging your SOQL. The SOQL is fine.

Who can read the rules store

Your rule text encodes thresholds, exclusion logic, attribution policy, and definitions of terms like qualified pipeline. That's the operating model of your GTM org written in plain English, in one queryable place.

If the guidance object inherits default org-wide read, you've published it to every seat in the company. Including the sales org whose compensation depends on the attribution rules.

Set the org-wide default to Private and grant read through a permission set. This takes two minutes and nobody thinks to do it.

Who can write the rules

Here's the part that isn't in most write-ups, and it's the one that matters as agents get more capable.

A guidance rule is an instruction your agent will follow on every question. Editing one is closer to changing application behavior than to updating a record. Someone with edit access on the rules object can:

  • change what "qualified pipeline" means, shifting every number that depends on it;
  • deactivate an exclusion, silently inflating counts across the org;
  • add a rule instructing the agent to ignore another rule;
  • write text into a rule that the agent reads as an instruction.

That last one is the interesting one. It's configuration injection: the rules store is a privileged channel into the model's behavior, and anything that can write to it can steer the agent.

Practical controls, in rough order of value:

  • Separate edit from read. More people should read the rules than write them.
  • Require approval before status: active. draft and approved exist for this. A rule reaching production should be a deliberate transition, not a save.
  • Version and audit every change. You want to answer "what did this rule say in July" without archaeology.
  • Keep user-generated CRM content out of the guidance channel. Never build a rule body by interpolating a text field a customer or rep can write into. That's the CRM equivalent of string-concatenating SQL.
  • Keep rollback one step away. A bad rule should be revertible in seconds, not in a deploy cycle.

The threat model isn't only malicious. A well-meaning admin who edits the fiscal calendar rule to fix one report can shift every historical comparison the agent makes, and nobody will notice for a month.

How much should the agent be allowed to do

Reading and acting are different risk profiles, and "can the agent write?" is too blunt a question. A ladder is more useful, because it lets you stop somewhere on purpose:

LevelCapabilityWhat can go wrongReasonable for
0Answer from supplied context onlyWrong answer, no data reachDemos, prompt design
1Read live CRM data under the user's permissionsConfident wrong answer from unexplained fieldsMost production value lives here
2Recommend an action a human then takesA bad recommendation someone followsSecond most value
3Propose a specific write for approvalApproval fatigue; rubber-stamped bad writesNarrow, high-volume, well-tested paths
4Execute a constrained writeSilent data corruption at machine speedRare, and only with a hard blast radius

Most of the value is at levels 1 and 2. Most of the incidents come from jumping to level 4 because a demo made it look easy.

If you do go past level 2, three things stop being optional:

Know what silently reverts. A field force-set by automation on every save will accept the agent's update, return 200, and revert. The recommendation looks applied and isn't. Mark those writePolicy: force_set_by_automation and don't let the agent propose writing them.

Never overwrite a human-owned field. A rep's qualification score or a CSM's health assessment should be read, compared against, and reported as agreement or disagreement with reasoning. The moment the AI's opinion overwrites the practitioner's, trust collapses and the field gets gamed or abandoned.

Constrain the blast radius in code. Row count caps, allowed field lists for writes, and a dry-run mode belong at the tool boundary, not in a prompt asking the agent to be careful.

What to check

  • The agent runs as the asking user, not a privileged integration user

  • Answers state whose permissions the query ran under

  • Empty results on sharing-restricted objects are never reported as "none exist"

  • FLS-hidden fields surface as errors rather than nulls

  • The guidance object's org-wide default is Private

  • Rule write access is narrower than rule read access

  • Rules require approval before reaching status: active

  • Rule changes are versioned, audited, and revertible in seconds

  • No rule body interpolates user-editable CRM text

  • The write capability level is a decision someone made, not a default

  • How to build an AI context layer for your CRM — the concept and full build

  • One CRM question, traced end to end — where the gate sits in a real run

  • Debugging wrong CRM AI answers — the symptoms these failures produce

  • Salesforce implementationWITH SECURITY_ENFORCED in context

FAQ

Should a CRM AI agent run as the asking user or as an integration user?
As the asking user, in almost every case. It means the same question returns different answers for different people, which is correct — each person sees what they're entitled to see. Running as a privileged integration user is simpler and quietly turns every agent answer into a data-exfiltration path, because a rep can now ask questions that return records they could never open in the UI.
Why does a blank field in a CRM AI answer not mean the field is empty?
Because field-level security doesn't error when it hides a field — it returns null. A permission-suppressed null and a genuinely empty field are byte-identical to the model, which will happily reason that the account has no renewal date. In Salesforce, WITH SECURITY_ENFORCED or Security.stripInaccessible turns that silence into an exception you can handle.
Who should be allowed to edit AI guidance rules?
Fewer people than can edit CRM records, and never the same permission set by default. A rule is an instruction an agent will follow across every question, so editing one is closer to changing application behavior than to updating a record. Treat rule edits as a change that needs review and an audit trail, because an attacker or a careless admin editing a rule is configuration injection into your agent.
How much should an AI agent be allowed to do in a CRM?
Start at read-only and move up deliberately. A useful ladder: answer from context only, read live CRM data, recommend an action a human takes, propose a specific write for approval, and execute a narrowly constrained write. Most production value sits at levels 1 and 2, and most incidents come from jumping to level 4 because a demo made it look easy.

Get the next guide

New guides and the occasional note on GTM tooling. Don't worry, I won't drop you into a three-month nurture.