Enterprise CORS allow-list

This document publishes the canonical set of browser origins that AseptSoft's single-page application (SPA) is served from. An AseptSoft API backend must permit these origins in its CORS configuration so the SPA can call it from a browser.

It is the single source of truth for that origin set. Managed AseptSoft backends consume it automatically (see Managed regions); self-hosting administrators are responsible for applying it to their own reverse-proxy or ingress (see Self-host configuration).

Canonical allow-list (V1 — version 2026q2)

The V1 canonical origin set is:

https://app.aseptsoft.ch
https://app-ch.aseptsoft.ch
https://app-eu.aseptsoft.ch
https://app-us.aseptsoft.ch
https://app-ap.aseptsoft.ch
Origin Purpose
https://app.aseptsoft.ch Shared SPA host — the canonical bookmark target.
https://app-ch.aseptsoft.ch Switzerland-region SPA host alias.
https://app-eu.aseptsoft.ch EU-region SPA host alias.
https://app-us.aseptsoft.ch US-region SPA host alias (reserved; not yet deployed).
https://app-ap.aseptsoft.ch APAC-region SPA host alias (reserved; not yet deployed).

All five origins are published from V1 even though app-us and app-ap are not deployed until customer demand triggers those regions. Publishing the full set up-front means a region rollout never requires a synchronised allow-list bump on already-deployed backends.

As a comma-separated value — the form the Cors__AllowedOrigins environment variable expects:

https://app.aseptsoft.ch,https://app-ch.aseptsoft.ch,https://app-eu.aseptsoft.ch,https://app-us.aseptsoft.ch,https://app-ap.aseptsoft.ch

Applied CORS policy

An AseptSoft API serves these origins with the following CORS policy:

A preflight OPTIONS request from an origin not on the list returns success with no Access-Control-Allow-Origin header, so the browser blocks the call. This is fail-closed: an unknown origin is rejected, never silently allowed.

Who needs this

Managed regions (automatic)

AseptSoft-managed backends — the Personal cloud regions and Enterprise-managed deployments — consume this allow-list automatically. The set is the default of the personalCorsOrigins[] Bicep parameter in infra/region/main.bicep, which the per-region deployment flows into the API Container App as the Cors__AllowedOrigins environment variable. No administrator action is required; a deployment refresh propagates any future change.

Self-host backends

Self-hosting administrators own their CORS posture. AseptSoft does not — and cannot — configure CORS on a backend it does not operate. Read this document, then apply the allow-list to your reverse-proxy or ingress as shown in Self-host configuration.

Security caveats

Lifecycle and versioning

This document is versioned with a version: <year>q<quarter> header (currently 2026q2). Each revision carries a change log row.

Quarterly bump cadence

The allow-list is reviewed and, if needed, bumped once per quarter, aligned with AseptSoft's other published-key and published-set rotation cadences. New origins are appended at a quarter boundary. A bump that only adds origins is backwards-compatible — existing backends keep working until they pick up the new set on their next deployment refresh.

Deprecation window

When an origin must be removed, it enters a 6-month deprecation window before deletion:

  1. The origin is annotated in the change log with a removal-date: <year>q<quarter> at least two quarters in the future.
  2. It remains in the allow-list — and remains served — for the whole window.
  3. At the stated removal-date the origin is removed in that quarter's version bump.

Six months gives enterprise administrators time to plan, audit, and migrate any bookmarks or embedded links before a removed origin stops working.

Self-host configuration

Apply the canonical allow-list to whichever layer terminates browser traffic for your backend.

AseptSoft API — environment variable

If you run the AseptSoft API container directly, set the allow-list as a comma-separated environment variable. The API's built-in CORS policy reads it:

Cors__AllowedOrigins=https://app.aseptsoft.ch,https://app-ch.aseptsoft.ch,https://app-eu.aseptsoft.ch,https://app-us.aseptsoft.ch,https://app-ap.aseptsoft.ch

Azure Container Apps ingress

When deploying the API as an Azure Container App, set the same environment variable on the container (az containerapp shown; Bicep / Terraform equivalent):

az containerapp update \
  --name <your-api-app> \
  --resource-group <your-rg> \
  --set-env-vars \
    'Cors__AllowedOrigins=https://app.aseptsoft.ch,https://app-ch.aseptsoft.ch,https://app-eu.aseptsoft.ch,https://app-us.aseptsoft.ch,https://app-ap.aseptsoft.ch'

Container Apps ingress itself does not need a separate CORS rule — the API process applies the policy. If you additionally place a CORS rule on the ingress, keep it identical to this list.

nginx reverse proxy

If a reverse proxy terminates TLS in front of the API, match the request Origin against the fixed set — never reflect it blindly:

map $http_origin $aseptsoft_cors_origin {
    default                          "";
    "https://app.aseptsoft.ch"       $http_origin;
    "https://app-ch.aseptsoft.ch"    $http_origin;
    "https://app-eu.aseptsoft.ch"    $http_origin;
    "https://app-us.aseptsoft.ch"    $http_origin;
    "https://app-ap.aseptsoft.ch"    $http_origin;
}

server {
    location / {
        if ($aseptsoft_cors_origin) {
            add_header Access-Control-Allow-Origin      $aseptsoft_cors_origin always;
            add_header Access-Control-Allow-Credentials "true"                always;
            add_header Access-Control-Allow-Methods     "GET, POST, PUT, PATCH, DELETE, OPTIONS" always;
            add_header Access-Control-Allow-Headers     "*"    always;
            add_header Access-Control-Expose-Headers    "ETag, Location" always;
            add_header Access-Control-Max-Age           "600"  always;
        }
        if ($request_method = OPTIONS) {
            return 204;
        }
        proxy_pass http://aseptsoft-api;
    }
}

The map block resolves to an empty string for any unlisted origin, so the Access-Control-Allow-Origin header is omitted and the browser blocks the call.

Change log

version change removal-date
2026q2 Initial publication. V1 canonical set: app, app-ch, app-eu, app-us, app-ap.