Payvala

Assistant

Payvala Assistant

Suggestions

Press Enter to send · Shift+Enter for new line

On this page
Payvala Security Overview

Payvala Security protects the connections, API requests, and information exchanged between Payvala and its partner financial institutions (FIs). It helps ensure that only trusted institutions can connect, make authorized requests, and access the data they are permitted to use.

Security works through multiple layers. Network controls determine which connection path can reach Payvala. Client certificates and access tokens help verify the institution, while request signatures help confirm that API requests are genuine and have not been changed. Payvala also checks permissions and validates requests before processing them.

Security also includes protecting sensitive information, managing certificates and keys safely, keeping each institution's data separate, and preparing for security incidents. Merchant-facing APIs and Soundbox devices use separate security methods from FI API connections.

This overview introduces the security model and summarizes each layer. Each topic is explained in full on one dedicated page. Every requirement is labeled Confirmed, Provisional, Proposed, or Open, and values marked † are provisional. Provisional, proposed, and open items must not be treated as final production commitments.

How Payvala Security Works

Payvala protects each financial institution (FI) connection through several checks. First, the FI connects through one approved network path: a private connection or the public path through Cloudflare. The network path controls which traffic can reach Payvala, but it does not verify the caller's identity. Each FI API request must then pass mutual TLS (mTLS), present a short-lived access token linked to the client certificate, and carry a valid request signature made with the method registered for its key. Payvala then checks the request format and the FI's API permissions before processing the request. The health and status endpoints are documented exceptions to the token and signature rules (see Security Rules for Each API). Optional message encryption (JWE) adds protection for the message body. It is off by default for normal FI API traffic and is always used to deliver a new HMAC secret. Merchant-facing APIs and Soundbox devices use separate security methods, and device connections never use the FI paths.

Identity & Access

Payvala uses the FI's registered client certificate and a short-lived access token linked to that certificate to verify the caller. It checks the token's permissions on every request. The institution identity comes from the registered certificate, not from a value supplied in the request.

Network & Communication

Each FI uses one network path for normal traffic: a private connection or the public path through Cloudflare. FI API connections require TLS 1.3, with no fallback to older TLS versions. The network path does not replace certificate, token, or signature checks.

Application & Data

Payvala checks request size, media type, and message format before processing the body. It verifies the registered request signature and applies the API's validation rules. Access is limited to the operations and data permitted for that FI.

Operational Security

Security procedures cover key and certificate management, controlled approval of sensitive key operations, audit records, protection against repeated signature failures, and emergency procedures for certificate authority problems. Items marked provisional or proposed must not be treated as confirmed commitments.

Loading diagram...
Security Rules for Each API

Payvala APIs do different jobs, so each API belongs to exactly one security class. The class sets the request-signing method, validation rules, and access controls that the API must meet, and how its caller must connect. Four classes apply to the current FI and merchant APIs: K, W, R, and M. Additional classes for people, staff, devices, outbound calls, and device commands (H, I, D, O, and C) are proposed for surfaces that are not yet built and await owner confirmation. This page gives a quick overview of the requirements for each class. Detailed procedures for creating, rotating, and revoking keys are covered on the separate Key Management page.

Class K: Key Management

Applies to API 2, which manages keys. Requests must use JWS signing; HMAC is not accepted for this API. The FI's master key signs each request, and that key is held in the FI's hardware security module. A master key cannot be used on any data API. Each new key waits for an activation delay and can be cancelled during it.

Class W: Data Ingest

Applies to APIs 3, 7, and 8, which receive transaction, device-classification, and heartbeat submissions. Each key must use its registered HMAC or JWS signing profile, with no downgrade to another method. Each transaction carries a unique txnId. A repeated transaction within 48 hours returns the original result instead of being processed again.

Class R: Reads

Applies to APIs 5, 6, and 9, which return information to authorized callers: device status, FI transaction reads, and the events feed. Results are paginated so clients can retrieve them in manageable portions. A device serial number that does not exist gives the same response as one that belongs to another FI, so one institution cannot discover another institution's devices.

Class M: Merchant First Party

