Technical and organizational measures
Last updated November 9, 2026
These are the measures ULB Media (Pty) Ltd keeps to protect personal data processed through OnSanctions, as Article 32 of the GDPR and section 19 of POPIA require. They are Annex 4 of the data processing agreement. OnSanctions runs entirely on managed infrastructure; we operate no servers or data centers of our own.
1. Confidentiality
Physical access
Data is held only in the data centers of our subprocessors: Cloudflare (hosting and the D1 database, restricted to the European Union), VerifyNow (screening, Cape Town) and Stripe (payments). Their physical controls are covered by their ISO/IEC 27001, SOC 2 and PCI DSS programs. No customer data is kept on laptops or office systems.
System access
- Production consoles (Cloudflare, Stripe, VerifyNow) are limited to the named people who run the service.
- Application secrets are stored as encrypted Cloudflare secrets, never in source code, and are rotated if a leak is suspected.
- Customer passwords are hashed with bcrypt (cost 12). Sign-in and sign-up are rate limited per IP address.
- Sessions are signed tokens in a host-only, HTTP-only, secure cookie, expire after 12 hours, and are revoked on every device when the user signs out.
Data access
- Every query is scoped to the customer's organization. Owners and developers have separate roles.
- API keys are shown once and stored only as SHA-256 hashes. Keys can be limited to IP addresses and revoked at any time.
- The API returns only an allowlisted set of response fields from the screening engine.
Separation
- Test keys use a mock engine and never reach live screening or billing.
- Card data is handled only by Stripe, a PCI DSS Level 1 service provider, and never touches our systems.
Pseudonymization and minimization
- We never store a readable name or identifier. The subject map holds a keyed HMAC-SHA-256 fingerprint of the identifier and a random numeric reference.
- The passport number or LEI is never sent to the screening engine. The engine holds the name and reference only as keyed digests.
- Quick check names are screened and shown, not stored.
- Logs record time, key prefix, route, status and request ID, never names or identifiers.
2. Integrity
Transmission and storage
- All traffic uses HTTPS, with HTTP Strict Transport Security on onsanctions.com.
- Cloudflare D1 encrypts data at rest. Full screening responses at the engine are encrypted and expire after 48 hours.
- Webhooks we send are signed with HMAC-SHA-256 and a timestamp. Webhooks we receive from Stripe are verified by signature.
- Webhook destinations are checked to block private, internal and reserved network addresses.
Input and change control
- Write requests require an idempotency key, so a retried request can't enroll a subject twice.
- Every API call is logged with a request ID that the customer can see and export.
- Code changes are tracked in version control and pass an automated integration test suite before each deploy.
Destruction
A scheduled job deletes call and webhook logs after 30 days, idempotency records after 48 hours and unused invites after 7 days. Account data is deleted within 30 days of an account ending.
3. Availability and resilience
- The website and API run on Cloudflare's global network, with no single server to fail.
- The database supports point-in-time recovery through Cloudflare D1 Time Travel. We take a restore point before each schema change.
- Per-organization and per-IP rate limits protect the service from overload and abuse.
- The screening engine has its own availability and backup controls, described in VerifyNow's information security documentation.
4. Testing, assessment and evaluation
- An integration test suite covers authentication, access control, rate limits, billing, webhooks and data deletion, and runs before each release.
- Code is reviewed for security issues, and findings are fixed and tested before release.
- Dependencies are kept up to date, and security advisories are reviewed when published.
- Anyone can report a vulnerability under our responsible disclosure policy.
5. Organizational measures
- Everyone with access to personal data is bound to confidentiality and gets access only to what their role needs.
- An information officer is registered under POPIA and handles data protection requests at privacy@onsanctions.com.
- Breaches are handled under an incident response process, with notice to affected customers within 48 hours of becoming aware.
- Each subprocessor is bound by a data processing agreement and listed on the subprocessors page.
6. Data protection by design and by default
OnSanctions is designed to screen without keeping what it screens: no stored names or identifiers, keyed fingerprints instead of raw values, short-lived logs, and only strictly necessary cookies. We collect only what we need to run, bill and secure the service.