How do I prove SOC 2 compliance for a Python Django or Rails app?
Framework Security Features as SOC 2 Evidence
Both Django and Rails include security features that map to SOC 2 controls. Document these in your system description:
| Security Feature | Django | Rails | SOC 2 Control |
|---|---|---|---|
| CSRF protection | Built-in middleware | Built-in token verification | CC6.1 |
| SQL injection prevention | ORM parameterization | ActiveRecord parameterization | CC6.1 |
| XSS protection | Template auto-escaping | ERB auto-escaping | CC6.1 |
| Session management | Django sessions framework | Action Dispatch sessions | CC6.1 |
| Password hashing | PBKDF2 by default | bcrypt by default | CC6.1 |
| Clickjacking protection | X-Frame-Options middleware | X-Frame-Options header | CC6.1 |
Application-Level Evidence
Beyond framework defaults, prove your specific implementation:
Authentication
- Screenshot of your login flow showing MFA (if implemented)
- Code or configuration showing authentication method (Django Allauth, Devise, etc.)
- Session timeout configuration
Authorization
- Your permission model (Django groups/permissions, Pundit/CanCanCan policies)
- Screenshot showing different access levels for different user roles
- API endpoint authorization checks
Data Protection
- Database encryption configuration (RDS, PostgreSQL native)
- Environment variable management (no secrets in code)
- Data handling in views/controllers (what data is logged, what's filtered)
Deployment Evidence
| Evidence | Django Typical Setup | Rails Typical Setup |
|---|---|---|
| CI/CD pipeline | GitHub Actions → Heroku/AWS | GitHub Actions → Heroku/AWS |
| Test suite | pytest results | RSpec/Minitest results |
| Code review | GitHub PR approvals | GitHub PR approvals |
| Dependency scanning | pip-audit, Safety | Bundler-audit, Brakeman |
Tips for Django/Rails Startups
- Run a security scanner before the audit. Use
bandit(Python) orbrakeman(Rails) to catch common issues. - Document your middleware/rack stack. Show the auditor which security middleware is active.
- Check
settings.py/ environment config. Ensure DEBUG=False, SECURE_SSL_REDIRECT=True, and similar production settings are documented.