Engineering
Security architecture.
What we build into the product. Updated continuously.
Encryption
- AES-256-GCM envelope encryption at rest. Each verification record is wrapped with a per-record data-encryption key (DEK) encrypted by a customer-master key (CMK) stored in an HSM.
- TLS 1.3 minimum in transit. Forward secrecy. Public-key pinning on critical mobile flows.
- Internal service-to-service traffic over mTLS. Certificates rotated automatically.
Authentication + session
- Passkey / WebAuthn for users where supported. Email + password fallback uses Argon2id hashing.
- Short-lived access tokens (15 min) with rotating refresh tokens. Refresh-token reuse triggers session revocation.
- Device fingerprinting on every session creation — unfamiliar fingerprints downgrade trust until re-verified.
Access control
- Postgres Row Level Security on every table. The default is deny. Specific policies grant access to participants only.
- No raw SQL access from clients. All data is reached via Supabase REST or RPC with the user's JWT.
- Internal admin tooling uses just-in-time elevation: short-lived (15 min) tokens, MFA-protected, every access logged in the audit_log.
OWASP ASVS alignment
The build maps against the OWASP Application Security Verification Standard. Highlights:
- V2 Authentication: Passkey + Argon2id + bot-defence on signup.
- V3 Session: rotating tokens + device binding + refresh reuse detection.
- V4 Access control: Postgres RLS, JWT scope checks, server-side authorisation only.
- V5 Validation: input schema validation at API boundary; output encoded in JSX.
- V6 Crypto: AES-256, Argon2id, HSM-backed master keys.
- V7 Errors + logging: structured logs with PII redaction; audit_log immutable.
- V8 Data protection: data minimisation, encryption at rest, secure deletion.
- V14 Configuration: CSP, HSTS, X-Frame-Options, Permissions-Policy applied on every response.
Logging + audit
Every privileged action lands in the immutable public.audit_log table — admin access to user records, reviewer approvals, exports, data deletions. Rows are append-only and protected by row-level security so even authenticated users cannot read audit entries; only the service_role can. Compliance reviews query this directly.
Incident response
- 24/7 on-call rotation for production incidents.
- Severity-tiered response targets — SEV-1 (data exposure): ack within 15 min, public status within 4 hours, root cause within 5 working days.
- User notification within 72 hours of confirmed PII exposure, per GDPR Art. 33 and the equivalent POPIA requirement.
Disclosing a vulnerability
Mail security@agoditechnologies.com with reproduction steps. We respond within one business day. Coordinated disclosure expected; we publish a public credit once the fix has landed.