Applies to APIs 1 and 4, called by Payvala's own app or web page on a merchant's behalf, through Cloudflare. These flows do not use an FI client certificate. Merchants sign in with their device serial number and printed device code, or with a one-time code sent by email, which gives lower assurance. Access tokens are bound to a device key (DPoP) after a pushed authorization request (PAR) and PKCE S256.

Connecting to Payvala Securely

Financial institutions (FIs) can connect to Payvala through the approved public route using Cloudflare. Cloudflare acts as the entry point for incoming traffic and applies configured network protections before requests reach the Payvala FI API. The origin accepts traffic from Cloudflare only, helping prevent requests from reaching the service through an unapproved public route. This section explains how traffic reaches Payvala; certificate verification, access tokens, request signing, and API permissions are explained in their dedicated security sections.

Loading diagram...
Secure Connections and Certificates

All Financial Institution (FI) API connections must use TLS 1.3, and older TLS versions are not accepted. Mutual TLS (mTLS) requires both sides to prove their identity using certificates. Each FI generates its private key and certificate request inside its own hardware security module (HSM), and the private key never leaves the HSM. Software-only private-key storage is not permitted in production. Connections with missing, invalid, or unregistered certificates are refused before any data is read. Because mTLS does not support session resumption, FI clients should keep connections open using HTTP keep-alive and use a small connection pool rather than opening a new connection for every request.

TLS 1.3 — Secure Communication

mTLS — Certificate-Based Authentication

Client Key Type

Certificate Issuer

Certificate Validity and Renewal

Certificate Revocation

Identity Checks and Access Permissions

Authentication checks which FI is making the request. Authorization checks what that FI is allowed to do. Payvala uses the client certificate and a token linked to that certificate to identify the FI, then checks the token and key permissions on every call. FI API access is system-to-system, so it does not use a browser sign-in or a client secret. Access is granted per key and per API; the detailed token scopes are listed on the Short-Lived Access Tokens section.

Authentication

Mutual TLS identifies the institution from the client certificate. The institution ID is never read from the request body or headers.

Authorization

A key holds one scope for one API. A token with a data scope cannot reach API 2, and a token with the key-management scope cannot reach any data API. The scope required by the API, the token's scope, and the key's scope must all agree, and the key must belong to the same institution and be active.

Request Validation

Size, media-type, encoding, and length checks run before the body is parsed. The signature is verified over the raw bytes before the JSON parser reads the body. Requests with duplicate member names or unknown fields are refused.

Short-Lived Access Tokens

An access token is a short-lived credential that allows an FI to call approved APIs. Each token is linked to the client certificate used to request it and lasts 900 seconds (15 minutes). There is no refresh token. When a token expires, the FI requests a new one. The FI should cache the current token and reuse it until it expires instead of requesting a token for each call. Token permissions limit which APIs it can reach. On every call Payvala checks the token's signature, issuer, audience, expiry, scope, and certificate binding, and confirms that the certificate is still registered to an active institution. If the certificate is revoked or the FI is suspended, its tokens stop working at once, without waiting for expiry.

Token Type

Lifetime

Grant

Control-plane Scope

Data-plane Scopes

Status Scope

Checking That API Requests Are Genuine

Each API key is registered to one request-signing method: HMAC or JWS. HMAC uses a shared secret, which must never be sent with a request. JWS uses a private key held by the FI to create a signed proof for each request, and Payvala checks that proof against the registered public key. Payvala checks the signature to help confirm that the request came from the expected key and was not changed. A key's method is fixed, so a key cannot switch methods, and a request signed with the wrong method is rejected with 400 invalid_signature. API 2 accepts JWS only. The older X-Api-Key header is no longer used. A third profile, RFC 9421 HTTP Message Signatures (http-sig), is planned with a target date of 30 June 2027. That date can move by mutual agreement, and it is not a commitment.

