# Security Approach ## Authentication - **Mechanism**: JWT Bearer tokens issued by Azaion Resource API - **Token handling**: Decoded without signature verification (`options={"verify_signature": False}`) — trusts the API server - **Token refresh**: Automatic re-login on 401/403 responses (single retry) - **Credential storage**: In-memory only (Credentials object); not persisted to disk ## Authorization - **Model**: Role-based (RoleEnum with 7 levels: NONE through ApiAdmin) - **Enforcement**: Roles are parsed from JWT and stored on the User object, but **no endpoint-level authorization is enforced** by the loader. All endpoints are accessible once credentials are set. ## Encryption ### Resource Encryption (binary-split scheme) - **Algorithm**: AES-256-CBC with PKCS7 padding - **Key expansion**: SHA-256 hash of string key → 32-byte AES key - **IV**: Random 16-byte IV prepended to ciphertext ### Key Derivation | Key Type | Derivation | Scope | |----------|------------|-------| | API download key | `SHA-384(email + password + hw_hash + salt)` | Per-user, per-machine | | Hardware hash | `SHA-384("Azaion_" + hardware_fingerprint + salt)` | Per-machine | | Resource encryption key | `SHA-384(fixed_salt_string)` | Global (shared across all users) | | Archive decryption key | `SHA-256(key_fragment_from_api)` | Per-unlock operation | ### Binary Split - Resources encrypted with shared resource key, then split into: - **Small part** (≤3KB or 30%): uploaded to authenticated API - **Big part** (remainder): uploaded to CDN - Decryption requires both parts — compromise of either storage alone is insufficient ## Hardware Binding - Hardware fingerprint: CPU model, GPU, memory size, drive serial number - Used to derive per-machine encryption keys for API resource downloads - Prevents extraction of downloaded resources to different hardware ## IP Protection - Security-sensitive modules (security, api_client, credentials, etc.) are Cython `.pyx` files compiled to native `.so` extensions - Key derivation salts and logic are in compiled code, not readable Python ## Secrets Management - CDN credentials stored in `cdn.yaml`, downloaded encrypted from the API - User credentials exist only in memory - JWT tokens exist only in memory - No `.env` file or secrets manager — environment variables for runtime config ## Input Validation - Pydantic models validate request structure (LoginRequest, LoadRequest) - No additional input sanitization beyond Pydantic type checking - No rate limiting on any endpoint ## Known Security Gaps 1. JWT decoded without signature verification 2. No endpoint-level authorization enforcement 3. No rate limiting 4. Resource encryption key is static/shared — not per-user 5. `subprocess` with `shell=True` in hardware_service (not user-input-driven, but still a risk pattern) 6. No HTTPS termination within the service (assumes reverse proxy or direct Docker network)