Security¶
Comprehensive security guide for Accessibility Project Management.
Overview¶
Security is paramount in APM, especially when handling sensitive student data and accessibility materials. This guide covers all aspects of securing your APM instance, from authentication and authorization to data protection and audit compliance.
Security Architecture¶
APM employs a multi-layered security approach:
graph TD
A[Client] -->|HTTPS| B[Reverse Proxy]
B -->|HTTP| C[APM Application]
C --> D[Authentication Layer]
D --> E[Authorization Layer]
E --> F[Data Access Layer]
F --> G[Data Storage: SQLite]
G --> H[File Storage]
D --> I[Session Management]
D --> J[Password Hashing: PBKDF2]
E --> K[Role-Based Access Control]
F --> L[Data Encryption: Fernet]
G --> M[SQLite Encryption]
H --> N[File System Permissions]
O[.secrets] --> C
P[tools.ini] --> C
Q[Audit Logs] --> F
Authentication¶
Password Security¶
APM uses PBKDF2-HMAC-SHA-256 for password hashing with:
- 260,000 iterations (computationally intensive to prevent brute force)
- Random 16-byte salt (unique for each password)
- 32-byte derived key (256 bits of security)
- Base64 encoding (salt + derived key stored together)
Password Hash Generation¶
Generate a secure password hash:
python -c "
import hashlib, os, base64
password = b'your_secure_password_here'
salt = os.urandom(16)
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 260000)
print('ACCESSMAN_PASSWORD_HASH=' + base64.b64encode(salt + dk).decode())
"
** Security Note**:
- Never use simple or dictionary passwords
- Never reuse passwords across systems
- Generate a new hash for each deployment
- Store the
.secretsfile securely
Legacy SHA-256 Support¶
For backward compatibility, APM still accepts 64-character hex SHA-256 hashes, but this triggers a deprecation warning. Use PBKDF2 for all new deployments.
Legacy hash generation (not recommended):
Session Management¶
APM uses NiceGUI's session system with:
- STORAGE_SECRET: Encrypts session data (must be strong and unique)
- Session Timeout: Configurable inactivity timeout (default: 30 minutes)
- Session Isolation: Each user has isolated session data
Generating STORAGE_SECRET¶
Requirements:
- At least 32 characters
- Cryptographically random
- Unique for each deployment
- Never committed to version control
Login Process¶
- User submits username and password
- APM:
- Validates input (rejects empty passwords)
- Looks up password hash from configuration
- Verifies password using PBKDF2 with stored salt
- Checks for account lockout
- Creates session on success
- Session stored in:
- Server-side: Encrypted session data
- Client-side: Session cookie (HttpOnly, Secure if HTTPS)
Failed Login Handling¶
- Max Attempts: Configurable (default: 5)
- Lockout Duration: Configurable (default: 15 minutes)
- IP Tracking: Tracks failed attempts by IP
- Account Lockout: Temporarily disables account after max attempts
- IP Blocking: Optionally block IPs with too many failed attempts
Two-Factor Authentication (2FA)¶
APM supports Time-based One-Time Password (TOTP) 2FA:
Enabling 2FA¶
- Navigate to Admin → Settings → Security
- Enable Two-Factor Authentication
- Configure:
- 2FA Method: TOTP (default)
- Enforcement: Optional or Required
- Issuer: Organization name for authenticator apps
- Users must configure 2FA on next login
User 2FA Setup¶
- User logs in with password
- If 2FA is enabled and not configured:
- User is prompted to set up 2FA
- User scans QR code with authenticator app (Google Authenticator, Authy, etc.)
- User enters verification code
- 2FA is now required for all future logins
Recovery Codes¶
- Users receive 10 recovery codes during setup
- Each code can be used once to bypass 2FA
- Codes are single-use and not regenerated automatically
- Admins can generate new recovery codes for users
Secret Management¶
Environment Variables¶
APM loads sensitive configuration from .secrets file:
# .secrets - NEVER COMMIT TO VERSION CONTROL
# Authentication
STORAGE_SECRET=your_storage_secret_here
ACCESSMAN_PASSWORD_HASH=your_pbkdf2_password_hash_here
ACCESSMAN_VAULT_KEY=your_fernet_key_here
# API
ACCESSMAN_API_AUTH_REQUIRED=1
ACCESSMAN_API_KEY=your_api_key_here
# Database
ACCESSMAN_DB_PATH=/var/lib/accessibility_mgr/database.db
# Development only (DANGER)
ACCESSMAN_UNPROTECTED=0
** Critical**:
.secretsmust be in the repository root (not insideaccessibility_mgr/)- File permissions should be 600 (owner read/write only)
- Never commit
.secretsto version control- Exclude from backups if they contain sensitive data
Authorization¶
Role-Based Access Control (RBAC)¶
APM uses a flexible RBAC system to control user access.
Default Roles¶
| Role | Description | Permissions |
|---|---|---|
| Administrator | Full system access | All permissions |
| Operator | Production operations | Create/edit jobs, run pipelines, view all data |
| Reviewer | Quality review | View jobs, review QA results, approve deliveries |
Permission Categories¶
| Category | Description | Example Permissions |
|---|---|---|
| Jobs | Job management | Create, Read, Update, Delete, Assign |
| Pipelines | Pipeline execution | Create, Run, View status, Cancel |
| QA | Quality assurance | Run tools, View results, Create profiles |
| Reports | Reporting | View, Create, Export |
| Users | User management | View, Create, Edit, Deactivate |
| Settings | System configuration | View, Edit |
| API | API access | Access, Create tokens, Manage keys |
| Admin | Administration | Manage roles, View logs, System maintenance |
Custom Roles¶
Create roles tailored to your organization:
- Navigate to Admin → Roles & Permissions
- Click Create Role
- Define permissions for each category
- Assign to users as needed
Permission Inheritance¶
Permissions can be inherited from other roles:
- Create a base role with common permissions
- Create specialized roles