A test system is meant to mirror production closely enough that a defect shows up there instead of in the running shop. The most convenient route to that is a dump of the production database - and that is exactly where the problem starts: the dump carries names, addresses, mail addresses, order histories and payment references into an environment that is rarely protected as well as the Shopware store itself. In legal terms it remains the same processing with the same obligations; in technical terms the test system usually lacks access protection, logging and a defined deletion date. This article shows which requirements a staging environment has to meet, what a dump pipeline looks like that prevents plain text from appearing in the first place, and which three locks every copy needs before anyone logs in.
Why a copy of the production database is not a special case
Personal data means any information relating to an identified or identifiable natural person (GDPR Art. 4 (1)). Copying, storing and making such data available counts explicitly as processing (GDPR Art. 4 (2)). That makes the production dump a processing activity in its own right, with a purpose, a legal basis and protective measures - not a technical side effect. On top of that comes the principle of data minimisation: data must be adequate, relevant and limited to what is necessary (GDPR Art. 5 (1) (c)). A development team needs realistic volumes, field lengths and distributions - it usually does not need a single real surname.
The consequences of an incident in a test system are no different from one in production. If a staging environment is compromised, the same notification duty applies: without undue delay and, where feasible, within 72 hours to the competent supervisory authority, unless the breach is unlikely to result in a risk to the rights and freedoms of natural persons (GDPR Art. 33 (1)). Where a dump of real order and customer data is involved, that exception is typically hard to argue. Missing technical and organisational measures fall into the bracket of up to 10 000 000 euros or 2 per cent of worldwide annual turnover (GDPR Art. 83 (4)); infringements of the processing principles fall into the bracket of up to 20 000 000 euros or 4 per cent (GDPR Art. 83 (5)). In each case the higher amount applies. For a system that officially runs for testing only, that is a remarkably high exposure.
Wenn neue Software mit Produktivdaten getestet wird, könnten eventuell nicht befugte Personen hierbei vertrauliche Informationen einsehen, wie besonders schützenswerte personenbezogene Daten.
BSI, IT-Grundschutz Compendium Edition 2023, module CON.8 Software Development, section 2.8 (German original)
In practice, the test system is the weaker twin. It often runs on smaller hosting without the protective layers of production, carries a password that gets passed around the team, and is neither deleted nor maintained once the project ends. Search engines find it through a forgotten subdomain, order confirmations go out to real recipients, and a payment service receives requests from an environment nobody monitors. None of these points is an exotic edge case; they all come from the same assumption, namely that a test system is worth less than its original. To an attacker it is the same data at lower resistance.
The difference decides whether the data protection obligations keep running. Pseudonymisation means the data can no longer be attributed without additional information, while that additional information continues to exist separately (GDPR Art. 4 (5)). Such data still counts as information about an identifiable person (GDPR Recital 26). Only once the data subject can no longer be identified do the principles of data protection stop applying. A test system in which names were swapped for an identifier while address, order value and timestamp stay untouched is therefore usually pseudonymised - not anonymised - and remains fully within the scope of the regulation.
What law and baseline security expect from a test system
Two provisions apply directly. The controller has to implement appropriate technical and organisational measures - pseudonymisation is named explicitly - and to do so already at the time of determining the means for processing (GDPR Art. 25 (1)). As an example of appropriate security, the regulation lists the pseudonymisation and encryption of personal data first (GDPR Art. 32 (1) (a)). Anyone who writes the replacement rules only after the first test system is running satisfies the idea of data protection by design only after the fact. If the dump serves a purpose other than the original collection, it also has to be assessed whether appropriate safeguards such as encryption or pseudonymisation are in place (GDPR Art. 6 (4)).
| Requirement | What this means in staging | Reference | Check point |
|---|---|---|---|
| Data minimisation | Pull only the tables and periods the test actually needs | GDPR Art. 5 (1) (c) | Table list |
| Protection by design | Replacement rules belong in the dump pipeline, not in a later clean-up | GDPR Art. 25 (1) | Process plan |
| Security of processing | Pseudonymisation and encryption as the baseline of the environment | GDPR Art. 32 (1) (a) | Access protection |
| Separated environment | Test and production share neither database nor cache nor search index | BSI CON.8.A7 | Credentials |
| Protected test data | Pseudonymise personal test data at a minimum | BSI OPS.1.1.6.A11 | Sample per table |
| Ability to report | An incident in the test system runs into the same 72-hour window | GDPR Art. 33 (1) | Contact chain |
The IT baseline protection framework of the German Federal Office for Information Security is clearer on this point than many internal policies. Software has to be tested in a test and development environment that is separated from the production environment (BSI IT-Grundschutz Compendium CON.8.A7). Separated means more than a different domain here: its own database, its own credentials, its own cache and its own prefix for the search index (Shopware documentation). If the two environments share one of these layers, a test run can overwrite or displace production data without anyone making an operating mistake. The reverse direction counts too: a test system that talks to production counterparts creates real transactions there.
For the data itself the baseline framework is just as clear: if production data used for software tests contains information worth protecting, that test data has to be protected appropriately; if it contains personal information, it has to be pseudonymised at a minimum (BSI IT-Grundschutz Compendium OPS.1.1.6.A11). Functional software tests also have to be carried out in a way that does not affect production operations (BSI IT-Grundschutz Compendium OPS.1.1.6.A2). Together these produce the everyday working rule: the test data set should be as realistic as necessary and carry as little personal reference as possible. How to build a dependable test track on top of that is described in the article on end-to-end test automation for online shops - automated tests need predictable data rather than random real orders anyway.
- Purpose before volume: Before the first dump, record what the test system is needed for. A layout test needs different data from a migration rehearsal, and the volume follows from that answer.
- Replace instead of empty: An emptied field changes field lengths and distributions and makes the test useless. A replaced value of the same shape keeps the result meaningful.
- Keep the references: Foreign keys have to survive the replacement, otherwise the data set falls apart into unconnected islands and the test checks a structure that does not exist.
- Plan the deletion date: Every test system needs an expiry date. How that interacts with statutory periods is shown in the deletion concept with retention periods.
- Document it: The replacement rules belong in the process documentation, not in the memory of the person who pulls the dump.
Four stages: dump, replace, truncate, import
The order decides the outcome. Anyone who imports the dump first and cleans it afterwards has a complete copy of the customer data sitting on the weaker system for the length of that window - and traces of it stay behind in that system's log files, caches and backups. The dependable pipeline turns this around: the dump is pulled, the replacements run on the dump or in a sealed intermediate stage, superfluous tables are truncated, and only the cleaned version reaches the test system. That way no plain text data set ever exists on the target system, so none has to be chased down later.
-- The replacement runs on the dump before it reaches the test system
UPDATE customer
SET first_name = CONCAT('Firstname', id),
last_name = CONCAT('Lastname', id),
email = CONCAT('user-', id, '@example.invalid'),
company = CONCAT('Company ', id),
remote_address = NULL,
custom_fields = NULL;
UPDATE customer_address
SET street = CONCAT('Sample Street ', id),
zipcode = '00000',
city = 'Sample City',
phone_number = NULL;
-- The order keeps its own copy of customer and address
UPDATE order_customer
SET first_name = CONCAT('Firstname', customer_id),
last_name = CONCAT('Lastname', customer_id),
email = CONCAT('user-', customer_id, '@example.invalid');
UPDATE order_address
SET street = CONCAT('Sample Street ', id),
zipcode = '00000',
city = 'Sample City';
-- Truncate instead of replace: the test does not need these rows
TRUNCATE TABLE log_entry;
TRUNCATE TABLE newsletter_recipient;
TRUNCATE TABLE import_export_log;
TRUNCATE TABLE product_review; The rules stay deliberately predictable: the replacement value is derived from the primary key so the same record gets the same placeholder on every run. That keeps two dumps comparable and makes it possible to match a defect report from the test system to a transaction without knowing the real name. Mail addresses move to a reserved suffix that belongs to no business; the .invalid suffix exists for exactly this purpose. As the data set grows it pays to store the replacement as a repeatable step in the development pipeline instead of a set of instructions in a chat message.
- Log tables: Access, error and dispatch logs contain addresses and content and are usually not needed for a test.
- Carts and sessions: Open carts inflate the dump and carry identifiers that can be traced back to a person.
- Attachments and documents: Invoice and delivery note files live outside the database and are frequently overlooked in a pure database dump.
- Credentials for external systems: Keys for payment, shipping and ERP have to be swapped, otherwise the test system acts inside real systems.
- Newsletter lists: A complete recipient list in the test system is the shortest route to a real mass mailing.
The most common design flaw is a clean-up script that runs on the test system after the dump has been imported there. Between import and end of script lies a window of complete plain text - and that window leaves traces in backups, caches and logs the script can no longer reach. If the replacement moves into the dump step instead, the plain text does not appear on the target system in the first place. The effort is the same, the risk is not.
Which tables in the shop carry personal data
The search for personal fields rarely ends where it begins. The customer master is obvious, the address table too; in a B2B shop company records, contact persons and customer-specific prices are added. Less obvious are the copies: a shop system usually stores its own transcript of customer and address with the order so that a later address change does not alter the document. These transcripts carry the same data a second time and are frequently forgotten during a replacement. Add to that reviews under real names, contact requests with free text, returns, voucher assignments, import and export logs and notifications.
For the search itself a systematic look at the data model beats guesswork. Column names containing mail, name, street, phone, ip or token are a good start, but they catch neither free text fields nor serialised columns in which a payment service stores its response. Anyone running those queries against a large data set should keep an eye on the runtimes; which measurements help here is described in the article on slow query log and database indexes. The result is a list that gets versioned and grows with every extension of the shop.
Customer master and addresses
First name, surname, company, address, phone number, date of birth and customer number. This is where the replacement starts - and it has to cover the transcripts of the same data in the order documents.
Orders and payments
Document data, payment references and the responses of connected services. Amounts and timestamps may stay; identifiers and real names have to be replaced.
Communication
Mail logs, contact requests, reviews and newsletter lists. These tables are usually truncated rather than replaced because the test does not need them.
Technical traces
IP addresses, session identifiers, access logs and import-export runs. They are personal data even when no name sits next to them.
Two areas tend to slip through the net. The first is custom extensions: a self-built module for quotes, complaints or customer prices creates its own tables, and those appear in no standard list. The second is the connected systems - an ERP, a shipping service or an accounting package that talk to the shop through integrations. If the test system points at the production counterparts, real transactions appear there: shipments get announced, documents get posted, stock levels change. The credentials for those connections therefore belong on the replacement list just as much as the customer data itself.
Three locks: mail dispatch, payment, indexing
The first lock concerns mail dispatch. It matters most because a mistake here becomes visible outside immediately: a test run across a thousand orders produces a thousand shipping confirmations to real recipients. The official documentation states explicitly that mail dispatch should be disabled in the staging environment so that no test mails reach real customers (Shopware documentation). The built-in staging mode deactivates dispatch on its own; if it is not used, the switch has to be set by hand. More robust is a second layer: a mail route on the test system that has no exit to the outside at all.
That second layer is worth the effort because a setting inside the application can be reopened by a configuration error or an extension. If the mail route is pointed at a catch-all on the system level, the lock holds even when the application intends otherwise. As a side effect it becomes visible which mails a transaction triggers at all - information that is hard to obtain in production. How sender authentication and deliverability are set up in production is covered in the article on SPF, DKIM and DMARC in the online shop; for the staging domain, the records described there should deliberately look different.
The second lock concerns payment and connected services. Staging mode removes apps with active connections to external services and resets the instance identifier so that no transactions run back from the copy into the production environment (Shopware documentation). The third lock concerns visibility: a test system does not belong in the search index, neither through a forgotten subdomain nor through a reference in a sitemap. The header carrying noindex has to remain reachable - a block in robots.txt only prevents it from being read. How unwanted automated access can be steered overall is shown in the article on bot traffic and scraping in the online shop.
The check belongs at the end of every setup, not in someone's memory. Three queries are enough as a minimum: how many records still carry a mail address outside the reserved suffix, how many log rows are left, and does the start page answer without access protection? If one of those checks runs empty because a table was renamed or an extension created a new one, that is not a green result but a missing measurement. An empty check result and a passed check result look identical in the output - and the difference decides whether the test system can be released.
Access, logging and deletion date
Even a cleaned test system is not a public system. The official documentation recommends protecting the staging environment against unauthorised access with password protection, IP restriction or an upstream login (Shopware documentation). The simplest dependable route is an access prompt at web server level that takes effect before the application and therefore also protects paths the application itself would release. What matters is the exception for interface paths when automated tests run against them - otherwise the test suite only checks the login form. A restriction to known address ranges complements this but does not replace it.
Part of access is the question of who actually has it. Over the life of a project a test system collects accounts from development, the business side, the agency and occasional reviewers; once the project ends, that list usually stays exactly as it is. A short, dated overview of the accounts and a fixed expiry date for the system itself solve this with little effort. We record both points during consulting together with the table list, because experience shows they share one cause: the test system has many users and no owner.
The dump file itself is the overlooked part of the chain. After the import it often still sits in a working directory, a shared folder or a message attachment - unencrypted, without an expiry date and with complete plain text if the replacement only ran on the target. Add the backups of the test system, which multiply the data set once more. Anyone reviewing the chain should therefore look beyond the running system at every place where a copy is parked, and record a deletion date for each of them.
How often a dump gets renewed
A test system loses its value as its data ages: new products, new customer groups and new payment methods are missing, and a defect that only occurs with current data stays undiscovered. A dump pulled too frequently, on the other hand, costs runtime on production and multiplies the number of copies. As a rule a monthly cadence carries well, with additional dumps before larger undertakings - version upgrades, migrations, changes to the data model. What matters is less the interval than the repeatability: a dump that exists as a script gets pulled; a dump made of twelve manual steps gets postponed.
- A script instead of a plan in someone's head: Pulling, replacing, truncating and importing belong in an executable file with an evaluable return code.
- Output into a log file: A run without output provides no signal that a persistent error could show up in.
- Cross-check the numbers: Compare row counts per table before and after the run; a deviation without an explanation aborts the run.
- An expiry date per copy: Dump files and backups get the same deadline as the system they feed.
The cadence has a second side: the less often a dump is pulled, the larger the gap between test and production becomes - and the more often a test run ends with the sentence that it worked on staging. Automating the pipeline makes it possible to shorten the interval without increasing the effort. The backup track follows the same logic and can be verified with the same checks; the article on backup and disaster recovery for online shops describes why a backup only becomes a backup once the restore has been tested.
Failure patterns that typically appear
The first failure pattern is the half replacement. The customer master is cleaned, the transcripts in the orders are not - and because the customer account displays the master record, clicking through does not reveal it. It only becomes visible in an export, on an invoice or in a query across the document data. The counter-check is simple and belongs in every checklist: a count across all tables that can carry a mail address, not just the one that came to mind. If the count finds columns missing from the list, then the list is outdated rather than the data set clean.
The second failure pattern is a test system that measures differently from production. A smaller machine, a cold cache, no upstream accelerator - runtimes from staging are therefore useful for comparing two builds, but not as a statement about what real visitors experience. Why lab values and field data differ, and which number counts in which decision, is set out in the article on field data over lab scores in shop performance. For the test environment this yields a plain rule: function is checked in staging, speed is measured in the field.
The third failure pattern is the silent return channel. A test system whose configuration still points at production counterparts creates transactions nobody expects: an announced shipment, a posted invoice, a reset stock level. The mistake often surfaces days later in the other system, and by then the cause is hard to attribute. What works against it is separation on two levels: different credentials in the configuration and, where possible, a block at network level that rejects connections from the test system to production counterparts. Together they turn a configuration error into an error message rather than a booking.
In which order to retrofit
Anyone tidying up an existing environment makes faster progress by starting with the locks rather than the clean-up. A test system that sends no mail, talks to no external services and stays out of the index does considerably less damage even with uncleaned data than one with clean data and an open exit. Access protection comes next, then the table list, then the replacement, and finally the automation of the pipeline. This order is not a question of elegance but of effect per working hour.
- Set the locks: Disable mail dispatch, cut connections to connected services, deliver noindex and check that the header is reachable.
- Close access: Access prompt in front of the application, exception for the test interfaces, date the list of accounts.
- Record the tables: Capture all tables and columns with a personal reference, custom extensions explicitly included.
- Write the replacement: Define rules per column, keep the references, count the result per table.
- Turn the pipeline around: Move the replacement into the dump step so that no plain text appears on the target system.
- Automate and log: Store the process as a script, write the output into a file, set an expiry date per copy.
What comes out at the end is a test system that matches production in behaviour and not in data. That is the separation that counts: structure, volumes and field lengths stay realistic, the personal reference stays in production. Setting the pipeline up cleanly once also brings a practical side benefit - dumps can be handed on without every handover requiring its own assessment. If you would like a review of what currently sits in your test system, we place that in the context of your e-commerce project and name the points at which the plain text appears.
This article draws on Regulation (EU) 2016/679, cited from its publication in the Official Journal of the European Union L 119/1 of 4 May 2016 and, for Article 33, from the consolidated text 02016R0679-20160504, which carries the corrigendum of 22 November 2016, in particular the definitions in Article 4, the principle of data minimisation in Article 5, the requirements on protection by design and security of processing in Articles 25 and 32, the notification duty in Article 33, the fine brackets in Article 83 and Recital 26 on the distinction between anonymisation and pseudonymisation. The requirements on separated test environments and on handling test data come from the IT-Grundschutz Compendium of the German Federal Office for Information Security, Edition 2023, modules CON.8 Software Development and OPS.1.1.6 Software Tests and Releases. The details on the staging environment, staging mode, mail dispatch and access protection come from the official Shopware documentation. The legal references reflect the state of the respective source and do not replace legal advice in an individual case.
Usually not. A replaced name alongside an unchanged address, order history and sequence of timestamps often still allows attribution; such data counts as information about an identifiable person (GDPR Recital 26). The replacement only becomes dependable once it covers all fields that together identify a person - name, address, mail address, phone number, customer number and the transcripts of those values in the order documents. The field list for that comes from the data model, not from memory, and it grows with every extension of the shop.
Processing for testing purposes is a different purpose from collection for performing a contract. For further processing for another purpose it has to be assessed, among other things, whether appropriate safeguards are in place, which may include encryption or pseudonymisation (GDPR Art. 6 (4)). The baseline protection framework requires at least pseudonymisation for personal test data (BSI IT-Grundschutz Compendium OPS.1.1.6.A11). In practice this means the route via cleaned data is typically far easier to justify than the route via real data with additional measures. For the assessment in an individual case, legal advice is sensible.
On two levels. Inside the application dispatch is switched off; the built-in staging mode does this on its own, and without it the documentation points out explicitly that dispatch should be disabled (Shopware documentation). On the system level the test system additionally gets a mail route with no exit to the outside, so that an extension or a configuration error does not reopen the lock. The second level has a side benefit: you can see which mails a transaction triggers without any of them being delivered.
As long as personal data is processed there, it is a processing activity like any other and belongs in the record accordingly - with purpose, categories of data, recipients, deletion periods and the protective measures in place. That includes the replacement rules, the access protection and the deletion date for the system, the dump files and the backups. If the data set is altered before import so that the data subject can no longer be identified, the principles of data protection stop applying to that data set (GDPR Recital 26); the assessment of whether that has been achieved belongs in the documentation.
That depends on how quickly the assortment, the pricing logic and the customer groups change. Experience suggests a monthly cadence carries well, with additional dumps before version upgrades, migrations and changes to the data model. More important than the interval is that the process exists as a script and writes its output into a log file - a run without output has no signal that a persistent error could show up in. Once the process is automated, the interval can be shortened later without additional effort.
They live outside the database and therefore survive any purely database-level clean-up. Document files, uploaded attachments from contact forms, import and export files and the logs of the web server and the application carry names, addresses and mail addresses. For a test system they are usually not needed and should therefore be left out or emptied. If you would like to know which of these stores get copied along in your environment, we can look at the chain - a short inventory is enough, see contact.