EventSync follows five core rules:
- Authentication identifies the user.
EventMembershipdetermines the user's role for an event.- Server-side authorization is the real security boundary.
- Event IDs and team IDs are always checked against the current user's permissions.
- Secrets never belong in source control or browser-exposed configuration.
JWT authentication is used for API access.
Login
↓
Access token + refresh token
↓
Protected API request
↓
JWT validation
↓
Current user
Password verification is handled through Django's authentication system.
Never do this:
@if email.endsWith("@eventsync.io") → organizer
Instead:
JWT
↓
User
↓
EventMembership
↓
role + is_active + event
Supported event roles:
participantjudgeorganizer
Every event-scoped operation should verify the target event.
Example:
Organizer of Event A
↓
request Event B
↓
EventMembership check
↓
403 / reject
This applies to:
- people management
- event settings
- tracks
- judge assignments
- judging visibility
- teams
- submissions
- check-ins
- announcements
Team administration is separate from event administration.
Event Organizer
→ Event-level operations
Team Leader
→ Team-level operations
Normal Member
→ Member operations
Non-member
→ No team administration
A team leader is determined by the database relationship rather than a frontend flag.
When judge assignments are active for an event:
Judge A
→ sees Assignment A
Judge B
→ sees Assignment B
Judge B
→ must not see Assignment A
Cross-event judge or submission assignments are rejected.
The frontend must never be considered a trusted security boundary.
This is insufficient by itself:
if (role === "organizer") {
showOrganizerButton();
}The backend must separately reject unauthorized requests.
Never commit:
- Django
SECRET_KEY - JWT secret keys
- database credentials
- external API keys
- private access tokens
- real user passwords
VITE_* variables are browser-visible and therefore must contain only public configuration.
Production CORS should explicitly allow the deployed frontend origin.
Expected origin:
https://event-sync-ten.vercel.app
Do not use unrestricted authenticated CORS such as:
allow_origins=["*"]
Django Admin is a technical administration surface.
It should not be treated as the same thing as the Organizer UI.
Recommended practice:
- restrict admin credentials
- use strong passwords
- avoid sharing superuser accounts
- minimize who receives Django staff/superuser privileges
- do not expose admin credentials in repository documentation
Seeded demo accounts are for competition demonstration only.
They should be:
- isolated from real production users
- rotated or removed before a real event
- documented as demo credentials, not operational credentials
[ ] Rotate all secrets
[ ] Disable or replace demo users
[ ] Verify production CORS
[ ] Verify ALLOWED_HOSTS
[ ] Verify DEBUG=False
[ ] Review Django Admin access
[ ] Verify organizer memberships
[ ] Verify judge assignments
[ ] Verify event isolation
[ ] Verify backups for PostgreSQL
[ ] Remove unused environment variables
[ ] Re-test auth and privileged APIs