GDPR is not just a document to make your client sign. It is a set of technical obligations that, if not implemented in code, exposes you to fines and, worse, data leaks. We see it every day in projects that come to us: forms saving plain text in MySQL without any protection, cookies without tracked consent, logs exposing emails and poorly hashed passwords. No need for alarmism — you need to understand what a developer must do to make an application compliant. We, at Meteora Web, have been working with SMEs for over 8 years, and we have learned that privacy is not an option: it's architecture.
Why GDPR is About Code, Not Just a Privacy Policy
The General Data Protection Regulation directly impacts: database design, session management, logging, encryption, APIs, consent, portability, and deletion. If you think a cookie banner and a Privacy Policy page are enough, your client is at risk. We have seen WordPress plugins storing personal data in post meta without any encryption, or Laravel applications keeping unlimited sessions in files. The problem is that many developers don't know that every personal data has a lifecycle: collection, processing, storage, deletion. The code must handle it.
Data Mapping: Know What and Where Before Writing a Line
Before implementing any feature, you must know: what personal data does the application collect? Where is it stored? How long is it retained? Who can see it?
Create an Inline Data Register in Code
No need for a separate Excel sheet. You can document it with structured comments or in a JSON file in the repository. We use an associative array in PHP with table, fields, purposes, legal basis, and retention. Example:
$data_map = [
'users.name' => [
'purpose' => 'Account registration',
'legal_basis' => 'Contract performance (Art. 6.1.b)',
'retention' => 'Until account deletion + 12 months for tax',
'encrypted' => false, // stored in DB, not sensitive
],
'users.email' => [
'purpose' => 'Communication, login',
'legal_basis' => 'Contract performance',
'retention' => 'Until account deletion or consent withdrawal',
'encrypted' => false,
],
'payments.card_last_four' => [
'purpose' => 'Payment reference',
'legal_basis' => 'Legal obligation (Art. 6.1.c)',
'retention' => '10 years for tax',
'encrypted' => true,
],
];
This allows you to automatically generate a report for the DPO and to have every field under control.
Practical Tools for Mapping
Use database functions (information_schema in MySQL) to extract tables with personal data. A simple SQL script gives you the list:
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_db_name';
Then manually filter sensitive columns. There is no perfect automation, but it reduces risk.
Consent: Not Just a Banner, Track It
GDPR requires consent to be: specific, informed, unambiguous, and revocable. A banner saying "Accept All" without granularity per purpose is non-compliant. The regulation requires that consent must be demonstrable (Art. 7.1).
Implementing Tracked Consent
Do not use third-party cookies without explicit consent. The most robust method is to save a JSON string in localStorage (or a signed technical cookie) with a timestamp and the user's choice. Example with vanilla JavaScript:
function setConsent(preferences) {
const data = {
version: '1.0',
timestamp: new Date().toISOString(),
preferences: preferences // {analytics: true, marketing: false, necessary: true}
};
// Save in localStorage (not sent to server automatically)
localStorage.setItem('gdpr_consent', JSON.stringify(data));
}
Then, in your script activation functions, read consent before loading Google Analytics or Meta Pixel. If the user revokes, clear the localStorage item and stop the scripts.
Warning: Do not use a pre-checked checkbox. Consent must be opt-in.
Data Subject Rights: Access, Rectification, Erasure, Portability
Every user has the right to know what you hold about them, to obtain a copy, to request modification or deletion. You must implement it in the back-end.
API for Data Export
In Laravel, you can create an endpoint that collects all data linked to a user and returns a downloadable JSON. Example:
// routes/api.php
Route::get('user/data-export', function (Request $request) {
$user = $request->user();
$personalData = [
'profile' => $user->only(['name', 'email', 'created_at']),
'orders' => $user->orders()->get()->toArray(),
'support_tickets' => $user->tickets()->get()->toArray(),
];
return response()->json($personalData)->withHeaders([
'Content-Disposition' => 'attachment; filename="personal-data.json"',
]);
})->middleware('auth:sanctum');
Make sure to encrypt the file if sent by email, and provide the export within 30 days (Art. 12.3).
Hard Delete vs Soft Delete
Erasure request (right to be forgotten, Art. 17) must be permanent if there are no legal retention obligations. Do not just set a 'deleted_at' flag if data remains accessible. Implement a cron job that, after the retention period, physically DELETEs or anonymizes sensitive fields.
-- Anonymization: overwrite email with irreversible hash
UPDATE users
SET email = CONCAT('deleted-', id, '@example.com'),
name = 'Deleted User',
updated_at = NOW()
WHERE deleted_at IS NOT NULL
AND deleted_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
Technical Security Measures: Encryption and Pseudonymization
GDPR does not prescribe specific algorithms (Art. 32), but requires measures appropriate to the risk. We recommend at least:
- Encryption at rest (AES-256) for DB if you host health or financial data.
- Encryption in transit (TLS 1.3) for all communications.
- Pseudonymization: replace direct identifiers with a unique ID for analysis.
Example of Application-Level Encryption in PHP
// Use openssl with a key derived from a strong password (not hardcoded)
function encryptData($plaintext, $key) {
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, 0, $iv, $tag);
return base64_encode($iv . $tag . $ciphertext);
}
function decryptData($encoded, $key) {
$data = base64_decode($encoded);
$iv = substr($data, 0, 16);
$tag = substr($data, 16, 16);
$ciphertext = substr($data, 32);
return openssl_decrypt($ciphertext, 'aes-256-gcm', $key, 0, $iv, $tag);
}
Store the key in environment variables, never in code. On Linux servers, use openssl enc -aes-256-cbc for encrypted backups.
Data Breach: Logging and Mandatory Notification
In case of a data breach, notification to the supervisory authority must be made within 72 hours (Art. 33). To do that, you need detailed logs of anomalous accesses and modifications to personal data.
Implement Structured Logging Without Exposing Sensitive Data
// Example with Monolog (Laravel)
use Monolog\Handler\StreamHandler;
$logger = new \Monolog\Logger('security');
$logger->pushHandler(new StreamHandler(storage_path('logs/security.log'), \Monolog\Level::Warning));
$logger->warning('Failed login attempt', [
'user_id' => $userId,
'ip' => $request->ip(),
'timestamp' => now(),
// NEVER log passwords or tokens
]);
Logs must be stored securely, with restricted access and automatic rotation (logrotate). Never log passwords, session cookies, authentication tokens, or biometric data.
Controller vs Processor Liability: Contracts with Third Parties
If you use external services (Google Analytics, Mailchimp, AWS), you must sign a Data Processing Agreement (DPA) with each. Most providers offer pre-signed ones. But as a developer, you must ensure the technical integration respects GDPR: for example, do not send data to Google Analytics before consent, do not share full email addresses with advertising platforms without anonymization.
In Summary — What to Do Now
- Map personal data in your application: create a register with table, field, purpose, retention.
- Implement granular consent tracking: save user preferences in localStorage, do not load tracking scripts before consent.
- Create endpoints for access, export, and erasure: the user must be able to exercise their rights via UI.
- Encrypt sensitive data: use AES-256 at rest, TLS 1.3 in transit, pseudonymize IDs.
- Log security events: without recording personal data, but sufficient to reconstruct a breach.
- Verify DPAs with external vendors: do not assume the client has it covered.
We at Meteora Web see every day websites and apps that do not meet even the basic requirements. It is not bureaucracy — it is about protecting people. And if you are a developer, it is your technical responsibility. Start today: GDPR does not wait.
Sponsored Protocol