Keystne
Platform Hubs Architecture How it works
Docs Try the demo
Home/Legal/POPIA Compliance
Privacy Policy Terms of Service POPIA Compliance Incident Response

POPIA Compliance Statement

Accuracy notice. The security measures table (§2.7) and tenant isolation section (§6) were rewritten on 2026-08-04 against the Go implementation, and every source reference in them resolves to a file that exists — enforced by frontend/src/__tests__/docsSources.test.ts. The previous version cited ten deleted backend/*.py files as evidence and asserted four measures that are not implemented; those are now recorded as gaps in §2.7 rather than removed quietly. Sections outside §2.7 and §6 are policy and process text and were reviewed, not rewritten.

Status: Reviewed for factual accuracy against the implementation on 2026-06-24 — every security claim below is tagged Implemented (with a source reference), Deployment-required, or Organisational commitment, and the statutory standards (notably breach notification) have been corrected to POPIA, not GDPR. Before publication, two items remain: (a) the company’s CIPC particulars in the Information Officer block, and (b) sign-off by an admitted South African legal practitioner. This document is a compliance description, not legal advice.

Last updated: June 2026 · Version: 1.1

This statement describes how Cognizance Processing (Pty) Ltd (“KeyOne”) complies with the Protection of Personal Information Act, 4 of 2013 (“POPIA”) in its operations as both a responsible party and an operator for its customers.


1. Overview of POPIA

POPIA is South Africa’s principal data protection legislation, administered by the Information Regulator of South Africa. It regulates the processing of personal information by public and private bodies, establishing eight conditions for lawful processing.

KeyOne processes personal information as:

  • A responsible party for its own employees and platform users (account name, email, authentication data).
  • An operator for personal information contained in customer-uploaded business data (retailer POS / ERP data), where the customer is the responsible party.

2. The Eight Conditions for Lawful Processing

2.1 Accountability

Under POPIA s56, where a private body has not separately designated and registered an Information Officer, the head of the body is the Information Officer by default. Registration of the Information Officer with the Information Regulator is mandatory before processing. KeyOne’s Information Officer particulars and registration status are recorded in the Information Officer block at the foot of this statement. Contact: privacy@keyone.sh.

2.2 Processing Limitation

We collect only the personal information that is necessary, adequate, and not excessive for the stated purpose. As a responsible party, the personal information we hold is limited to account identity (name, email) and authentication data. We do not collect special personal information (s26) in the ordinary course of business (see §3).

2.3 Purpose Specification

Personal information is collected for specific, explicitly defined, and lawful purposes, specified at the point of collection. See our Privacy Policy for full purpose descriptions.

2.4 Further Processing Limitation

We do not use personal information for purposes incompatible with the original purpose of collection without a fresh lawful basis. As operator, we do not process Customer Data for our own independent purposes (§5).

2.5 Information Quality

Account holders can view and update their profile information at any time, and request correction under s24. We take reasonable steps to keep information accurate for its purpose.

2.6 Openness

This document and our Privacy Policy constitute our notification of processing activities. A PAIA Manual (s51 of the Promotion of Access to Information Act) is in preparation — see §9; until published it is available on request.

2.7 Security Safeguards

POPIA s19 requires appropriate, reasonable technical and organisational measures. The table separates what is implemented in the platform today (with source references, verifiable) from what is required at deployment or is an ongoing organisational commitment — so this statement does not overclaim.

Implemented (verifiable in the platform):

Every source reference below was checked against the Go tree on 2026-08-04 and resolves to a file that exists. The previous version of this table cited ten backend/*.py files, all of which had been deleted when KeyOne became a single Go binary — a compliance table whose entire purpose is to be verifiable, with a fabricated verification column. Claims that turned out to be untrue have been moved to the not in place table below rather than restated.

MeasureDetailSource
Password securityArgon2id hashing (OWASP’s second recommended configuration); no plaintext storagecore/internal/auth/hash.go
Two-factor authenticationTOTP 2FA with an enroll → confirm lifecycle; a pending secret is only promoted once a real code verifiescore/internal/auth/totp.go, migration 0023
Session securityShort-lived access tokens + rotating refresh tokens with reuse detection that survives a later legitimate refreshcore/internal/auth/refresh.go, core/internal/auth/jwt.go
Signing-key durabilityJWT signing keys persist in signing_keys and are shared by every instance — no key file, no /tmp fallback, no per-instance divergence under autoscalingcore/cmd/keyone/signingkeys.go, migration 0021
Tenant isolationPostgres row-level security, FORCEd on 32 tables, with app.tenant_id set per transaction; exercised by an automated cross-tenant testcore/internal/store/tenant.go, core/internal/store/rls_test.go (TestRLS_TenantIsolation)
Access controlsRole-based authorisation checked server-side on every mounted route groupcore/internal/auth/roles.go, core/internal/api/routes.go
Action audit trailaudit_log records who did what to which object, under RLS, readable through the ops surface. Covers decision actionsmigration 0014, core/internal/decision/actions.go, core/internal/ops/auditlog.go
Authentication audit trailLogin success and failure (with a server-side reason the client is never told), refresh-token reuse recorded distinctly from an ordinary rejected token, logout, TOTP enrolment/verification/failure, password-reset requests and invite redemption. Written to audit_log with target_type = 'auth' and the client IP. A failed login against an address with no account is recorded too, so credential-stuffing against non-existent addresses is not invisiblecore/internal/api/authaudit.go, core/cmd/keyone/authauditadapter.go
Encryption in transitTLS on all client/service connectionsdeployment (reverse proxy / ingress)
Incident responseDocumented breach-response procedureIncident Response

Not in place (previously claimed here, and untrue):

These rows are listed because an earlier version of this statement asserted them as implemented. They are recorded as gaps rather than deleted, so the record shows what was corrected.

Claim previously madeActual position
TOTP secrets encrypted at rest via application-layer envelope encryptionNot true. The secret is stored in a plaintext totp_secret column. An AES-256-GCM encryptor exists (core/internal/store/crypto.go) but nothing calls it.
Authentication events recorded in an auth_events tableCorrected, not as claimed. There is no auth_events table and there never was. Authentication events are now recorded in audit_log with target_type = 'auth' — see the implemented table above.
Data-access events recorded in query_audit_eventsNot true. No such table exists. Query execution is not audit-logged.
Per-tenant ClickHouse database with a dedicated DB userNot applicable. KeyOne has no ClickHouse. Tenant isolation is Postgres RLS only (above).
Embed tokens are read/metric-scoped and cannot carry raw-SQL authorityNot applicable. There is no embed-token endpoint.
App refuses to start in production with default signing/encryption secretsNot verified. Config validation (core/internal/config/validate.go) enforces required tenant fields; it does not check for default secrets.

Required at deployment (infrastructure, before processing real personal information):

MeasureStatus
Encryption at rest (storage volumes)Provision encrypted Postgres / object storage in africa-south1
Field-level encryptionNOT in place. core/internal/store/crypto.go is called by nothing; no field is encrypted at rest beyond whatever the database volume provides. This affects the TOTP secret and sources.credentials_ciphertext.
Network controlsProduction CORS allow-list; TLS termination; firewalling
Hosting assuranceHost in a certified (e.g. ISO 27001) data centre in South Africa

Organisational commitments (process, not code): Documented incident-response testing, periodic independent security assessment (penetration testing), and POPIA awareness training for staff with data access. These are commitments KeyOne undertakes operationally; they are not represented as already-completed events.

2.8 Data Subject Participation

Data subjects may request access (s23), correction or deletion (s24), object to processing (s11(3)), and lodge a complaint with the Information Regulator. Requests are actioned within the statutory timeframes (see §8). Contact: privacy@keyone.sh.


3. Special Categories of Personal Information

KeyOne does not process special personal information (s26) — religious or political belief, race, trade-union membership, health, sex life, biometric data, or criminal behaviour — in the ordinary course of business. If such information were received inadvertently (e.g. within uploaded retailer data), it would be deleted on discovery.


4. Cross-Border Transfers

KeyOne’s architecture is designed to process all personal information within South Africa (target region africa-south1). KeyOne will not transfer personal information outside South Africa except where s72 permits — adequate protection in the recipient country, data-subject consent, or a contract incorporating appropriate safeguards. Any sub-operator processing data outside South Africa would be recorded in our sub-operator register under a POPIA-compliant agreement. (Until production infrastructure is provisioned in-region, residency is a configuration requirement, not yet an operational fact. An earlier version of this section pointed to a POPIA_RESIDENCY.md that does not exist.)


5. KeyOne as an Operator for Customer Data

When customers upload business data (retailer POS, ERP), KeyOne acts as an operator and the customer is the responsible party for any personal information it contains. In this capacity KeyOne (s20–s21):

  • Processes Customer Data only on the customer’s documented instructions and to deliver the contracted service;
  • Does not process Customer Data for its own purposes;
  • Applies the security measures in §2.7;
  • Assists the customer with data-subject requests relating to Customer Data;
  • Notifies the customer of a security compromise affecting their data within 72 hours of discovery (a contractual SLA — see §7 for the distinct statutory standard);
  • Deletes Customer Data within 30 days of contract termination;
  • Makes information available to assist the customer’s compliance audits.

Our standard Data Processing Agreement is incorporated into the Terms of Service; enterprise customers may request a standalone DPA via legal@keyone.sh.


6. Tenant Isolation and POPIA

A core security-by-design feature is tenant isolation. KeyOne is a single-tenant binary: one deployment serves one customer, and the tenant is resolved once at startup rather than per request.

  • All operational and analytical data lives in Postgres with row-level security, FORCEd on 32 tables so the policy applies even to the table owner (core/internal/store/tenant.go);
  • Every request runs inside a transaction that sets app.tenant_id, which the RLS policies read — a query that forgets the tenant returns nothing rather than everything;
  • The tenant claim in the signed token is checked server-side before the transaction is opened.

This supports POPIA’s requirement to guard against unauthorised access to personal information (s19), and is exercised by an automated cross-tenant isolation test (core/internal/store/rls_test.go, TestRLS_TenantIsolation).

An earlier version of this section described per-tenant ClickHouse databases with dedicated database users. KeyOne has no ClickHouse; that architecture belonged to the retired Python stack. Postgres RLS is the whole of the isolation boundary.


7. Security Compromise Notification (POPIA s22)

If there are reasonable grounds to believe personal information has been accessed or acquired by an unauthorised person, KeyOne (as responsible party) notifies:

  • The Information Regulator, and
  • The affected data subjects (where their identity can be established),

as soon as reasonably possible after discovery of the compromise — taking into account the time needed to determine its scope and restore the integrity of the information system (s22(2)). POPIA does not impose a fixed deadline (the 72-hour rule is a GDPR concept and is not the POPIA standard). Notifications to data subjects include the matters required by s22(5) — likely consequences, measures taken or proposed, recommended protective steps, and the identity of the unauthorised person if known.

The 72-hour figure in §5 applies only to KeyOne’s contractual operator-to-customer notification, which is distinct from this statutory obligation. The full procedure is in our Incident Response procedure.


8. Data Subject & Access Requests

To exercise your rights:

  1. Email privacy@keyone.sh, subject “POPIA Data Subject Request”;
  2. Include your full name, email, and a description of your request;
  3. We may verify your identity before actioning it;
  4. We respond within the statutory timeframe. Access requests under PAIA are handled within 30 days (extendable as PAIA permits); correction/deletion and objection requests are actioned promptly on verification.

If you are unsatisfied, you may escalate to:

The Information Regulator of South Africa JD House, 27 Stiemens Street, Braamfontein, Johannesburg inforegulator.org.za · complaints: POPIAComplaints@inforegulator.org.za · general: inforeg@inforegulator.org.za


9. PAIA Manual

A Promotion of Access to Information Act (PAIA) Manual under s51 is in preparation. Until published it is available on request from paia@keyone.sh. (This is an honest status: the manual is not yet a published artifact.)


10. Updates to This Statement

Reviewed at least annually and whenever processing activities materially change. Updates are notified via the platform and by email to affected users.


Information Officer

Cognizance Processing (Pty) Ltd Information Officer: the head of the body, by default under POPIA s56, until a separate designation is registered with the Information Regulator Email: privacy@keyone.sh

Company particulars to complete from the entity’s own CIPC records before publication (these are public-record facts specific to the registered company; they are intentionally left blank rather than guessed):

  • Registered company / CIPC registration number: ____________________
  • Registered physical address: ____________________
  • Information Officer designation registered with the Regulator: ☐ yes ☐ pending

This statement has been reviewed for factual accuracy against KeyOne’s implementation as of the date above. It is a compliance description, not legal advice, and should be confirmed by an admitted South African legal practitioner before it is relied upon externally.

Keystne

From raw retail data to shelf-level action — one commercial cockpit, ranked decision hubs, closed-loop execution.

Platform

Decision Engine Decision Hubs Architecture How it works Live demo

Company

Documentation Why KeyOne

Legal

Privacy Terms POPIA Incident response
© 2026 Cognizance Processing (Pty) Ltd t/a KeyOne. All rights reserved. South Africa · hello@keyone.sh