# Production ACUL Deployment Checklist

Deploy order is strict: complete the backend prerequisites (Section 2) before the application deploy (Section 3), then configure the tenant (Section 4).

## 1. Application code (in the release build)
- [ ] Add the production Auth0 client IDs to the ACUL bundle brand map (`apps/auth0-acul/src/login.ts`):
    - `JiDtizzzIAE516WLaCrXFYOvAWNLcrBz` -> NetFoundry Console (classic)
    - `NyJe4ojIAKEFQCkYmB5OHkpy8KPyGlDC` -> Customer Connect (modern)
- [ ] Set `domain: 'login.netfoundry.io'` and `newUniversalLogin: true` in the production environment files:
    - `apps/cloud-ziti/src/environments/environment.prod.ts`
    - `apps/nfconsole/src/environments/environment.prod.ts`
    - `apps/nfconsole/src/environments/environment.siemens-production.ts`
    - Customer Connect (separate repo): `src/environments/environment.production.ts`
- [ ] Confirm the rendering configuration declares all six ext- parameters: ext-idps, ext-brand, ext-logol, ext-logod, ext-app, ext-theme.

## 2. Backend prerequisites (required before the application deploy)
- [ ] Configure the identity gateway to trust login.netfoundry.io as a token issuer (accept its iss claim and JWKS), while retaining trust for netfoundry-production.auth0.com, to allow a zero-downtime cutover.
- [ ] Update the CSP (Lambda@Edge) headers on the production distributions: add login.netfoundry.io to frame-src, child-src, and connect-src.

## 3. Application deploy
- [ ] Deploy the production build so that login.js and login.css are published to https://cloudziti.io/assets/acul.
- [ ] Verify both assets return HTTP 200 and include the header Access-Control-Allow-Origin: https://login.netfoundry.io (the bundle is loaded cross-origin by Auth0).
- [ ] Ensure deploys reliably reach users. Today the tenants point at the stopgap `<env>-cloudziti.io/assets/acul` path, which has no Cache-Control and non-SRI head_tags, so browsers/CDN can keep serving a stale bundle after a deploy (observed on staging: the passkey-enrollment card showed the pre-deploy version until a hard refresh). The proper fix is already built and live: the versioned immutable origin `acul.<console_domain>` (terraform/acul.tf, Cache-Control: immutable) plus SRI head_tags from gen-rendering.mjs — no app code needed. Wire the deploy to it: upload to s3://nf-acul-<env>/v/<build-id>/, run gen-rendering with ACUL_ASSET_BASE_URL=https://acul.<console_domain>/v/<build-id>, then apply that rendering.json (SRI) to every tenant screen. See acul-asset-caching-recommendation.md.

## 4. Production Auth0 tenant configuration (after the build is live)
- [ ] Confirm the custom domain login.netfoundry.io is verified and set as primary.
- [ ] Set the tenant Universal Login logo_url to a valid hosted logo (for example, https://nfconsole.io/assets/icons/android-icon-192x192.png) to prevent a broken image on standard-rendered screens such as passkey enrollment.
- [ ] Configure the login screen: set rendering_mode to advanced, point the head tags to the production asset path, and include the six ext- parameters in context_configuration.
- [ ] Apply the same rendering configuration to the signup-id and signup-password screens (the branded create-account screens invitees see; requires the identifier_first flow).
- [ ] On each enterprise connection, enable "Display connection as a button" (show_as_button: true) and set a clear display_name.
- [ ] (Optional - passkeys / Identifier-First) Apply the same rendering configuration to the login-id and login-password screens, enable the passkey authentication method on the database connection, then set identifier_first: true. This changes the login to a two-step flow for all users.
- [ ] (Passkeys) Apply the same rendering configuration to the passkey-enrollment and passkey-enrollment-local screens so the post-login "Set up a passkey" prompt shows the branded card instead of Auth0's default. Note: in the Management API these two screens live under the `passkeys` prompt (PATCH /prompts/passkeys/screen/passkey-enrollment/rendering), not a prompt named passkey-enrollment. Copy head_tags + context_configuration verbatim from the login-id screen.
- [ ] Verify the Customer Connect production Auth0 client's allowed callback, logout, and web-origin URLs are correct.

## 5. Verification
- [ ] Complete an end-to-end login for each application (CloudZiti, NetFoundry Console, Customer Connect) and confirm a successful redirect into the application with no authorization errors.
- [ ] Confirm the correct theme (organization default for the consoles, browser preference for Customer Connect), page title, and subtitle.
- [ ] Confirm identity provider buttons render with the correct icons and labels, and that enterprise email-domain routing works.
- [ ] (If passkeys enabled) Confirm passkey enrollment shows the branded screen and completes.
- [ ] Send a test invitation and confirm the invitee lands on the branded Create Account screen, not Sign In.

## 6. Rollback
- [ ] Revert the tenant login screen rendering_mode to standard, or set newUniversalLogin to false and redeploy. Retain the dual-issuer gateway configuration.
