Ensuring website compliance with GDPR requirements
GDPR (General Data Protection Regulation) is an EU regulation on personal data protection effective since 2018. Applies to any website processing data of EU citizens, regardless of server location. Penalties: up to €20 million or 4% of global revenue.
Six legal bases for personal data processing
- Consent — explicit, revocable, specific
- Contract — necessity for contract fulfillment
- Legal obligation — law requirements
- Vital interests — life protection
- Public task — government functions
- Legitimate interest — commercial interests (balance test)
Most commercial websites use consent and contract.
Technical measures (GDPR Art. 25 & 32)
Privacy by Design:
class UserRegistrationRequest extends FormRequest
{
public function rules(): array
{
return [
'email' => 'required|email',
'password' => 'required|min:8',
];
}
}
class AnalyticsEventService
{
public function track(User $user, string $event): void
{
AnalyticsEvent::create([
'user_pseudonym' => hash('sha256', $user->id . config('app.analytics_salt')),
'event' => $event,
]);
}
}
Data subject rights (GDPR Art. 15-22)
| Right | Response Time | Implementation |
|---|---|---|
| Access (Art. 15) | 1 month | Export data in account |
| Correction (Art. 16) | 1 month | Edit profile |
| Deletion (Art. 17) | 1 month | Delete account button |
| Restriction (Art. 18) | 1 month | Processing freeze |
| Portability (Art. 20) | 1 month | JSON/CSV export |
| Objection (Art. 21) | Without delay | Newsletter unsubscribe |
class GdprUserDeletionService
{
public function deleteUser(User $user): void
{
DB::transaction(function () use ($user) {
$user->update([
'name' => 'Deleted user',
'email' => 'deleted_' . $user->id . '@deleted.invalid',
'phone' => null,
]);
$user->consents()->delete();
$user->addresses()->delete();
$user->tokens()->delete();
$user->update(['deleted_at' => now(), 'anonymized_at' => now()]);
});
event(new UserDataDeleted($user->id));
}
}
Data Processing Agreements (DPA)
Each data processor service must have DPA:
- Sendgrid/Mailchimp — available online
- Google Analytics — GA4 + DPA + IP anonymization
- Stripe — built into Terms of Service
- AWS/GCP/Azure — available in console
Data breach notification (Art. 33-34)
class DataBreachService
{
public function notifySupervisoryAuthority(DataBreach $breach): void
{
BreachNotification::create([
'breach_id' => $breach->id,
'notified_authority' => $this->getCompetentAuthority($breach),
'notified_at' => now(),
'notification_ref' => $this->submitToAuthority($breach),
]);
}
public function notifyDataSubjects(DataBreach $breach): void
{
if ($breach->risk_level === 'high') {
$breach->affectedUsers()->each(function (User $user) use ($breach) {
Mail::to($user)->queue(new DataBreachNotificationMail($breach));
});
}
}
}
Implementation Timeline
- Gap analysis of current state: 2–3 days
- Technical measures (encryption, rights, cookie banner): 7–14 days
- Documentation (ROPA, DPA, policies): 3–5 days
- Testing deletion/export processes: 2–3 days
- Total: 3–5 weeks for typical SaaS







