all insights

Salesforce Data Mask & Seed: safe, realistic sandbox data for testing agents and Apex

Your sandbox has a full copy of production, which means it has a full copy of your customers' PII — sitting in a lower-security environment where developers, contractors, and now AI agents all poke at it. Here's how Data Mask obfuscates that data in place, what the four masking types actually do, how seeding gives you realistic data without the risk, and why testing an agent on masked data is a different job than testing Apex.

Salesforce Data Mask & Seed: safe, realistic sandbox data for testing agents and Apex — article illustration

Here’s an uncomfortable question to ask your team: how many copies of your customers’ personal data exist right now, and who can read them? If you run Full or Partial Copy sandboxes, the honest answer includes every sandbox — each one a lower-security clone of production where real names, emails, phone numbers, and revenue figures sit in front of developers, QA, contractors, and, increasingly, AI agents you’re testing before they ever meet a real customer. Production has Shield, monitoring, and a small blast radius. Your sandboxes have a refresh button and a lot of people with logins.

That gap is exactly what Salesforce Data Mask closes, and it’s become more urgent, not less, in the agent era. You can’t responsibly test an Agentforce agent’s grounding and actions against live customer PII in a sandbox — but you also can’t test it against an empty org, because an agent that works on ten tidy records falls over on the mess of real data. You need data that’s shaped like production without being production. This post is about the two halves of that: masking the sensitive data you copied down, and seeding realistic data where you don’t have it.

What Data Mask actually is, and where it runs

Data Mask is a managed package that uses platform-native obfuscation to mask sensitive data — PII, revenue, anything you classify as sensitive — in Full and Partial Copy sandboxes. The mechanic that makes it safe is worth stating precisely, because it’s the thing people get nervous about:

You author the masking configuration in your production org — choosing the objects and fields that hold sensitive data and assigning a rule to each. But masking never runs in production. The configuration travels with any sandbox spun up from that org, and when the sandbox is created or refreshed, Data Mask runs against the copied records in the sandbox. Production data is never altered, because the transformation happens on the copy, after it lands.

Data Mask configures in production and executes in the sandbox. Your live data is never touched — the obfuscation happens to the copy, on refresh. That separation is the whole safety model.

One consequence to internalise: masking is irreversible by design. Once a sandbox record’s email is obfuscated, the original is gone from that sandbox — that’s the point. There’s no unmask button, and you wouldn’t want one. Which means the discipline is to mask on every refresh, not to mask once and forget, because a fresh copy from production arrives un-masked until the job runs.

The four masking types, and when each is right

Data Mask gives you four ways to transform a field, and choosing correctly per field is the actual skill — over-mask and your tests become meaningless, under-mask and you’ve leaked. The options:

  • Replace with random characters. Swaps the value for random characters or numbers — readable, clearly not real. Good for free-text fields where you need something in the box but the content is irrelevant to your tests.
  • Replace from a library. Substitutes the value with random but recognisable data from a library — a real-looking-but-fake name, a plausible city, a valid-format email. This is the one that keeps your sandbox usable: testers see “Jordan Rivera in Denver,” not “[email protected],” so screens and reports still look like reality.
  • Pattern-based masking. Generates substitutes that match a required format — a nine-digit number that looks like an SSN, a phone number with the right shape — so validation rules and integrations that check format don’t break on the masked value.
  • Delete. Removes the value entirely. Right for fields that have no business existing in a sandbox at all.

The reason “replace from a library” matters so much: an agent, a report, or a screen flow tested against gibberish behaves differently than one tested against realistic-looking data. If you’re validating an Agentforce agent that summarises a customer record, masking the name to random characters can change how the model reads the record. Recognisable fake data keeps the distribution and shape of production while removing the identity — which is exactly what you want under test.

The permissions gotcha that silently skips objects

Here’s the failure mode that bites teams and produces a false sense of safety: Data Mask only masks objects the running user can write to. If the user running the masking job lacks write access to an object, that object is quietly not masked — no error, just unmasked PII sitting in your sandbox where you assumed it was clean.

So the setup requires the running user to have real reach. The documented requirements: Modify All Data and API Enabled at the profile/permission level, plus the Data Mask User permission set license and the Data Mask permission set. Miss the object-level write access on a custom object full of sensitive data and you’ll pass your own audit while leaking. The right move is to verify, after a masking run, that every object you think is masked actually was — treat the job’s report as evidence, not the configuration as a promise. This is the same “beyond the score” skepticism we argue for in running a real security review: the checkbox being green is not the same as the data being clean.

What Summer ‘26 changed

Data Mask has been quietly getting better, and the Summer ‘26 release is the notable step: it’s moving toward being a core, built-in app — a simpler experience rather than a package you hunt down and install — with a handful of practically useful upgrades. Verify the specifics against the current release notes for your instance, but the direction Salesforce has published:

  • Proactive PII detection, so the tool helps you find the sensitive fields to mask rather than relying entirely on you to enumerate them — the single most common way masking configs go stale is a new field nobody added to the rules.
  • Automatic preservation of field value distributions, so masked data keeps the statistical shape of production. This is a real upgrade for testing: a picklist that’s 80% “Active” in production stays roughly 80% “Active” after masking, so your reports, data-quality checks, and model behaviour see realistic proportions, not a flattened distribution.
  • Plain-language masking job reports, so when a run has a problem you can see what failed in readable terms instead of decoding a log.

The through-line: masking is moving from a specialist package you configured once to a routine, legible part of sandbox hygiene. That’s the right direction, and it lowers the excuse-not-to bar considerably.

