
Before copying a production database into dev or UAT, know where the risk grows and when masking, synthetic data or a minimal subset fits the job.
Just before UAT on a new system, one request always sounds reasonable: copy the production database into the test environment, because real data contains odd cases that sample data never does. The reasoning is sound. But the moment you approve it, the same personal data exists in at least two places, and the second place has not been reviewed the way the first one was.
This article is written from the point of view of a team that designs test environments. It is not legal advice. We describe what we weigh before letting real data leave production, what the alternatives are, and when real data is genuinely needed. What your organization is obliged to do under Thailand's Personal Data Protection Act B.E. 2562 (2019), the PDPA, is a question for your DPO or legal counsel to confirm. The Thai legal text quoted below is our own English translation.
One real dataset becomes several, without anyone deciding it should
A production system that has passed a security review restricts access by role and keeps logs of who did what. A test environment exists so the team can move quickly, so it tends to get pulled the other way: accounts may be shared, and anyone who helps with testing may be given access to all of the data.
There are only a few places where risk grows once real data lands in dev, staging or UAT, but each of them is quiet.
More people can see it. Developers, testers, business users helping with UAT and the outside development team all see the same data that production was built to protect.
Controls are looser. Error messages and logs in test mode may print real values, which then flow into a logging system that more people can read.
Data leaves the system. If test cases are written in spreadsheets with real sample records, those files sit entirely outside the database's controls.
Copies are forgotten. The UAT database outlives the project, and it may have backups of its own.
Suppose an organization copied its member database into UAT while building a system two years ago. Today a member asks for their data to be deleted. The production team deletes it from the live system, but nobody thinks of the UAT database that is still running. In this hypothetical nobody did anything wrong. The problem is that the copy had no owner.
Section 37 (1) of the PDPA requires a data controller to "put in place appropriate security measures to prevent the loss, access, use, alteration, modification or disclosure of personal data without authority or unlawfully." The section does not distinguish between data in a live system and data in a test system, so we design on the basis that a copy in a test environment must be protected at least as well as the original (the PDPA text on the PDPC website).
A second point comes from the Personal Data Protection Committee's Notification on Criteria for Deletion, Destruction or Anonymization of Personal Data B.E. 2567 (2024). Clause 3, paragraph two, states that acting on a deletion request "must also cover personal data that has been copied or backed up (if any)" (the Notification on the PDPC website). As we see it, a copy in UAT is a copy. If an organization does not know where its copies are, it cannot fully answer a deletion request.
Alternatives to copying the whole production dataset
The options come in levels, and you do not need to pick one for the whole system. Each environment can use a different approach depending on the work that happens in it.
Masking and tokenization
Masking replaces real values with values that do not reveal identity, for example by hiding some characters or replacing the whole value with a token. Google Cloud's Sensitive Data Protection documentation describes pseudonymization as a de-identification technique that replaces sensitive data values with cryptographically generated tokens. It distinguishes two kinds of token: a one-way token cannot be reversed, while a two-way token can, because the same cryptographic key that generates tokens can also reverse them (Google Cloud: Pseudonymization).
The same page notes that with the same key, an input value is always transformed to the same output, and that where data contains repetitive patterns, the risk of re-identification increases. Those two points are why our rule is that the key for two-way tokens must not live in the test environment, or with the team that uses the test data. If the key sits next to the data, tokenization achieves very little.
Dynamic masking is not a masked copy
Some databases can hide values at display time. Microsoft's documentation describes Dynamic Data Masking in Azure SQL as a feature that hides sensitive data in the result set of a query while the data in the database is not changed, and notes that users with administrative rights, such as server admin, Microsoft Entra admin and db_owner, can see the original data without any mask (Microsoft Learn: Dynamic Data Masking).
A feature like this is useful for limiting what different groups of users see, but we do not count it as test data, because the real values are still in the database.
Synthetic data
Synthetic data is generated to fit the schema and business rules without coming from real people. We use it as the default for dev and for any environment an outside team can reach, because if it leaks, nobody is harmed. The cost is making it realistic enough, for example Thai names of varying lengths, or ID numbers that pass the system's validation checks.
The smallest subset the work needs
Some work needs data that looks very close to the real thing. Pulling only the rows and columns that task needs, then masking the columns that identify people, limits the damage if something goes wrong. The question we decide by is which columns this test really needs, not which columns the table happens to have.
Pseudonymized is not anonymized
The misunderstanding we most want readers to watch for is the belief that data stops being personal data once names are swapped for codes. Section 6 of the PDPA defines "personal data" as "information relating to a person which enables the identification of that person, whether directly or indirectly, but not including information of deceased persons in particular."
The word "indirectly" is the one to watch.
Clause 6 of the 2024 Notification mentioned above sets out anonymization in two steps. The first is to remove direct identifiers, such as name, national ID number, telephone number and email address. The second is further consideration so that the chance of indirect identification is "at a sufficiently low level." The Notification says this may involve "pseudonymization, or taking any other action on all or part of the data" to reduce the chance of identification from indirect identifiers, for which it gives examples including date of birth, age, job title and IP address.
To be clear, this Notification was written for deletion or anonymization in response to requests under Section 33, and for the review system under Section 37 (3). It does not address test data directly. We use its two-step principle as a design reference, not as a claim about what the law requires for testing.
The conclusion we work with is this: if the organization still holds a mapping table or key that can turn codes back into people, we treat that dataset as still indirectly identifiable, and we handle it exactly as personal data. The final classification of each dataset is for your organization's DPO to confirm.
Who should have access to test environments, and what to agree with an outside development team
We apply the same principle we use when giving AI agents access to production systems: grant only what the work needs, and let that access expire when the work ends. For test environments, that means access is listed by named individual, not through a shared team account, and any environment holding real or reversible data keeps a log of who entered and when.
Once an outside development team is involved, the question of legal roles comes up immediately. Section 40 of the PDPA sets out the duties of a data processor, which include acting on personal data "only in accordance with the instructions received from the data controller," unless those instructions are contrary to law or to the Act's data protection provisions, and putting appropriate security measures in place while notifying the controller of any breach. The same section also states that "the data controller shall arrange an agreement between them" to govern the processor's work. Whether your outside team holds that role on a given piece of work is for your DPO to assess.
Whatever that assessment concludes, these are the points we recommend writing into the TOR or the contract with an outside development team:
Which type of data each environment may hold, for example synthetic data only in dev and a masked subset in UAT.
Test data stays in the organization's own cloud account, not the developer's, and may not be exported to personal devices.
The masking process is part of the deliverables, documented and repeatable by the internal team.
A deletion date for test data at the end of each phase, with evidence that it was deleted.
The time frame and channel for reporting an incident if data leaks or is accessed abnormally.
When real data is genuinely needed, and how to fence it
Some work really cannot use substitute data. The clearest example is a data migration rehearsal before cutover, which has to prove that every real row moves across completely and correctly. We cover validation and cutover separately in our article on validation and cutover. Another case is a bug that only occurs with certain rows in production and cannot be reproduced with other data.
When real data is needed, we do not lower the data's protection to test-environment standards. We raise the environment to production standards.
A separate cloud project or subscription for this work only, not mixed with general dev.
Named individuals with written approval, and every access logged.
A deletion date set on the day the environment is created, with a record of when it was deleted and who confirmed it.
Export channels closed, and no debug logging that prints data values.
The drawback we should state plainly is that masked or generated data cannot catch certain kinds of bug, such as problems caused by the distribution of real data, or legacy values the old system accepted but the new one rejects. The masking process itself also has to be maintained every time the schema changes. If yours is a small internal system with only a few personal-data columns, and everyone involved is an employee of the organization, building a full masking pipeline may not be worth it. The simpler path in that case is a fenced copy following the list above, deleted on schedule.
Objections we hear often
The first objection is that the test system sits on the internal network, outsiders cannot reach it, so this much effort is unnecessary. An internal network answers the question of whether outsiders can get in. The risk with test data lies with the people who can already get in, including outside teams on VPN. And if a deletion request arrives one day, a copy on the internal network still has to be deleted.
The second objection is that the development team has signed an NDA. We think an NDA is worth having, but an NDA works after the fact. It does not reduce the number of copies or the number of people who can see the data at all. Letting an outside team work with data that harms nobody if it leaks protects both the organization and the developers themselves.
Where to start
Find out where copies of production data exist today, across dev, staging, UAT, export files and backups of those environments, and name an owner for each one.
Classify columns, separating direct identifiers from indirect ones, using the examples in the 2024 Notification as a starting point and adding the columns specific to your system.
Decide per environment whether each one uses synthetic data, a masked subset or a fenced real copy.
Write the rules into procurement documents before the next project starts, not just before UAT.
Set deletion dates for every real copy that remains, and have someone confirm each deletion.
If you take one thing from this article, ask a single question before approving any request to copy production data: when will this copy be deleted, and who will confirm it? If nobody can answer yet, the copy should not exist yet. If your organization is setting up test environments for a new system, or wants someone to review how existing copies should be handled, we are happy to talk, with no pressure to decide.
You can reach us on 088-983-9386 or at [email protected]. Our office is in Bangkapi, Bangkok, and more about us is at superdev.tech. If it turns out that what your organization needs is a legal answer rather than a system design, we will say so plainly and suggest starting with your DPO.
FAQ: Frequently Asked Questions about This Article
A collection of questions and answers to help you better understand the content of this article.
Tags:

