Security
Isolation you can point at, not a promise in a policy
Multitenancy is where most retail platforms quietly rely on every query remembering to filter correctly. MultiPOS moves that boundary into the database, where forgetting is not an option.
Request path
What happens to one request
Four checkpoints, none of which depend on application code remembering to add a WHERE clause.
- 01
The request arrives with a session, not a token in storage
Authentication is a JWT in an HttpOnly, SameSite cookie. Page scripts cannot read it, so an injected script has nothing to exfiltrate.
- 02
Tenant context is set for the transaction
Before any statement runs, the selected business is bound as transaction-local context. It cannot leak into a pooled connection's next user.
- 03
The database enforces the boundary itself
Tenant tables force row-level security. The runtime role is a non-owner that holds no privilege to bypass it, so the database refuses cross-tenant rows regardless of what the query asked for.
- 04
The action is recorded where it cannot be edited
Operational changes land in the system-wide audit log; platform actions land in a separate immutable trail alongside tenant lifecycle events.
Controls
The rest of the boundary
Sessions, administration, revocation, audit, uploads, credentials and schema change — each with its own separation.
Isolation in the database, not the query
Tenant tables force row-level security in the database. The runtime connects as a non-owner role that cannot bypass it, and tenant context is set per transaction. A forgotten WHERE clause returns nothing rather than someone else's sales.
Sessions the browser cannot read
Authentication is a JWT delivered in an HttpOnly, SameSite cookie. There is no token sitting in local storage for a script to pick up.
A control plane that is genuinely separate
Platform administration runs with its own administrators, its own JWT audience and signing key, and mandatory TOTP. A business administrator account cannot authenticate to it at all.
Immediate authority revocation
Withdrawing access takes effect on the next request rather than whenever a token happens to expire.
An audit trail that cannot be edited
Operational actions land in a system-wide audit log, and platform actions land in an immutable trail alongside tenant lifecycle controls and per-tenant feature flags.
Uploads are scanned before they are kept
Supplier and quotation attachments go to private object storage with SHA-256 checksums, tenant-scoped metadata and malware scanning. File contents never enter the database.
Integration credentials encrypted per tenant
Payment credentials are encrypted with a dedicated key, and provider callbacks are signed and verified before anything is reconciled.
Schema changes under version control
Schema changes are applied as versioned migrations under a separate owner role. The application runtime has no authority to alter the schema it depends on.
Compliance
Fiscal obligations that survive a bad connection
eTIMS transmission sits behind a transactional outbox. The sale commits, the obligation is recorded, and delivery is retried independently — so an unreachable revenue authority never stops a customer paying.
Production eTIMS transmission additionally requires KRA-issued credentials and a certified adapter. MultiPOS provides the configuration and the outbox boundary; the certification is yours to hold.
Operations
Deployed as immutable images
Builds are promoted to a separate deployment repository as immutable tags, and the cluster reconciles to them automatically. Schema changes run as versioned migrations under an owner role the application runtime does not hold.
- Migration role
- Owner, full privileges, migrations only
- Runtime role
- Non-owner, row-level security enforced, no DDL
- Bootstrap role
- One-time container initialisation
Due diligence
Send us your security questionnaire
We would rather answer it properly than have you take a marketing page at its word.