FieldDescription
X-Api-Key-IdKey identifier for HMAC and JWS. It is an identifier, not a secret, and is covered by the HMAC signature.
X-TimestampHMAC only. Must be within 300 seconds of the platform clock. Covered by the signature.
X-NonceHMAC only. Unique per request and remembered for 600 seconds to block replay. Covered by the signature.
X-SignatureHMAC only. Base64 of the 32-byte HMAC-SHA256 result over the version 2 signing string: the HTTP method, the path with query, the key identifier, the timestamp, the nonce, and the raw body bytes. Because the method and path are signed, a signature cannot be reused on a different request.
X-Request-ProofJWS only. Signed with ES256 or PS256 and typ payvala-proof+jwt. Carries iat (within 300 seconds), jti (remembered 600 seconds), htm, htu, a SHA-256 digest of the body and, for API 3, the txnId. A new proof is computed for every request.
Loading diagram...
Keeping Keys and Credentials Safe

Keys and credentials must be managed safely from creation to retirement. A new key waits for an activation delay before it becomes usable. The delay is provisionally 30 minutes (allowed range 15 to 60), and the key can be cancelled during that time. During planned rotation, the new key is added before the old one is retired, with a 24-hour overlap, so integrations can switch without an avoidable outage. HMAC secrets rotate every 90 days, with 14 days' notice. If the master key is lost or suspected to be compromised, a controlled out-of-band recovery applies. It involves two FI officers, two Payvala approvers, registered contacts, and a cooling-off period. Retired and expired keys cannot be reactivated.

One Key per API

Each key is created for one API and holds one scope and one signing profile. No key covers several APIs. Every call checks that the scope the API requires, the token's scope, and the key's scope agree.

Key Identification

Each key is identified by its kid. The JWE header names the decryption key by kid.

Non-Disruptive Rotation

New keys are added without interrupting existing integrations, with a 24-hour overlap on both sides.

HMAC Secret Handling

The platform generates the HMAC secret and returns it once, encrypted (JWE) to the FI's encryption key. It can never be read back. A request that carries the secret is rejected with 400, and that credential is flagged for rotation.

Limited Key Operations

Key operations are deliberately rare: a handful per hour and, provisionally, 20 per day per FI. Every key operation is written with its signed request to write-once storage.

Credential Protection

Private keys and credentials stay in the owner's hardware security module or secrets manager. Suspected compromise must be reported to Payvala within 1 hour.

Loading diagram...
Public Keys and How They Are Shared

JSON Web Key Sets (JWKS) publish the public keys used for encryption and signature verification between Payvala and FIs. Payvala publishes its public encryption keys at /.well-known/jwks.json. Signing keys (master, approver, and request-proof keys) use ES256 with an EC P-256 key (preferred) or PS256 with an RSA key of 2048 bits or more. Encryption keys are RSA keys of 2048 bits or more. Private keys are generated by their owner and never leave the owner's hardware security module. Each new public key is confirmed by a fingerprint call-back (RFC 7638 thumbprint) and checked for uniqueness across all FIs and both environments before it is registered.

FieldDescription
ktyKey type. EC for ES256 signing keys (preferred); RSA for PS256 signing keys and for encryption keys.
kidUnique key identifier. Selects the key during planned rotation and in the JWE header.
useIntended key usage. enc for encryption keys; sig for signing keys. A signing key is refused as an encryption key.
algAlgorithm. RSA-OAEP-256 for encryption keys today; ES256 or PS256 for signing keys. RS256 is not permitted.
crvEC curve, for EC keys only (P-256).
xEC public key x coordinate in Base64URL, for EC keys only.
yEC public key y coordinate in Base64URL, for EC keys only.
nRSA modulus encoded using Base64URL, for RSA keys only.
eRSA public exponent encoded using Base64URL, for RSA keys only.
Finding Public Keys

FIs obtain Payvala's public encryption keys with a GET request to /.well-known/jwks.json. An FI may register the address of its own key set, but only for its encryption key. Never for its master, approver, or request-proof keys, and never for certificates. That address must be HTTPS on a domain the FI registered at onboarding. Payvala caches the last good set and keeps it if a fetch fails. It uses a new key only 24 hours after the key first appears (Proposed), alerts the FI's security contacts on every change, and runs the uniqueness check on each new key. Key identifiers allow the correct key to be selected during planned rotation. Exact endpoint details are documented in Developer → API.

Protecting Information in Requests

