Security and Compliance
SecuFile — Security and Compliance
Security and Compliance
Security and Compliance
Encryption Architecture
SecuFile uses a multi-layered hybrid encryption architecture:
Layer 1: Encryption in Transit (TLS)
All communications between clients and servers use TLS 1.3. Certificates are automatically managed by the Nginx Ingress Controller on the OVH Kubernetes cluster.
Layer 2: Encryption at Rest (S3)
Files stored in OVH S3 are already encrypted at rest by the provider. SecuFile adds an additional layer of application-level encryption.
Layer 3: Application Encryption (AES-256-GCM)
Each file is encrypted with a unique DEK (Data Encryption Key):
- AES-256-GCM: Authenticated encryption algorithm
- 12-byte nonce: Randomly generated for each file
- 16-byte tag: Authentication tag for integrity
- Chunked: Large files are split into blocks with derived nonces (baseNonce XOR chunkIndex)
Layer 4: Key Protection (RSA-4096 + KMS)
DEKs are protected by the key management system:
- RSA-4096: Each organization has an RSA-4096 key pair (PKCS1 / PKIX PEM format)
- RSA-OAEP: Asymmetric encryption algorithm with SHA-256 (matching Web Crypto API, nil label)
- KMS: The RSA private key is encrypted by the KMS before storage
- PBKDF2: 600,000 iterations (OWASP 2023 recommendation) for password-based key derivation
- Base64: The encrypted key is Base64-encoded for storage in PostgreSQL (TEXT column)
Encryption Diagram
Original file
|
v
[AES-256-GCM] <-- DEK (random 256-bit key)
| |
v v
Encrypted file [RSA-OAEP] <-- RSA-4096 public key
(stored in S3) |
v
Encrypted DEK
(stored in PostgreSQL)
|
RSA private key
|
v
[KMS WrapKey]
|
v
Encrypted private key + Base64
(stored in PostgreSQL)Regulatory Compliance
Loi 25 (Quebec)
Quebec's Act Respecting the Protection of Personal Information in the Private Sector requires:
- Informed consent: SecuFile displays a configurable consent text per organization before any upload via share link. Acceptance is traced in the audit trail.
- Data minimization: E2E encrypted files are never accessible to the server.
- Right of access and rectification: Users can view and delete their files.
- Breach notification: The complete audit trail allows tracing all operations.
- Data residency: Data is stored in Quebec (OVH BHS, Beauharnois).
PIPEDA (Canada)
- Accountability: Each organization has a responsible administrator.
- Consent: Consent mechanism for share links.
- Limiting use: Data isolation per organization.
- Security safeguards: E2E encryption, MFA, rate limiting, CSRF protection.
GDPR (European Union)
- Legal basis: Explicit consent for share links.
- Right to erasure: File and account deletion.
- Portability: File export.
- Data residency: Storage option in France (OVH GRA, Gravelines).
Audit Trail
Every action is recorded in the audit_logs table with:
user_id: User performing the actionaction: Action type (login, file_upload, share_link_access, etc.)resource_type: Resource type (file, folder, share_link, etc.)resource_id: Resource IDdetails: JSON action detailsip_address: User IP addressuser_agent: User browsercreated_at: Timestamp
Tracked Actions
| Action | Description |
|---|---|
login | Successful login |
login_failed | Failed login attempt |
account_locked | Account locked (5 failures) |
file_upload | File upload |
file_download | File download |
file_delete | File deletion |
folder_create | Folder creation |
folder_delete | Folder deletion |
share_link_create | Share link creation |
share_link_access | Share link access |
share_link_download | Download via share link |
share_link_upload | Upload via share link |
consent_accepted | Loi 25 consent acceptance |
transfer_create | Transfer creation |
user_create | User creation |
password_reset | Password reset |
Threat Protection
Brute Force
- Account lockout: 5 failed attempts = 15-minute lockout
- Rate limiting: 20 requests/minute on authentication endpoints
- JWT expiration: Access tokens valid for 15 minutes only
CSRF
- ContentTypeMiddleware: Rejects "simple" Content-Types (text/plain, x-www-form-urlencoded) on state-changing requests (exempt: Stripe webhook)
- Strict CORS: Explicitly listed allowed origins
- No credentials:
Access-Control-Allow-Credentialsheader suppressed
Injection
- Prepared statements: All SQL queries use parameterized queries ($1, $2...)
- Input validation: Gin binding validation on all handlers
- Body limit: 1 MB global, 25 MB for uploads only
Antivirus
- ClamAV: Optional scanning of uploaded files before storage
- Configurable: Enabled/disabled via
CLAMAV_ENABLED