Security and compliance posture

The mechanisms that actually exist, each named with the artefact that evidences it.

This page describes implemented and in-build controls. Where a control is in build we say so rather than implying coverage; where a driver is a mock we label it a mock. Wynk Systems holds no certification it does not name here.

The four load-bearing claims

Row-level security

Tenant isolation is enforced by the database, not by application code remembering to filter. Every tenant table carries FORCED row-level security and every read runs inside a tenant-scoped transaction, so a query issued without a tenant context returns nothing rather than everything.

Hash-chained audit

Audit and ledger records each commit a SHA-256 over their predecessor. History cannot be edited quietly: a rewrite breaks the chain at the exact record it touched, and an independent verifier recomputes from origin and raises a fork as a blocking alarm.

POPIA

Personal information is collected against a declared purpose and a retention clock, data subjects get self-service access and erasure, logs and URLs are free of personal identifiers, and a discharged erasure destroys the per-subject key.

Two-eyes dual control

Money-adjacent and override actions require a second, distinct operator. The requester cannot approve their own request, the pending state is visible in the interface, and the grant of authority is itself recorded — the UI never implies an override is one click.

Control register

Page 1 of 4 · 30 controls. Wide rows scroll inside the table, not the page.

Across all 4 pages: ✓ Live 27 · ◐ In build 3. In-build controls are not load-bearing yet and a risk assessment should treat them as absent.

Wynk Systems control register
AreaControlHow it is enforcedStatusEvidence
Tenant isolationPostgreSQL row-level security on every tenant tableEach connection sets the tenant GUC inside db.tenantTx; RLS is FORCED, so even the table owner cannot read across tenants.✓ LiveADR-S-0003
Tenant isolationNo query outside a tenant transactionReads acquire a scoped handle; a query issued outside db.tenantTx has no tenant GUC and returns zero rows rather than the wrong rows.✓ LiveGate G-RLS
Tenant isolationSessions are bound to the portal that issued themA session records its audience; a client cookie presented at the admin portal is unauthenticated, not merely unauthorised.✓ LiveF-TENANCY-3
Audit integrityHash-chained ledger and audit event logEvery audit and ledger record commits a SHA-256 over its predecessor; a rewritten history breaks the chain at the point of tampering.✓ LiveADR-S-0011
Audit integrityIndependent chain verifierverifyAuditChain and verifyLedgerChains recompute the chain from origin and surface a FORK state as a blocking alarm, not a warning.✓ LiveGate G-CHAIN
Audit integrityAFS line to origin-event walk-backAny financial-statement line resolves to the postings, the workflow step, the identity and the mandate that produced it.✓ LiveADR-S-0034
Audit integrityAppend-only ledgers enforced in the databaseA BEFORE UPDATE trigger refuses an edit to an event row, and a uniqueness constraint on the predecessor hash makes a chain fork physically impossible.✓ LiveADR-S-0104
AuthorityTwo-eyes dual control on money-adjacent actionsDisbursement, override and reversal require a second, distinct operator; the requesting operator cannot approve their own request.✓ LiveADR-S-0057

What we do not claim

Independent reviewers get the evidence pack — chain attestation, control register, exception log and the sampling workfile — rather than a slide deck. ✓ Live means the mechanism is in this codebase and on the gate board today.