# Auth0 best practices

## Package Manager & Testing

This project uses **pnpm** as the package manager and **Vitest** for unit testing.

> **Note:** The `integration-tests` directory is an exception—it still uses **Jest**.

### All auth0 Application, API, & Rule names are lowercase and with dashes instead of spaces.

_Multifactor-Guardian-Do-Not-Rename is an exception to the rule._

**DO**

-   a0deploy-cli-client
-   orchard-machine-to-machine
-   auth0-management-api
-   force-email-verification
-   Multifactor-Guardian-Do-Not-Rename

**DON'T**

-   a0deploy CLI Client
-   The Orchard Machine-To-Machine
-   Auth0 Management API
-   multifactor-guardian-do-not-rename

## Deployment

```shell
pnpm run deploy
```

### Env var replacement

The deployment script will load the `config/import.${ENV}.json` file and replace all values wrapped like `##[var-name]##` with environment variables.
It will first lookup matching environment variables using the `ENV` as suffix.
Example:
Given ENV=prod and for the value `##INSIGHTS_CLIENT_ID##`;
The deployment/import script will replace it with the value of the `INSIGHTS_CLIENT_ID_PROD` environment variable, falling back to `INSIGHTS_CLIENT_ID`.
If the environment variable is not defined, the script will throw an error.

### auth0 cli deploy

In order to deploy to all 3: dev, qa and prod tenants we are using the `auth0-deploy-cli` node library.
As of version auth0-deploy-cli@8.4.4, it deploys

-   Actions
-   Branding
-   Client Grants
-   Clients (Applications)
-   Connections
-   Custom Domains
-   Email Templates
-   Emails
-   Grants
-   Guardian
-   Hook Secrets
-   Log Streams
-   Migrations
-   Organizations
-   Pages
-   Prompts
-   Resource Servers (APIs)
-   Roles
-   Tenant Settings

