Skip to main content
Danipa
Back to Blog
Engineering4 min read

Zero-Trust by Default: How Danipa is Architected

Patrick Aboagye·May 18, 2026

What "zero-trust" actually means

The phrase gets thrown around a lot. In our case it means one specific thing: no service inside the platform implicitly trusts any other service. Every inter-service call presents a client certificate. Every secret is fetched from Vault, never baked into a container. Every database has a client-auth listener. If a single service is compromised, the blast radius is that service, not the platform.

This is the same posture a tier-1 bank's payment infrastructure has to take. It's not what most early-stage fintechs do, because doing it right is expensive. We did it from day one because the alternative — building it later — usually means a rewrite.

Here's how it's wired.

The six pillars

1. Zero-trust security

Every Spring Boot service has its own per-service mTLS certificate issued by an internal Vault PKI. The certs auto-rotate. Postgres, Redis, Kafka, Consul, and Keycloak all run client-auth-enforced TLS 1.3 listeners — no cleartext on any internal hop. If you tcpdump between two Danipa services in sandbox, you see encrypted TLS frames, end of story.

2. Secrets management

HashiCorp Vault is the single source of secrets. Vault KV paths are scoped per environment (sandbox / production) and per service. Spring Cloud Config Server composites Vault with Git: secrets from Vault, non-secrets (feature flags, service URLs) from the config repo.

No secret lives in a Docker image, a Kubernetes manifest, a CI variable, or anyone's laptop. The rotation workflow is audited; the audit trail is queryable.

3. Data privacy & compliance

Card processing is PCI DSS-handled via Stripe — we never touch a PAN. For everything else, PII masking is enforced at the architecture layer. An ArchUnit test fails the build if a logger statement could leak a phone number, email, or card token. The guard is more reliable than a code-review checklist because it runs every commit.

Multi-tenant tables use Postgres row-level security. The TenantConnectionInterceptor sets the tenant id on every JDBC connection; queries that forget to filter by tenant return zero rows, not someone else's data.

4. Multi-jurisdiction readiness

Ghana statutory compliance — KYC tiers, AML, Ghana Card verification — is shipped. CAD and USD banking corridors are wired via Stripe Connect with per-country routing. The provider model is extensible: adding a new country's payment rail means writing a PaymentGateway implementation, not re-architecting the core.

5. Testing & observability

80%+ test coverage across every service. Not a marketing number — a JaCoCo gate that fails CI if coverage drops below the floor. Unit, integration, and E2E layers; ArchUnit at the build for architecture invariants (no wildcard imports, no PII in logs, no direct DB access outside repositories).

Structured logs carry a request-scoped trace id, tenant id, and user id across every service hop. A merchant ticket with a request id resolves in one click.

6. Sandbox-first development

Hetzner runs the sandbox. Every feature gets validated against real provider integrations — MTN MoMo against MTN's sandbox, Stripe against test mode, webhooks against the merchant's actual endpoint — before it can ship.

Production cuts over to Azure or AWS post-funding for multi-region scale. The sandbox isn't going away after that; it stays as the staging step before any production deploy. Every feature has to clear the sandbox bar twice — once to ship into sandbox, once to graduate.

Why I'm telling you this

Two reasons.

For developers: if you're considering building on Danipa's API, this is what your data is sitting on top of. The full architecture page lives at /architecture, with the same pillars in more detail.

For investors: the cost of building this discipline in later — after a hundred merchants are live, after a regulator asks a question, after a breach — is a complete platform rewrite. We did it before the marketing site existed. You're not buying a roadmap toward production-grade infrastructure; you're buying the infrastructure with a sandbox-stage label on it. The label comes off when the funding lands; the architecture does not change.

If you'd like the full read, the architecture page and the milestone docs in the platform repo are both open. If you'd like to talk, contact us.