Security & Privacy¶
Overview¶
Nigall security combines Django session/JWT authentication, role and plan-based authorization, HTTPS deployment practices, Stripe PCI delegation, GDPR tooling in the Attendees module, and email unsubscribe compliance.
Purpose¶
Protect participant data, payment integrity, and organizational compliance obligations.
Who should use it¶
- Security reviewers
- Organizers handling PII
- DPOs evaluating GDPR features
- DevOps hardening production
Benefits¶
- No card data stored locally (Stripe Checkout)
- GDPR export/delete workflows
- Unsubscribe tokens for email
- Event-scoped host authorization
Navigation path¶
| Topic | Path |
|---|---|
| Privacy center | /attendees/privacy/ |
| Email preferences | /communications/preferences/ |
| Unsubscribe | /communications/unsubscribe/<token>/ |
| Event compliance | /attendees/events/<pk>/<tag>/compliance/ |
| Security settings | Deployment / core/settings.py |
Prerequisites¶
- HTTPS enabled in production
- Secure cookie flags configured
- Stripe webhook signature verification
- Email provider authentication (SES/Resend)
Authentication¶
| Surface | Mechanism |
|---|---|
| Web | Django session + django-allauth |
| Mobile API | JWT bearer tokens |
| Webhooks | Provider signatures (Stripe, SES) |
| Admin | Django staff/superuser |
Authorization model¶
flowchart TD
User[Authenticated user] --> Host{event.host?}
Host -->|Yes| Manage[Event management]
Host -->|No| Participant[Participant flows]
Staff[is_staff] --> Admin[Admin queues + tool bypass]
See Roles & Permissions.
Data protection¶
| Feature | Description |
|---|---|
attendee_gdpr_enabled |
Enables formal GDPR flows |
| Data retention | 1/2/5 years per event |
| Export | Attendee-initiated + host compliance export |
| Deletion | Request queue with host completion |
| Networking visibility | User-controlled opt-in |
Payment security¶
- Card data handled by Stripe hosted Checkout
- Webhook verifies events before ticket issuance
- Platform fee metadata in session — not client-trusted
Email compliance¶
- Unsubscribe links with UUID tokens
- SES bounce/complaint webhook
- Preference center at
/communications/preferences/
Business rules¶
| Rule | Detail |
|---|---|
| Private events | Not listed on Discover |
| Host-only PII | Guest lists not public |
| Lead capture | Exhibitor scan requires attendee QR opt-in context |
| SMS | Logged only without provider — reduces accidental send |
Validation rules¶
- CSRF on web forms
- JWT expiry on mobile
User permissions¶
Documented per feature — default deny for management actions.
Examples¶
GDPR request: Attendee requests deletion → host completes on compliance dashboard.
PCI: Organizer never touches raw card numbers.
Best practices¶
- Force HTTPS and HSTS
- Rotate Stripe webhook secrets periodically
- Minimize staff account count
- Enable GDPR for EU events
- Use environment variables for secrets (never commit
.env)
Tips¶
- Media on S3 with private ACLs when
USE_S3=True - Review
ALLOWED_HOSTSon deploy
Common mistakes¶
| Mistake | Result | Fix |
|---|---|---|
| DEBUG=True in prod | Leak stack traces | Set DEBUG=False |
| Shared host password | Account compromise | Individual accounts |
FAQs¶
Where is data stored?
Database + media storage (local volume or S3 per deployment).
SOC2 certified?
Organizational claim — verify with Nigall sales for your contract.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| Session hijack concern | HTTP cookies | Enforce HTTPS |
| Webhook replay | Misconfig | Verify signatures |
Related features¶
Screenshot placeholders¶
[SCREENSHOT: Privacy center delete request][SCREENSHOT: Unsubscribe confirmation]
Administrator notes¶
- Run dependency security updates
- Backup database and media
- Incident response: rotate keys, audit
is_staffusers
Developer/API notes¶
SECRET_KEY,STRIPE_*, email credentials in environment- JWT settings in mobile API configuration
- GDPR views:
attendees/privacy_views.py
See also: Known Limitations