More information can be found in the [official documentation](https://auth0.com/docs/deploy-monitor/deploy-cli-tool).

Jenkins job will read `config/${ENV}.env` file and export those variables.
Also, it will read secret names from `config/secret_names.txt`, get corresponding secrets from AWS in format `${ENV}/auth0-hosted-pages/${SECRET_NAME}` and export as environment variables.

### Note:

-   As of now for dev setup > email redirect urls are not dynamic to different devboxes. Developers testing email functionality, should manually change them on Auth0 Dashboard.
-   Dashboard admin and other extension clients need to be added manually. They will not be created/updated from cli.
-   Tenant level `initiate_login_uri` need to be set manually using Management API. Refer section below.

## Non-verifiable callback URI confirmation

Auth0 can show an "Authorize App" confirmation on login for non-verifiable (`localhost`/`http`) callbacks, which breaks silent SSO for local dev. We control it with `skip_non_verifiable_callback_uri_confirmation_prompt`: tenant-wide in `src/tenant.json` (per-env values in `config/import.{env}.json`), and overridable per app in `src/clients/*.json` (app setting wins over tenant). Check those files for the current setup. As of 2026-07-08 it's off for local dev and kept on in prod, with two per-app exceptions: `apollo-mcp-login` opts back in (localhost loopback tool that wants the prompt), and `orchard-go-login` opts out in prod too (its native custom-scheme callbacks are non-verifiable, so the prompt fires for real mobile users). The orchardgo opt-out is temporary until the mobile team moves orchardgo to claimed https deep links (App Links / Universal Links) in their own repo. That mix can grow or be dropped over time. Manage it here, not the dashboard, deploys overwrite it.

# When Creating a new tenant

In certain cases where users have bookmarked the auth0 url or when the manually hit http://workstation.auth0.com/login without valid params, Auth0 could redirect back to the application's login page to initiation the /authorization with correct params. To do so we have to execute below Management API request for each tenant when it is created.

```
curl -X PATCH \
  https://workstation.auth0.com/api/v2/tenants/settings \
  -H 'Authorization: Bearer <mgmt-token>' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' \
  -d '{"default_redirection_uri": "https://workstation.theorchard.com/login/v2"}'
```

The login_url should point to a route in the application that ends up redirecting to Auth0's /authorize endpoint, e.g. http://yoursite.com/login. Refer https://auth0.com/docs/universal-login/default-login-url for more details

# GitHub Source Control Integration

Under [Extensions](https://manage.auth0.com/#/extensions) you'll find the GitHub Deploy extension which allows you to manage your Database Connections and Rules in a GitHub repository.

## Deploying Pages

For Hosted Pages you'll created an html file and a json file (for enabled/disabled status) under `src/pages`. Supported hosted pages:

```
error_page
guardian_multifactor
login
password_reset
```

> **Note:** As of 2025, these hosted pages are likely to be deprecated and replaced by the new [Universal Login](https://auth0.com/docs/universal-login) experience. The Universal Login approach is very similar, but the files are now located under `src/branding/templates`, also using a pair of HTML and JSON files for each template.

## Deploying Emails

For emails, there is a `src/emails` directory containing predefined email templates provided by Auth0 (such as `user_invitation` or `reset_email`).

These email templates work similarly to Hosted Pages: they consist of a tuple of `{template_name} (.html|.json)` files for each template, the HTML file defines the body and allows liquid syntax on it and the JSON file has metadata information like `subject` and other configurations, also allowing liquid syntax.

> **Old way:** Place the `.html` and `.json` files in the same directory. The deploy script will upload them directly to Auth0 as-is.

> **New way:** The target files are not committed to version control and ".gitignored" for safety. Instead, they are being generated at deploy time by the `prebuild` script. The script processes `.liquid` files from `src/emails` (and the `/partials` and `/i18n` folders), producing the final `.html` and `.json` files. This was needed as per the complexity of templates and their associated metadata (such as the `resultUrl` field) increased, maintaining everything in a single file/field becaming impractical. The prebuild system allows for better organization and supports unit testing of templates and even the metadata fields.

If you are set to migrate any existing static `.html` files to the composable `.liquid` prebuild system, please review some of the already migrated examples.

# Email Preview Instructions

1. Prepare your data file:

    - In the folder `scripts/manual-management/emails/preview/mocks`, copy the shadow file `{templateName}.data.json.shadow` and rename the copy to something like `user_invitation-orchard_settings.data.json` (for template `user_invitation`, and ideally naming after "-" with some hint about the context inside).
      These files are gitignored if following this naming pattern, so you can create as many as you want to preview different scenarios.

2. Configure your environment variable:

    - In your `.env` file, set the variable that defines both the template to be used and its associated data file (mimicking the request from ows-users to the Auth0 API):
        ```
        EMAIL_PREVIEW_FILE_PATH=scripts/manual-management/emails/preview/mocks/user_invitation-orchard_settings.data.json
        ```

3. Run the preview script:

    - Execute the command:
        ```
        pnpm dev:emails
        ```
        This will generate the HTML preview and start a local BrowserSync dev server serving the output.

4. View the preview:
    - Open your browser and navigate to:
      http://localhost:3000/${templateName}.html
   (Where `${templateName}`is the name of the template you are previewing, e.g.,`user_invitation`).

## Deploying Database Connection Scripts

For Database Connections you create a directory under `database-connections` which contains the name of your Database Connection (in exactly the same way as you named it in Auth0). And under this directory you'll create 1 file for every script you want to use. Only the `login` script is required in a Custom Database connection. If you enabled the migration feature, you'll also need to provide the `get_user` script.

Allowed scripts:

```
get_user.js
create.js
verify.js
login.js
change_password.js
delete.js
```

An example can be found [here](database-connections/my-custom-db).

## Running integration tests

-   Setup CLI [AWS access](https://www.notion.so/AWS-Access-f841b9dd815d4443a80e96a86c92cd2f)
-   `cp auth0-hosted-pages/integration-tests/.env.shadow auth0-hosted-pages/integration-tests/.env`
-   Fill missing values in `.env` file with secrets from AWS Secret Manager. Test secrets can be found by `qa/auth0-hosted-pages/TESTS_` prefix.
-   Add your IP address to [auth0 IP AllowList](https://manage.auth0.com/dashboard/us/qa-orchard/security/attack-protection/bot-detection)
-   Finally, run `pnpm test:integration`
