Environments

Exact audiences, UAT versus production, and how scope is assigned.

Canonical audiences are exact HTTPS origins with no trailing slash. The application rejects run.app audiences and slash-suffixed values.

Environment Host Audience API client
UAT uat.modulate-api.es.flute.com https://uat.modulate-api.es.flute.com Yes — the only server offered
Production modulate-api.es.flute.com https://modulate-api.es.flute.com No
Local localhost:8080 http://localhost:8080 No (use Postman or curl)

A token minted for one audience cannot call another. Audience mismatch is an application 401, not a CORS failure.

Why UAT OPTIONS is unauthenticated

UAT disables Cloud Run invoker IAM so the browser-based API client can send an unauthenticated CORS preflight (OPTIONS). Every non-OPTIONS request still requires a valid identity token for a registered, enabled principal.

Production keeps Cloud Run invoker IAM. An unauthenticated preflight never reaches the application there, which is why production is absent from the API client's server list.

Organization and data-scope behavior

The registry assigns each principal an explicit scope:

  • Organization — the caller sees one organization's merchant portfolio. organization_id on /me is that organization.
  • System — the caller is a platform principal. /me reports scope.kind: system and null organization fields. System-scope enablement is an activation gate; these docs do not turn it on.

The browser never supplies a free-form upstream merchant identifier. Flute dashboard must authorize the signed-in user, load a local merchant record that user may access, and resolve the upstream id from that record. Missing, ambiguous, or unauthorized mappings fail closed without calling the API.