TL;DR: GDPR Article 25 has two parts. By design means you build data protection into the system when you decide how it will work. By default means the shipped settings process only the personal data each purpose needs. The law names four things those defaults must cover. How much data you collect. How far you process it. How long you keep it. Who can reach it. None of these are legal settings. They are code settings. And code an AI tool wrote ships the opposite defaults unless someone tells it not to. It selects every column. It opens tables to anyone with the public key. It logs full request bodies. It adds tracking you never asked for. This guide maps each 25(2) element to what to look for in an AI-written codebase. It explains what appropriate means for a small team. And it gives you a plan for this week.
Here is how it often goes. A founder builds a SaaS in Lovable, Bolt, or Cursor. It works. Users sign up. A German customer sends a security questionnaire. Question four asks how the product implements data protection by design and by default. The founder searches for a template and writes a paragraph about taking privacy seriously. Then a scan shows the profiles table is readable by anyone. The API returns every column on every user. The server logs each signup email in plain text. The paragraph was true about the founder. It was false about the code.
What Article 25 says, in plain words
Article 25 is short. It has three paragraphs. Only the first two give you work to do.
25(1): Data protection by design
You must put in place technical and organisational measures that make the GDPR principles real. The article gives two examples. Pseudonymisation is a measure. Data minimisation is a principle. You must do this at two moments. First, when you decide how the processing will work. Second, while the processing runs. In other words, before you build, and for as long as the app is live.
The word that matters is appropriate. The article tells you how to weigh it. Look at the state of the art. Look at the cost of implementation. Look at the nature, scope, context and purposes of the processing. Look at the risks to people, both how likely and how severe. We come back to this below, because it is the part that stops small teams from panicking.
25(2): Data protection by default
By default, your system must process only the personal data that each specific purpose needs. The article then lists the four things this covers. The amount of personal data collected. The extent of its processing. The period of its storage. Its accessibility, meaning who can reach it.
Then comes one more sentence, and it is the one that catches AI-built apps. By default, personal data must not be made accessible to an indefinite number of people without the person doing something to allow it. Hold that sentence next to a database table with row-level security turned off. We will.
25(3): A certificate
An approved certificate under Article 42 may be used as one way to show you comply. It is optional. Article 42(3) says the scheme is voluntary. Nobody needs a badge to meet Article 25.
Why AI-written code ships the opposite defaults
An AI coding tool has one job. Make the thing you described work, and work on the first run. That is a good goal for shipping. It is the wrong goal for Article 25, because the fastest path to working is the widest path for data.
USING (true) policy, is the single most common finding on the Supabase-backed apps we scan. Both let every user read every row. That one finding is the last sentence of 25(2) failing in production.The pattern repeats across tools. Ask for a user profile page and the query it writes is select('*'). Every column comes back to the browser. That includes internal flags, other people's email addresses, and fields you added for admin use. Ask for a table and the tool creates it with no policy. A policy would make the demo fail. Ask for error handling and it logs the whole request body, including whatever the user typed. Ask for a landing page and it adds a tracking snippet it has seen in a thousand other projects. Nobody chose any of this. It is what shipped.
That is why Article 25 is a code problem for this audience before it is a policy problem. You cannot fix a default you do not know exists. So the first job is discovery, and discovery means reading the code and scanning the live app.
The four defaults, mapped to your codebase
Here is each 25(2) element next to what AI-written code often does, and where to look.
| 25(2) element | What AI-written code often does | What the law wants by default | Where to look |
|---|---|---|---|
| Amount of data collected | Adds extra fields to every form. Phone, company, date of birth, "just in case". | Only the fields the purpose needs. Optional means not asked for. | Signup and profile forms. Table schemas. The list of columns nobody reads. |
| Extent of processing | Returns whole rows to the client. Sends full user records to an LLM or analytics vendor. | Process each field only as far as the purpose needs. Send the one field the prompt requires. | API handlers. select('*') calls. Third-party SDK init code. Prompt builders. |
| Period of storage | No deletion path. No retention job. Logs kept forever. | A defined period per data type, and a working way to delete when it ends. | Cron or scheduled jobs (often none). Log retention settings. Account deletion flow. |
| Accessibility (who can reach it) | Tables with RLS off or USING (true). Public storage buckets. Admin routes hidden only by the UI. | Private by default. A person's data reachable only by them and by roles that need it. | Database policies. Bucket permissions. Server-side checks on every /admin and /api route. |
Amount: the columns nobody needs
Open your signup flow and count the fields. Now count the ones the product uses. The gap is your 25(2) amount problem. AI-written forms are generous because a longer form looks more complete. Delete the input and the column together. If you need the field later, add it later, with a reason.
Extent: every column to every client
Open the network tab in your browser and load a page that shows another user. Read the JSON. If you see fields that page does not render, your API is over-sharing. The same check applies to what you send out. If a chat feature sends the whole user record to an LLM when it needs a first name, that is extent. So is a marketing SDK that gets the email address on every page view. Our guide to data processing agreements for AI coding tools covers the vendor side of this.
Period: data that never leaves
Most AI-built apps have no retention logic at all. There is no job that clears old sessions, no rule for logs, and account deletion often just sets a flag. 25(2) asks for a default period. Pick one per data type, write it down, and make a scheduled job enforce it. The access and erasure request checklist shows why a working delete path matters twice.
Access: the sentence that names your open table
Read the last sentence of 25(2) again. By default, personal data must not be open to an indefinite number of people unless the person allows it. A Supabase table with RLS off is open to anyone who holds your public anon key. That is anyone who views the page source. That is an indefinite number of people. The user did not allow it. This is the clearest 25(2) failure an AI-built app can have. It is the one we find most.
The fix is not hard. Turn RLS on for every table that holds personal data. Write policies scoped to auth.uid(). Check storage buckets the same way. Then check every admin and API route for a server-side role check. A hidden menu item is not one. Our free Supabase RLS checker lists the open tables, and the RLS policy guide shows the patterns to copy.
One more access gap AI-written code creates: secrets in the client bundle. A service-role key shipped to the browser turns every table public, RLS or not. How to find exposed secrets inside AI bundles and how to secure API keys in Lovable-generated apps both cover this.
What "appropriate" means for a small team
Article 25 does not ask for big-company controls. It asks for appropriate ones, and it tells you how to judge that. Four factors.
- State of the art. What is a normal, available measure today. Row-level security, per-user policies, hashed passwords, encryption in transit, and access logs are all normal and available. Nobody expects you to invent anything.
- Cost of implementation. Cost is weighed, not ignored. A measure that costs a day is fair to ask for. A measure that costs a quarter may not be, unless the risk is high.
- Nature, scope, context and purposes. A waitlist form is not a health app. The same code pattern can be fine in one and serious in the other.
- Risk to people. How likely is harm, and how bad would it be. Payment details, health data, children's data, and location push the bar up.
Put together, this means a two-person SaaS is asked to set sane defaults. It is not asked to run a security team. The defaults in the table above are all cheap. That is exactly why not having them is hard to defend.
Article 32, the security article, uses the same four factors. So the work you do for one counts for the other. Fixing access, encryption, and logging under Article 32 also fixes the access default under 25(2).
How Article 25 connects to the rest of GDPR
Article 25 does not create new rules. It makes you build the existing ones into the system. The links are direct.
- Article 5(1)(c), data minimisation, becomes the amount and extent defaults.
- Article 5(1)(e), storage limitation, becomes the period default.
- Article 5(1)(f), integrity and confidentiality, becomes the access default and overlaps with Article 32.
- Article 5(2), accountability, means you must be able to show you did this. Keep the proof.
Recital 78 adds the reasoning. It lists the kinds of measures the law has in mind. Collect less. Pseudonymise as early as you can. Be open about what the system does. Let people watch their own data. Keep making the security better. It also says producers of products and services should be encouraged to think about data protection when they design. That is a nudge to the tool vendors. It is not a transfer of your duty to them.
Who is on the hook
The duty falls on the controller. For your product, the controller is you. The company that made your coding tool is not the controller of your users' data. Your database host is a processor. Article 28 makes you pick processors that give sufficient guarantees. It makes you sign a contract with them. That does not move the duty across.
This matters because the defaults in AI-written code feel like someone else's choice. They are not. The moment you ship, they are your settings. The same logic runs through the DPIA guide for AI-built apps. The description of processing has to come from the real code. The code does more with data than the prompt asked for.
A code-level checklist
You do not need to be a senior engineer to run this. You need the codebase, a browser, and an hour.
- List every table that holds personal data. Names, emails, IPs, user IDs joined to behaviour, and free-text fields all count.
- Check RLS on each one. On or off. If on, read the policy.
USING (true)is off with extra steps. Our RLS checker does this from the URL. - Grep for
select('*')andSELECT *. Replace each with the columns the page renders. - Open the network tab on three pages. Read every JSON response. Note any field the page does not use.
- Read the logging code. Search for
console.log(req,logger.info(body, and anything that prints a user object. Strip personal data from logs, or hash it. - List every third-party script and SDK. Tracking, session replay, error capture, chat widgets. For each, ask two things. Did you choose it. Does it receive personal data before the user does anything.
- Find the retention logic. If there is none, that is the finding. Write the period per data type and add a scheduled job.
- Check every
/adminand privileged API route. Call it while logged out and as a normal user. A hidden menu is not access control. - Check the client bundle for secrets. Service-role keys, private API keys, and database URLs in shipped JavaScript.
- Check response headers. Missing security headers do not break the app, which is why AI-written code skips them. They are a state-of-the-art measure. The free security headers analyzer shows what is missing.
Do this this week
Five working days is enough for a small app. Most of the time goes into the first two.
- Day 1: Discover. Run a free scan on the live URL and work through the checklist above. Write down every gap, with the file and line where you can.
- Day 2: Close access. RLS on every personal-data table. Owner-scoped policies. Bucket permissions. Server-side checks on privileged routes. Rotate any key that was in the bundle.
- Day 3: Cut amount and extent. Remove unused form fields and columns. Replace
select('*'). Trim what you send to LLMs and tracking tools. Scrub personal data from logs. - Day 4: Set periods. Write a one-page retention table. Add the scheduled deletion job. Make account deletion delete.
- Day 5: Record it. Save the before-and-after scan output. Save the commit list. Write a short note on the four factors and why your measures fit. File it next to your data map.
How to prove it later
Article 25 says do it. Article 5(2) says show you did it. The proof is not a badge. It is a record. The scan that found the gaps. The commits that closed them. The short note on why these measures fit your risk. A one-line answer to "how do you implement data protection by design" is weak. A dated record with proof is strong.
Founders comparing tools for this often start with compliance platforms. We wrote a plain Vanta alternative page for teams who need the gaps found and fixed first. Before there is anything to attest to. And for teams choosing between scanners, Launch Ready Code vs SafeToShip covers what each one checks. A policy platform can help you write the paragraph. It cannot turn RLS on.
See which of the four defaults your app fails today
Run a free scan on your live URL. You get a Launch Readiness Score out of 100, plus the open tables, leaked keys, and missing headers. In 25(2) terms, that is access.
Run a free scanWhere this sits in the wider picture
This is one GDPR duty among several, and it feeds the others. The same code-level facts go into your data map, your DPIA, your vendor contracts, and your breach response. Do the discovery once. Every document gets easier.
If you are starting from zero, our GDPR compliance guide for AI-built apps is the better first read. The compliance checklist covers the full sweep across frameworks. The EU AI Act risk categories guide covers the separate law people mix up with this one. The AI Act has no privacy-by-design duty. Article 25 is GDPR. It applies whether or not your product uses AI.
We do not certify anyone for GDPR. We are not lawyers. What we do is find the defaults your code shipped with. Then we fix the ones the law says should have been private. Our Compliance Wing runs automated checks and a human implementation pass. The plans are on our pricing page.
FAQ
Does GDPR Article 25 apply to a small AI-built startup?
Yes. Article 25 applies to every controller. Size does not matter. Funding does not matter. If your SaaS, websites and apps handle data of people in the EU, the duty is yours. The same goes if you offer services to them. What changes with size is what counts as appropriate. A two-person startup is not asked to run big-company tooling. It is asked to set sane defaults. Per-user data access. Only the fields it needs. A way to delete. No personal data in logs. Those are cheap. That is the point.
Do AI coding tools like Lovable, Bolt or Cursor handle privacy by default for me?
No. They build what you ask for and make it work on the first run. That goal pulls the other way from Article 25. To make a feature work, the code it writes often selects every column. It opens a table to anyone with the public key. It logs the full request. Nobody chose those defaults. They are just what shipped. The tool vendor is not the controller of your users' data. You are. So the fix is yours to make. Check the code rather than trust the prompt.
What is the difference between privacy by design and privacy by default?
By design is Article 25(1). It says you build data protection into how the system works. You do it when you decide how to process data, not after launch. By default is Article 25(2). It says the shipped settings must process only the personal data needed for each purpose. The law names four things this covers. How much data you collect. How far you process it. How long you keep it. Who can reach it. Design is the habit. Default is the setting. An AI-built app often fails on the default side first, because the defaults were never set.
Is an open Supabase table a breach of Article 25?
It is the clearest case there is. The last sentence of Article 25(2) says that, by default, personal data must not be open to an indefinite number of people unless the person allows it. A table with row-level security off, or a policy that returns true for everyone, does exactly that. Anyone with your public anon key can read every row. No user chose that. Fix it by turning RLS on for every table that holds personal data and writing per-user policies. Our free Supabase RLS checker shows you which tables are open.
Do I need a certificate to prove privacy by design?
No. Article 25(3) says an approved certificate under Article 42 may be used to help show you comply. May, not must. Article 42(3) says the scheme is voluntary. What you do need is proof. Keep the scan results that showed the gaps. Keep the commits that closed them. Write a short note on why the measures you chose fit your risk. That record is what a regulator or a big buyer asks for. It is also what Article 5(2) expects.
Can a free security scan show me my Article 25 gaps?
It shows the technical ones, which is where AI-built apps go wrong. A URL-based scan finds open data paths, weak access rules, leaked keys, missing headers, and missing monitoring. Each of those maps to one of the four 25(2) defaults, most often to access. It does not judge whether you need a data field. It does not write your retention rules. It is not legal advice. Use it to get the facts about what your code does today. Then set the defaults the law expects.
Research sources
- GDPR-info.eu — Art. 25 GDPR - Data protection by design and by default, reference for the 25(1) by-design duty, the four 25(2) elements, the indefinite-number sentence, and 25(3) certification.
- GDPR-info.eu — Art. 5 GDPR - Principles relating to processing of personal data, reference for data minimisation (5(1)(c)), storage limitation (5(1)(e)), integrity and confidentiality (5(1)(f)) and accountability (5(2)).
- GDPR-info.eu — Art. 32 GDPR - Security of processing, reference for the security duty that sits next to Article 25 and shares the same four factors.
- EDPB — Guidelines 4/2019 on Article 25 Data Protection by Design and by Default (version 2.0), reference for how regulators read the four factors and the by-default elements.
- Jai Mittal, Founder & CTO, Launch Ready Code — Proprietary data from 700+ AI-built app security audits, 2025–2026. Average Launch Readiness Score: 44/100.