Security & data handling

Last updated 2026-03-25

This page summarizes technical controls reflected in the Openfund codebase and internal engineering documentation. It is provided for transparency and due diligence. For how we collect and use personal information, see the Privacy Policy.

Region and hosting

Production workloads are deployed to AWS Canada (ca-central-1) for data residency aligned with Canadian operations. Infrastructure is defined as code (AWS CDK) under infrastructure/.

Authentication (session cookies)

API authentication uses HTTP-only cookies set by backend Lambdas (not JavaScript-accessible storage). Cookie names and expiries are shared constants in packages/api/src/cookies.ts; sign-in and refresh flows live under backend/lambda/iam/authn/.

Cookie

Purpose

Expiry

of_access_token

API authentication (JWT)

1 hours

of_id_token

User identity claims (JWT)

1 hours

of_refresh_token

Session refresh

30 days

of_mfa_session

Multi-factor authentication step

5 minutes

Identity provider and MFA

User pools are managed in Amazon Cognito. Password policy (minimum length and complexity) and MFA are configured in infrastructure/lib/stacks/authn-stack.ts: SMS-based second factor is supported; MFA is required in production and may be disabled in non-production environments for engineering workflows.

Authorization (API and pages)

Protected HTTP APIs use a layered model documented under docs/000-best-practices/security/three-layer-auth.md:

  • API Gateway Lambda authorizer validates the access token cookie and populates request context (see infrastructure/lib/utils/lambda-helpers.ts).
  • createHandler in packages/server/src/handler.ts enforces authentication and calls AWS Verified Permissions for allow/deny decisions.
  • Cedar policies in infrastructure/authorization/policies/*.cedar describe which principals may perform which actions on which resources.

Routes that are intentionally public are listed in packages/api/src/routes.ts (PUBLIC_APIS); all other API paths expect an authenticated session unless explicitly exempted.

Encryption and secrets

At rest: The Aurora PostgreSQL cluster uses KMS-backed encryption (storageEncrypted: true in infrastructure/lib/stacks/storage-stack.ts). The documents S3 bucket uses KMS bucket encryption. Database credentials are generated and stored in AWS Secrets Manager.

Integration credentials (e.g. LOS integrations) are encrypted with a dedicated KMS key in application code (backend/lambda/los-integrations/_lib/core/credentials.ts).

In transit: Clients use HTTPS to the API and web application; cookies are only sent over encrypted connections in normal browser use.

Audit logging

Security-relevant failures (authentication/authorization) are logged through the shared handler wrapper. Successful business actions are logged by handlers using logAudit in packages/server/src/audit.ts into the audit_events table. Backup retention for the database cluster is configured on the Aurora cluster (see CDK backup.retention in the storage stack).

Frontend and server-side requests

Browser code calls APIs with credentials: "include" so cookies attach automatically. Server Components and Server Actions forward cookies explicitly when calling the API from the Next.js app (apps/web/lib/api/server.ts) so server-side rendering stays authenticated without exposing tokens to client JavaScript.

Code references (non-exhaustive)

packages/api/src/cookies.ts · packages/api/src/routes.ts · packages/server/src/handler.ts · packages/server/src/audit.ts · infrastructure/lib/stacks/storage-stack.ts · infrastructure/lib/stacks/authn-stack.ts · infrastructure/authorization/policies/ · backend/lambda/iam/authn/ · backend/lambda/los-integrations/_lib/core/credentials.ts

Privacy Policy · Terms of Use