Skip to content

Technical reference

IPAC security architecture.

Written for the person who has to sign off, not for the person who has to be persuaded. Where a control does not exist, this document says so rather than describing an intention.

Last reviewed 20 August 2026


Request path

Two services behind a CDN. The web application never talks to the database. The API never renders a page. Business logic, validation, and every database query live in the API.

Edge and transport
Public traffic terminates at a CDN in front of managed container services. TLS is enforced end to end, and responses carry nosniff, DENY framing, and a strict-origin-when-cross-origin referrer policy.
X-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-origin
Application split
The web tier owns presentation and session gating, and it is the enforcement point for who reaches which data: it verifies the caller's session before a request for tenant data is allowed to proceed to the API. The API owns data and trusts requests that arrive from the gated web tier rather than re-deriving identity itself. The browser never holds a credential that reaches the database. Restricting the API to authenticated ingress from the web tier, so the gate cannot be bypassed by reaching the API directly, is a deployment-posture item on the security page rather than a control we claim is already complete.
Database access
PostgreSQL, reached over a private socket, never a public address. Every query is parameterized. No user input is ever interpolated into SQL. Connection pools are capped per instance so a traffic burst cannot exhaust the database's connection ceiling.
parameterized queries onlyper-instance pool capno public database address

Identity and session

Sessions are records in Postgres, not self-describing tokens. Revocation is a delete rather than a wait for expiry, with one caveat stated below.

Authentication
Identity runs on Better Auth rather than a hand-rolled implementation. Email and password, with optional TOTP two-factor enrollment per user. Sessions are held in PostgreSQL with a fixed seven-day expiry. SAML and OIDC single sign-on are not implemented.
Session verification
The web middleware checks a signature-verified session cookie cache first and falls back to the API's session endpoint as the authority. Transient API failures fail open at the middleware and are re-gated by the page itself, so a rate-limit burst cannot log a user out. A definitive rejection always does. The cache is a deliberate trade, and its cost is stated below.
Revocation latency
The signed session cookie carries a cached copy of the session for up to thirty minutes, which is what keeps ordinary navigation off the session endpoint. The cost is that deleting a session is not felt instantly on reads served from that cache. Where an immediate cut-off is required, disabling the account is the control to use, not session deletion.
cookie cache: 30 minsession expiry: 7 days
Programmatic access
Integrations authenticate with scoped API keys instead of a user's session, so an integration's reach is defined independently of any person and can be revoked without touching an account.

Tenancy and environment

Two nested boundaries. A tenant is the unit of reach. An environment is the unit of consequence.

Tenant scoping
Membership determines which records a user can address at all. Module entitlements are granted per tenant, so enabling a new operating model is an explicit grant rather than an inherited exposure. Enforcement is in application query scoping, not physical database separation, and we do not describe it as such.
Environment scoping
Within a tenant, records are partitioned into environments, typically one for production and one for demonstration. Requests carry the environment they act in. Document types, certification types, and supplier types are defined per environment, so demonstration configuration cannot leak into operating configuration.
Object storage
Uploaded documents live in object storage partitioned by tenant and environment. The API's service identity holds object-level permissions only. It can create and read objects, and cannot read bucket metadata or enumerate the bucket. Least privilege here is enforced by the platform, not by convention.
object-level IAM onlyno bucket enumerationpartitioned by tenant + environment

Evidence integrity

The property that matters is not that a document is stored. It is that the document a decision cited is still recoverable, unchanged, and identifiable as the one that was cited.

Hashing
Every document is hashed with SHA-256 at upload and the digest is stored on the record. The digest is computed server-side on the received bytes, so it describes what was actually stored, not what a client claimed.
Versioning
Superseding a document creates a new version. The prior version, its digest, and its review state are retained, and any decision that cited the earlier version continues to point at the version it cited.
Chain anchoring
Records are anchored in an append-only SHA-256 chain in which each entry incorporates the digest of the previous entry. Altering an earlier entry invalidates every entry after it, which makes retrospective alteration detectable. The chain is internal. Nothing is written to an external or public distributed ledger, and this is not equivalent to third-party timestamping.

Public verification

The only unauthenticated surface with tenant-derived content. It is designed to give away as little as it possibly can while still being useful.

Addressing
A verification page is reached by an unguessable token. Tokens are not returned by list endpoints without authorization, so possession of one is the only way to reach a page, and a token maps to exactly one claim.
Disclosure surface
The page renders the claim's own fields and the document digest. It exposes no tenant identity beyond what the claim itself asserts, no adjacent records, and no platform navigation. All output is HTML-escaped at the point of rendering.

The AI boundary

IPAC uses language models for assistance and summarization. It does not use them to decide, and where they are used the boundary is explicit.

Where models sit
Model calls leave through a proxy we operate, which holds the provider credentials. Application code never holds a provider key, and the provider is swappable by configuration without a code change. Scoring, decisioning, and evidence handling are deterministic application logic. A model does not produce a recommendation, a confidence figure, or a risk-of-inaction statement.
Data handling
IPAC does not train or fine-tune any model on tenant data. Model interaction is request-scoped and produces assistive text; nothing a model returns is written into an evidence record or a decision basis without a human action.

Operational posture

What is in place, and what is deliberately not claimed.

In place
SOC 2 Type 1 and Type 2 examinations performed by Sensiba, an independent service auditor, with Schubring Global Solutions as the service organization. The Type 2 examination covered Security, Availability, and Confidentiality over the period March 5 to June 5, 2024, and used the carve-out method for the subservice organizations providing application maintenance and support. Managed daily database backups with a fixed retention window. Secrets held in a managed secret store and injected at runtime, never baked into images. Automated bot mitigation and per-address rate limiting on public form endpoints. Authentication and login event history retained.
Not claimed
There is no ISO 27001 certificate. A Content-Security-Policy header is not yet enforced. The direction is report-only first, and we would rather say that than imply otherwise. Network-boundary access control restricting the API to authenticated ingress from the web tier is in progress, not yet complete. There is no bug bounty program. Data residency outside the current region is a scoping conversation, not a switch.

Questions this document does not answer.

Send them. A written answer, including “not today” where that is the answer, reaches you faster than a questionnaire cycle. [email protected]