Introduction
GDPR (General Data Protection Regulation) is a European Union data protection law that applies to any business collecting data from EU residentsโregardless of where your company is located. For indie hackers, compliance isn’t as daunting as it sounds. With focused effort on minimizing data collection, handling consent correctly, and documenting your processes, you can build a privacy-respecting product that operates legally.
This guide covers practical, engineering-focused steps to get compliant without hiring expensive consultants.
Understanding Key Privacy Concepts
What is Personal Data?
Personal data is any information that can identify an individual. Examples include:
- Email addresses and usernames
- IP addresses and device identifiers
- Cookies and tracking IDs
- Location data
- Payment information
- User behavior logs (if linked to an individual)
Key GDPR Terms
- Data Subject: The person whose data you’re collecting (your user)
- Data Controller: The entity deciding why and how data is processed (usually you)
- Data Processor: A service that processes data on your behalf (e.g., Stripe, hosting provider)
- Lawful Basis: The legal reason you can process data (consent, contract, legitimate interest, etc.)
- Data Protection Officer (DPO): A role required for certain organizations (usually not needed for small indie projects)
When Does GDPR Apply?
GDPR applies if you:
- Have users in the EU/EEA, OR
- Target EU residents with your marketing
It doesn’t matter where your servers are located. If you have one EU user, GDPR likely applies.
Practical Steps to GDPR Compliance
1. Conduct a Data Inventory (Data Mapping)
Start by listing exactly what personal data you collect and why. This is your foundation.
Example inventory for a SaaS app:
| Data Type | Why Collected | Retention | Processor |
|---|---|---|---|
| User registration & login | Account lifetime + 30 days | Your database | |
| Password hash | Authentication | Account lifetime | Your database |
| IP address | Security & abuse prevention | 90 days | Your logging service |
| Payment info | Billing | Per law requirements | Stripe |
| Usage analytics | Product improvement | 12 months | Plausible or Fathom |
| Cookies | Session management | 1 year | Your app |
Tools to help:
- GDPR.eu’s Data Inventory Template
- Spreadsheet or simple database to track this
2. Document Your Legal Basis for Processing
For each data type, you need a lawful reason to process it. Common bases for indie products:
- Consent: User explicitly agrees (e.g., newsletter signup, non-essential cookies)
- Contract: Data needed to fulfill a service the user signed up for (email for login)
- Legitimate Interest: You have a valid business reason that doesn’t override user rights (fraud detection, analytics)
Example:
- Email address: Lawful basis = Contract (needed for service delivery)
- Marketing emails: Lawful basis = Consent (user must opt-in)
- Analytics: Lawful basis = Legitimate Interest (product improvement, if not excessive)
3. Create a Privacy Policy
Your privacy policy must clearly explain:
- What data you collect
- Why you collect it
- How long you keep it
- Who has access to it
- Users’ rights (delete, export, etc.)
Template resources:
Example snippet for an indie product:
We collect your email address when you sign up.
We use it to authenticate you and send service updates.
We never sell your email. We delete it within 30 days
if you close your account. You can request a copy of
your data or deletion anytime at [email protected].
Consent & Cookies
Understanding Cookie Consent
Cookies are small files stored on users’ devices. Under GDPR:
- Essential cookies (authentication, security) don’t need consent
- Non-essential cookies (analytics, marketing) require prior consent before storing them
Implementing Consent
- Cookie Banner: Show a banner on first visit explaining what cookies are used
- Consent Granularity: Let users accept/reject different cookie categories separately
- Record Consent: Store proof of when users consented (timestamp, version of policy)
Code example (simple vanilla JS):
// Simplified cookie consent banner
function setupCookieConsent() {
const consentGiven = localStorage.getItem('cookie-consent');
if (!consentGiven) {
showBanner();
}
function showBanner() {
const banner = document.createElement('div');
banner.innerHTML = `
<div style="position: fixed; bottom: 0; width: 100%; background: #f0f0f0; padding: 20px;">
<p>We use cookies for analytics and essential functionality.</p>
<button id="accept-all">Accept All</button>
<button id="reject-non-essential">Reject Non-Essential</button>
</div>
`;
document.body.appendChild(banner);
document.getElementById('accept-all').addEventListener('click', () => {
localStorage.setItem('cookie-consent', JSON.stringify({
analytics: true,
essential: true,
timestamp: new Date().toISOString()
}));
banner.remove();
loadAnalytics();
});
document.getElementById('reject-non-essential').addEventListener('click', () => {
localStorage.setItem('cookie-consent', JSON.stringify({
analytics: false,
essential: true,
timestamp: new Date().toISOString()
}));
banner.remove();
});
}
}
setupCookieConsent();
Cookie Consent Tools (Easier Option)
For indie hackers, using a third-party service is simpler:
- Osano - Free tier available
- CookieBot - Auto-detects cookies
- OneTrust - More enterprise, but comprehensive
- TrustBox - Google’s free option
Data Minimization & Security
Minimization: Collect Only What You Need
This is the simplest GDPR compliance step. Don’t collect data “just in case.”
Bad example: Collecting full user location, phone number, and birthday when you only need email.
Good example: Collecting only email for account creation.
Security Best Practices
Even if you’re compliant legally, you must protect the data you collect:
-
Encryption in Transit: Use HTTPS/TLS everywhere
โ https://yourapp.com โ http://yourapp.com -
Encryption at Rest: Encrypt sensitive data in your database
# Example: Encrypt email using a library like cryptography from cryptography.fernet import Fernet key = Fernet.generate_key() cipher = Fernet(key) encrypted_email = cipher.encrypt(user_email.encode()) -
Access Control: Only authorize team members who need data access
- Use role-based access in your database
- Limit admin panel access
- Never log passwords or tokens
-
Regular Backups: Keep secure backups for disaster recovery
- Encrypt backups
- Store separately from production
- Test restoration regularly
-
Data Deletion: Implement a process to delete data when users request it
-- Example: Delete user and all associated data DELETE FROM users WHERE id = ?; DELETE FROM user_sessions WHERE user_id = ?; DELETE FROM analytics_logs WHERE user_id = ?;
Processing Data Securely
- Database Security: Use strong passwords, keep databases updated
- API Security: Validate all inputs, prevent SQL injection
- Logging: Don’t log sensitive data (emails, passwords, payment info)
Recommended reading:
Handling Data Subject Rights
Under GDPR, users have rights you must honor:
1. Right to Access (Data Portability)
Users can request all their data in a readable format (usually CSV or JSON).
Implementation: Create an endpoint that exports user data
@app.route('/api/export-my-data')
def export_user_data():
user = get_current_user()
data = {
'email': user.email,
'created_at': user.created_at,
'orders': [order.to_dict() for order in user.orders],
'exported_at': datetime.now().isoformat()
}
return jsonify(data)
2. Right to Deletion (“Right to be Forgotten”)
Users can request deletion of their account and data.
Implementation: Hard delete or pseudonymize data
@app.route('/api/delete-my-account', methods=['POST'])
def delete_account():
user = get_current_user()
verify_password(request.json['password']) # Security check
# Delete user and related data
db.session.delete(user)
db.session.commit()
send_confirmation_email(user.email, "Your account has been deleted")
return {'status': 'success'}
3. Right to Rectification
Users can correct inaccurate data.
Implementation: Allow users to update their profile
@app.route('/api/update-profile', methods=['PATCH'])
def update_profile():
user = get_current_user()
user.email = request.json.get('email', user.email)
user.name = request.json.get('name', user.name)
db.session.commit()
return {'status': 'updated'}
4. Right to Object
Users can object to certain processing (like marketing emails).
Implementation: Respect unsubscribe and preference settings
@app.route('/api/unsubscribe/<token>')
def unsubscribe(token):
user = User.verify_unsubscribe_token(token)
user.marketing_emails = False
db.session.commit()
return render_template('unsubscribed.html')
Data Processing Agreements (DPAs)
If you use third-party services (hosting, analytics, payment processors), they are your Data Processors. You must have signed Data Processing Agreements with them.
Services that likely need DPAs:
- Cloud hosting (AWS, Heroku, DigitalOcean)
- Analytics (Google Analytics, Mixpanel, Plausible)
- Payment processors (Stripe, PayPal)
- Email services (SendGrid, Mailgun)
- CRM tools (HubSpot, Intercom)
Check if your vendor has DPA: Most major services offer GDPR-compliant DPAs. Look for:
- “Data Processing Agreement” or “DPA” on their legal page
- Confirmation they process data in GDPR-compliant jurisdictions
- Standard Contractual Clauses (SCCs) for data transfers
Example vendors with free DPAs:
- Stripe GDPR
- Plausible Analytics (privacy-first, no DPA needed)
- Fathom Analytics
When to Seek Legal Help
While GDPR compliance is manageable for indie hackers, consult a lawyer if:
1. You Process Sensitive Data
Examples:
- Health/medical information
- Biometric data
- Financial/payment records
- Racial or ethnic origin
Requirement: You may need a Data Protection Impact Assessment (DPIA)
Resources:
2. You Operate in Multiple Countries
Different regions have their own privacy laws:
- EU/UK: GDPR (most comprehensive)
- California: CCPA (similar to GDPR)
- Canada: PIPEDA
- Brazil: LGPD
- Australia: Privacy Act
3. You Plan Enterprise Customers
Enterprise customers often require:
- Security certifications (SOC 2, ISO 27001)
- Detailed security questionnaires
- Business Associate Agreements (BAAs)
4. You’ve Had a Data Breach
You must notify:
- Affected users
- Regulatory authorities (within 72 hours)
- Have a incident response plan
Find a lawyer:
- GDPR.eu’s Lawyer Directory
- European Commission DPA Database
- Budget: โฌ500-2,000 for basic privacy policy review
Tools & Resources for Indie Hackers
Privacy Policy Generators
- Termly - AI-powered, free tier
- iubenda - Comprehensive, ~โฌ10/month
- Shopify Privacy Policy Generator - Free, simple
Cookie Consent Tools
Data Inventory & Compliance Tracking
- Tines - Automation workflows for compliance
- Vanta - Compliance monitoring (more expensive)
- Spreadsheet template (free, DIY)
Security & Encryption Libraries
- Python:
cryptography,bcrypt - JavaScript:
libsodium.js,tweetnacl.js - Go:
crypto/aes(built-in) - Database encryption: PostgreSQL
pgcrypto, MySQL encrypted fields
Educational Resources
- GDPR.eu - Official EU GDPR resource
- ICO Guidance - UK Information Commissioner’s Office
- Data Protection Commission - Irish DPC (most active in enforcing GDPR)
- Privacy by Design Framework - Practical guide
Final Thoughts
GDPR compliance is a combination of legal, technical, and organizational steps. The good news: for indie products, it’s manageable without breaking the bank. Start with these fundamentals:
- Minimize what you collect
- Secure what you do collect
- Document everything
- Respect user rights
Scale your compliance efforts as your business grows. A compliant product earns user trust and reduces legal risk.
Action Items for This Week:
- Create a data inventory spreadsheet (what you collect and why)
- Write or generate a privacy policy
- Implement a cookie consent banner
- Add a data export endpoint (
/api/export-my-data) - Enable HTTPS if you haven’t already
Next Steps (Month 1):
- Implement user deletion functionality
- Review and sign DPAs with your third-party vendors
- Test your data export/deletion flows
- Document your data retention policy
Comments