Auth0’s Deploy CLI is the key to treating your Auth0 configuration like code, but it’s not just about syncing settings; it’s about managing the evolution of your authentication system.

Let’s say you’ve got a new application that needs to integrate with Auth0. Instead of manually clicking through the dashboard, you can define its configuration in a JSON file and deploy it.

Here’s a simple tenant.json file representing a basic application, a custom login page, and a connection:

{
  "applications": [
    {
      "name": "My New App",
      "description": "The app that needs Auth0",
      "callbacks": [
        "https://myapp.example.com/callback"
      ],
      "allowed_logout_urls": [
        "https://myapp.example.com"
      ],
      "global": false,
      "app_type": "regular",
      "oidc_conformant": true,
      "grant_types": [
        "authorization_code",
        "refresh_token"
      ],
      "token_endpoint_auth_method": "client_secret_post"
    }
  ],
  "pages": {
    "login": {
      "html": "<html><body><h1>Welcome to My App!</h1><p>Please log in.</p></body></html>",
      "enabled": true
    }
  },
  "connections": [
    {
      "name": "MyDatabaseConnection",
      "strategy": "auth0",
      "metadata": {
        "signup_enabled": true
      },
      "enabled_clients": [
        "YOUR_AUTH0_APP_CLIENT_ID_HERE"
      ]
    }
  ]
}

To deploy this, you’d first set up your Auth0 tenant context:

a0deploy login --auth0-domain YOUR_AUTH0_DOMAIN --auth0-client-id YOUR_MGMT_API_CLIENT_ID --auth0-client-secret YOUR_MGMT_API_CLIENT_SECRET

Then, you can push your configuration:

a0deploy apply --input-file tenant.json

The Deploy CLI will compare your tenant.json with the current state in your Auth0 tenant. If "My New App" doesn’t exist, it creates it. If the login page HTML is different, it updates it. If "MyDatabaseConnection" exists but has signup_enabled set to false, it will flip it to true.

The real power comes when you start managing more complex aspects. Consider this tenant.json snippet for a custom rule:

{
  "rules": [
    {
      "name": "Add User Role to Token",
      "enabled": true,
      "script": "function (user, context, callback) {\n  // Add a custom claim for user role\n  const namespace = 'https://myapp.example.com/claims';\n  context.idToken[namespace] = context.idToken[namespace] || {};\n  context.idToken[namespace].role = user.app_metadata && user.app_metadata.role ? user.app_metadata.role : 'guest';\n  callback(null, user, context);\n}",
      "order": 10
    }
  ]
}

This rule adds a role claim to your ID tokens. When you deploy this, the CLI handles the creation or update of the rule. You can also manage things like APIs, scopes, branding, and much more.

The Deploy CLI operates by exporting the current state of your Auth0 tenant into a JSON format. When you run a0deploy apply, it performs a diff between your local JSON files and the remote tenant. It then generates and executes the necessary Management API calls to synchronize the two. This means that any change you make locally, whether it’s adding a new connection or modifying an existing rule, is translated into precise API instructions.

When you’re pushing changes, the CLI is smart about dependencies. If you define an application and then try to assign it to a connection that doesn’t exist in your local tenant.json, the CLI will typically error out, forcing you to define all necessary components together. This ensures a consistent deployment.

A truly surprising aspect of the Deploy CLI is its ability to manage tenant-wide settings that aren’t typically thought of as deployable assets. For example, you can control features like "B2C user registration" or "Allow users to sign up" via the tenant.json file, under the settings key. This allows for the full automation of tenant provisioning and configuration, not just application-specific elements.

{
  "settings": {
    "universal_login": {
      "allow_sign_ups": true,
      "enable_user_signup": true
    },
    "enterprise_connections": {
      "windows_azure_active_directory": {
        "enabled_domain_filtering": true
      }
    }
  }
}

This means you can literally spin up a new Auth0 tenant from scratch, including all its core settings, just by applying a well-crafted JSON configuration.

The next hurdle you’ll likely face is handling sensitive information and secrets within your deployable configuration, such as client secrets for external identity providers.

Want structured learning?

Take the full Auth0 course →