Security
This page describes what is implemented today, including its limitations. It is updated when the implementation changes.
Access we request
- AWS: a cross-account IAM role you create, assumed with a per-organisation External ID, carrying a read-only policy that lists exactly the API actions the checks use. Long-lived access keys are still accepted for compatibility but are discouraged.
- GitHub: a GitHub App with read-only permissions (recommended), a fine-grained read-only token, or OAuth. Note that GitHub's OAuth
reposcope technically grants write access; the product never uses write endpoints, but prefer the App or a read-only token. - The platform only calls read APIs. Remediation is guidance for you to apply; nothing is changed automatically.
Encryption
- Integration credentials, MFA secrets, uploaded documents and report exports are encrypted at rest with AES-256-GCM under a separate data key for each organisation. Each ciphertext is bound to its organisation and purpose. Data keys are stored only in wrapped form; the key that wraps them comes from server configuration or, when configured, stays inside Azure Key Vault. Items stored before this scheme use the previous format (Fernet: AES-128-CBC with HMAC-SHA256) until they are migrated.
- Credentials are decrypted only in the process that performs a scan and are never shown back in the UI.
- Transport security (TLS) is provided by the hosting platform; secure, HttpOnly, SameSite session cookies are enforced in production.
- Database-level encryption at rest depends on your hosting provider configuration.
Application security controls
- Passwords are hashed with scrypt. Optional TOTP two-factor authentication, which organisations can require for all members.
- Login throttling per account and per IP address; hashed, expiring email verification codes.
- Role-based access control with seven roles; every data access is scoped to your organisation on the server.
- CSRF protection on all state-changing requests, a strict Content Security Policy and other security headers.
- Security-relevant actions (sign-ins, integration changes, exports, approvals) are recorded in an audit log visible to organisation administrators.
Evidence integrity
Evidence records are append-only in the application and each includes a SHA-256 content hash chained to the previous record, so modification or deletion is detectable. Records are then sealed into batches whose Merkle roots are chained and, where signing is enabled, signed. This provides tamper evidence, not a guarantee of legal admissibility.
Evidence packages carry these proofs with them. An auditor can verify a package on their own computer, with the offline verifier included in every package or with verify.py, and compare the signing key with the one we publish.
Deletion
Disconnecting an integration deletes its stored credentials immediately (and revokes GitHub OAuth tokens where possible). Deleting an organisation ends access and destroys its credentials immediately; everything else is erased permanently 30 days later. Evidence is deleted at the end of your plan's retention period, oldest first, and the integrity check verifies the remaining chain from the deletion checkpoint. Retention periods for every kind of record are listed in the privacy policy.
Known limitations
- Uploaded files are validated by type but not yet scanned by an antivirus engine.
- Single sign-on (SAML/OIDC) and SCIM provisioning are not available yet.
- No independent penetration test has been published yet.
Reporting a vulnerability
Please test only against your own account and data, avoid degrading the service, and give us reasonable time to fix the issue before you disclose it. Machine-readable contact details are in /.well-known/security.txt.
TrustEvidence