Seeding: the other half of the problem

Masking assumes you copied production down. But Full and Partial Copy sandboxes are expensive and slow, and Developer sandboxes start empty — so a huge amount of real testing happens in environments with no data, or not enough of the right data. That’s the seeding problem: getting realistic, relationally-consistent data into an environment that doesn’t have it. Salesforce’s Data Mask & Seed framing pairs the two deliberately — mask what you copied, seed what you didn’t.

Natively, the lever for what comes down in a copy is the sandbox template. Templates control which objects and data get copied into a Full or Partial Copy sandbox, letting you size and scope the environment instead of cloning everything. The genuinely useful part: the template editor understands the relationships in your object schema — as you select objects, it ensures the required related objects come along, so you don’t end up with child records orphaned from parents they need. That relational integrity is the hard part of seeding done by hand, and it’s why ad-hoc data-loader scripts so often produce sandboxes that pass shallow tests and break on anything that traverses a relationship. (Partial Copy sandboxes cap the sampled data — on the order of 5 GB — so templates are also how you stay under the ceiling.)

Where a copy still won’t give you what you need — the edge cases production doesn’t contain, or the volume a Developer sandbox lacks — you generate data: mock or synthetic records seeded to exercise the paths real data doesn’t reach. This is the same instinct as testing an agent against synthetic personas — you deliberately manufacture the cases that matter — and it carries the same caveat: generated data clusters around the plausible and misses the weird, so use it to supplement masked real data, not replace it.

Why testing an agent is a different job than testing Apex

It’s tempting to treat masked/seeded data as one solved problem for all testing. It isn’t, and the agent case is where the difference bites.

Apex tests care about logic and format: does the trigger fire, does the calculation hold, does the validation reject the bad input. For that, pattern-based masking and a handful of seeded records are plenty — the code doesn’t care that “Jordan Rivera” is fake.

An agent cares about meaning and shape. It grounds on the record, reasons over the text, and decides what to do. Feed it masked-to-gibberish data and you’re not testing the agent you’ll ship — you’re testing how it behaves on nonsense. This is why the Summer ‘26 distribution-preservation and library-based replacement matter more for agent testing than for unit tests: the agent’s behaviour is sensitive to the realism of the data in a way Apex isn’t. When you deploy an agent from sandbox to production, the confidence you carry across is only as good as how production-like the data it was tested on was — masked for safety, but realistic enough that the test meant something.

There’s a compliance dimension too, and it’s not optional. Masking sandbox PII is how you keep lower environments defensible under GDPR, CCPA, and FINRA — regimes that don’t grant an exemption because the data is “only in a sandbox.” If you’re already thinking about right-to-be-forgotten in Data 360, the same subject-rights logic says the copies of personal data in your sandboxes are in scope, and masking is the cheapest way to take them out of it.

The takeaway

Every sandbox you refresh is a fresh copy of your customers’ PII in a lower-security environment, and “it’s only a sandbox” is not a control. Data Mask configures in production and executes irreversibly on the sandbox copy at refresh, with four masking types — random characters, library replacement, pattern-based, and delete — chosen per field so the data stays shaped like production without being it. Mind the permissions gotcha (unwritable objects are silently skipped), verify every run against its report, and lean into the Summer ‘26 upgrades — proactive PII detection, distribution preservation, readable reports — that make masking routine instead of a project. Pair it with sandbox templates that respect your schema’s relationships for seeding, and remember that testing an agent demands more realism from that data than testing Apex ever did. Get this right and you can hand a developer, a contractor, or an agent-in-testing a genuinely useful org without handing them a single real customer’s identity.

Understanding the basics

Does Salesforce Data Mask change my production data?

No. You author the masking configuration in your production org, but the masking only runs in Full and Partial Copy sandboxes — when the sandbox is created or refreshed, Data Mask obfuscates the copied records there. Production data is never altered because the transformation happens on the sandbox copy. The masking is irreversible by design, so the discipline is to mask on every refresh, since a fresh copy arrives un-masked until the job runs.

What are the four Data Mask masking types?

Data Mask can transform a field four ways: replace the value with random characters (readable but clearly fake), replace it with recognisable data from a library (a real-looking-but-fake name or city, so sandboxes stay usable), pattern-based masking (a substitute that matches a required format so validations and integrations don’t break), or delete the value entirely. Choosing the right type per field is the real skill — library replacement is usually what keeps a sandbox realistic enough to test against.

What permissions does Data Mask need, and what’s the common mistake?

The user running the masking job needs Modify All Data and API Enabled, plus the Data Mask User permission set license and the Data Mask permission set. The common — and dangerous — mistake is missing object-level write access: Data Mask only masks objects the running user can write to, and it silently skips objects it can’t, leaving unmasked PII in the sandbox with no error. Always verify a masking run against its job report rather than trusting the configuration.

How is masking data for an AI agent different from masking for Apex tests?

Apex tests care about logic and format, so pattern-based masking and a few seeded records are usually enough. An AI agent grounds on and reasons over the actual content of a record, so it’s sensitive to the realism of the data — masking to gibberish tests the agent on nonsense, not on what it’ll see in production. Library-based replacement and Summer ‘26’s field-value-distribution preservation matter more for agent testing because they keep the data’s shape and meaning production-like while removing customer identity.


Standing up a sandbox strategy where lower environments are realistic enough to test agents on but clean of customer PII — and defensible under GDPR and CCPA? Talk to us. Getting the environment and data foundation right so you can test with confidence is exactly the work we do.

Keep reading

All insights