TLS protects data while it travels between systems. Request signatures add a separate check that a request is genuine and has not been changed. Optional JWE encryption adds protection to the message body itself. It is off by default, except when used to deliver a new HMAC secret. Encryption does not prove who sent a message; certificates, tokens, and signatures do that. Requests must follow the published size and format rules. FIs must not send account numbers, BVN, NIN, phone numbers, or card numbers in requests. The rules for handling personal data are covered in Protecting Personal and Sensitive Data.

Extra Encryption for Message Data

JWE (JSON Web Encryption) is an optional way to encrypt the message body inside the TLS connection. It is off by default for normal API traffic and is always used when Payvala delivers a new HMAC secret. An FI whose policy does not allow a processor to see transaction data in clear, typically on the public path, can switch it on for API 3, API 5, and API 6. Those APIs carry amounts, payer references, device serial numbers, and device location. JWE encrypts the body but does not authenticate the sender; the certificate, token, and signature do that. When it is enabled, both sides decrypt every body, and the edge can check sizes but not content.

Serialization

Key Exchange

Content Encryption

Encryption Key

Key Publication

Sending an Encrypted Request
HeaderDescription
AuthorizationBearer <AccessToken>
Content-Typeapplication/jose
X-Api-Key-Id<Key identifier>
Receiving an Encrypted Response

When response encryption is enabled for an FI, the response body is returned as a compact JWE with Content-Type application/jose, encrypted to the FI's registered encryption key. Every authenticated response carries Cache-Control: no-store and X-Content-Type-Options: nosniff, whether or not its body is encrypted. Exact response structure is documented in Developer → API.

Protecting Personal and Sensitive Data

FI integrations exchange only what each operation needs, typically a transaction reference, amount, device serial number, and txnId. The payerRef field is personal data and is treated as a direct or pseudonymous identifier. Payvala stores the value as sent, encrypts it at field level at rest, masks it in logs to its last four characters, never places it in an error response, and shows it only to the merchant of that device. It is kept no longer than the transaction record. Credentials, access tokens, secrets, and private keys must never appear in application logs, source repositories, or unsecured configuration.

Credential & Token Protection

Access tokens and credentials must be protected from unauthorized disclosure. HMAC secrets are never returned after creation.

Private Key Protection

Private keys stay in the owner's hardware security module and are never exposed to Payvala or to any other party.

Minimal Data Exchange

FIs must not send account numbers, BVN, NIN, phone, or card numbers. payerRef is optional, and the FI chooses its content: an opaque, stable token, a masked name, or a token generated per merchant. A token that is the same for a payer at every merchant lets two merchants recognize the same payer, so a per-merchant token or masked name is the safer choice.

Secure Logging Practices

Sensitive values must not be exposed in logs. FIs keep their own logs for at least 12 months so they can correlate with Payvala audit records, and log payerRef only to its last four characters.

Protecting Payvala Websites and Browser Sessions

Merchant-facing APIs (1 and 4) and the planned administrator portal run in a browser, so the browser must be told how to protect the user. FI APIs are machine-to-machine and are not meant to be called from browsers. Their hosts send no cross-origin (CORS) headers and refuse cross-origin preflight requests, which is itself a control.

Transport Enforcement

Strict-Transport-Security with max-age of one year and includeSubDomains. Preload is added only after all subdomains are confirmed HTTPS-only.

Content Security Policy

Nonce-based scripts, no unsafe-eval, no inline scripts without a nonce, object-src 'none', base-uri 'none', frame-ancestors 'none', and upgrade-insecure-requests. The policy starts in report-only mode and is then enforced.

Cookies

Session cookies use the __Host- prefix with Secure, HttpOnly, SameSite=Strict (Lax only where a sign-in redirect requires it), Path=/, and no Domain attribute. Tokens are never kept in local storage.

Framing, Sniffing & Referrer

X-Frame-Options DENY, X-Content-Type-Options nosniff, and Referrer-Policy strict-origin-when-cross-origin, or no-referrer on pages that carry identifiers in the address. Permissions-Policy turns off camera, microphone, geolocation, and payment unless a feature is needed.

Caching

Cache-Control: no-store on every authenticated page and API response, so that data is not left in shared or browser caches.

CORS & CSRF

Merchant and portal APIs allow only an exact list of Payvala front-end origins, never a wildcard with credentials, and preflight responses are cached for at most 10 minutes. State-changing requests need SameSite cookies and a per-session token, or use a bearer token in a header.

