Skip to Content
Apso is in public beta. Get started
ArchitectureSecurity

Security model

Apso generates application code that you own. Security therefore has two parts: the controls Apso supplies through the selected stack and the controls your application adds for its users and data.

Start with the threat boundary

Before deployment, decide:

  • Which routes are public
  • How users or machines authenticate
  • Which records each identity can read or change
  • Which secrets the service needs
  • Which actions require an audit trail

The schema defines data shape and relationships. It does not replace application authorization. A workspaceId field, for example, only isolates records when your query or guard enforces that filter.

Authentication

Choose an authentication strategy when you initialize or scaffold the service. Current CLI options include Better Auth, Auth0, Clerk, Cognito, API key authentication, a custom database session, and no generated authentication.

Each provider has a different token or session format. Configure its server-side secrets through environment variables and verify requests in the generated or custom authentication module. See Authentication for provider-specific setup.

Authorization and tenant isolation

Authentication identifies the caller. Authorization decides what the caller may do.

For a multi-tenant service, put the tenant identifier on every tenant-owned entity and scope every read and write with it.

const project = await this.projects.findOne({ where: { id: projectId, workspaceId: request.user.workspaceId, }, });

Check membership and role before performing privileged actions. Keep this logic in guards, policies, or focused extension services so every custom route follows the same rule.

Test isolation with at least two tenants. A useful test creates data for tenant A, authenticates as tenant B, and confirms that list, read, update, and delete requests cannot reach tenant A’s record.

API keys

Service API keys are credentials for trusted server environments. Store them in a secret manager or a deployment environment variable. Send them only from a backend, scheduled job, or other controlled runtime.

Do not place an Apso API key in:

  • Browser JavaScript
  • A public Next.js environment variable
  • A mobile application bundle
  • Source control
  • Logs or error reports

Use a backend-for-frontend when a browser or mobile client needs to call an Apso service. The BFF authenticates the user, applies product authorization, and calls Apso with the server-side key.

Input validation

Use the generated DTOs as a starting point, then add validation for product rules in custom code. Validate lengths, allowed values, file types, and cross-field constraints before data reaches an integration or database query.

TypeORM repository methods and parameterized query-builder values keep user input separate from SQL.

return this.projects .createQueryBuilder('project') .where('project.workspaceId = :workspaceId', { workspaceId }) .andWhere('project.name ILIKE :query', { query: `%${query}%` }) .getMany();

Avoid constructing SQL by interpolating request values into a string.

Secrets and environment variables

Local secrets belong in an ignored .env file. Hosted service secrets belong in the service’s Environment view. Use separate credentials for development and production.

When a secret may have been exposed:

  1. Revoke or rotate it at the provider.
  2. Update the deployment environment.
  3. Redeploy the service if the runtime does not reload it automatically.
  4. Review logs and provider activity for misuse.
  5. Remove the secret from repository history when necessary.

Transport and hosting

Use HTTPS for every production client. Apso-hosted services expose their deployed API through managed cloud infrastructure. For self-hosted services, TLS termination, network policy, database access, backups, and runtime patching remain part of your deployment design.

Release checklist

  • Every protected route requires the intended authentication method.
  • Tenant-owned queries include the authenticated tenant identifier.
  • Privileged actions check membership and role.
  • API keys and provider secrets are server-side only.
  • Request values are validated before use.
  • Logs omit credentials and sensitive payloads.
  • Isolation tests cover list, read, update, and delete operations.
  • Production traffic uses HTTPS.
  • Dependencies and generated code are reviewed before release.
Last updated on