Sign-in Protection

Rate limits, lockout after repeated failures, generic error messages, and an optional bot challenge after repeated failures. The sign-in method for the administrator portal is an open decision: either the FI's identity provider or Payvala-managed accounts with multi-factor authentication.

Keeping Soundbox Connections Secure
Loading diagram...
Keeping FI Data Separate and Recording Security Events

Each FI can access only its own permitted data. Payvala identifies the institution from its client certificate, not from a value supplied in the request. Important key-management and request-check outcomes are recorded for later review. Detailed platform-wide log collection and threat detection are covered in a separate plan and are not specified in this section.

Tenant Isolation

Tenant isolation is enforced in the server and again in the database. Unknown resources and resources owned by another FI return identical answers, so existence is not revealed.

Authentication Activity

Traceability of identity verification activity for operational and security review.

Authorization Activity

Traceability of access-decision activity for operational and security review.

Request Validation Activity

Traceability of request-validation outcomes for troubleshooting and investigation.

Credential Management Activity

Every key operation is written with its signed request, and a secret can never be read back after creation.

Traffic & Abuse Protection

Three consecutive signature failures on one API, for one FI and one profile, trip a circuit breaker. The failing call returns 400. Later calls return 503 with circuit_break_active, and security contacts are alerted. For API 2, a person must reset the breaker. For the other data APIs, a trial request is allowed after a cooldown of 5 minutes (†). The FI must not build automatic retries around circuit_break_active. Per-FI rate limits apply to every API.

Who Is Responsible for Security?

Keeping the integration secure is a shared responsibility. Payvala manages the platform-side controls, while each FI manages its own systems, network settings, keys, certificates, and monitoring. Each side must complete the security steps it controls.

Payvala Responsibilities

Operates the platform-side controls: TLS 1.3 at the edge, certificate and token validation, signature verification, limits, audit records, and key-operation controls. Publishes the status endpoint, runs the emergency plan for the certificate authorities, and gives the required incident notices.

Integrating Organization Responsibilities

Protects its certificate and master keys in a hardware security module under dual control; production requires an HSM. Stores HMAC secrets in a key manager, keeps system clocks within 60 seconds of an NTP source, retains logs for at least 12 months, reports incidents within 1 hour, and monitors its own success rate, latency, and 429 and 503 counts.

Security Checklist and Best Practices

Protect Private Keys

Generate keys in a hardware security module, where they are non-exportable. Production requires an HSM. Keep the master key under dual control.

Protect Credentials

Store HMAC secrets and tokens securely in a key manager. Never log them, and never place them in source repositories.

Use Correct Environment

Use the institution ID, client IDs, endpoints, certificate authority, and keys for the selected environment. A staging certificate is never accepted in production.

Protect Sensitive Data

Do not send account numbers, BVN, NIN, phone, or card numbers. Send a full name only where the FI's privacy notice covers sharing it with the merchant. See Protecting Personal and Sensitive Data for the full rules.

Rotate Keys & Credentials

Rotate HMAC secrets every 90 days, with 14 days' notice. Renew client certificates before their 12-month expiry. Payvala notifies 30 days ahead, and the old and new certificates overlap for 7 days.

Keep Components Updated

Keep supported security components and dependencies up to date. Retire deprecated API versions before the Sunset date given in the response headers. After a breaking change, the old version runs for at least 90 days (Proposed).

Handle Failures Safely

Keep clocks synchronised within 60 seconds of an NTP source. Drift above 300 seconds causes every request to be rejected with 400. Never retry a 400, 401, 403, or 404 unchanged. Retry only timeouts, 429, and 503 responses (not circuit_break_active), with exponential backoff starting at about one second, a cap of 60 seconds, and jitter, and honour Retry-After. A transaction retry must reuse the original txnId.

Monitor Integration Activity

Track request success rate, latency, and 429 and 503 counts. Log X-Track-Id for each call, and cf-ray on the public path, so that support can trace it.

Related Documentation

Continue exploring PayVala documentation.

Secure. Reliable. Scalable.

Payvala is built with enterprise-grade security, 99.9% uptime, and scalable infrastructure.