diff --git a/main/.mintlify/skills/auth0/SKILL.md b/main/.mintlify/skills/auth0/SKILL.md index dc5a4bc3bf..bb9faf8c45 100644 --- a/main/.mintlify/skills/auth0/SKILL.md +++ b/main/.mintlify/skills/auth0/SKILL.md @@ -311,7 +311,7 @@ Read: references/tooling-{tooling}/index.md ### feature:passkeys ``` Read: references/feature-passkeys/index.md -Then Read the detected SDK's passkey leaf from the hub's "Example code snippets" table (e.g. nextjs → references/feature-passkeys/nextjs-auth0.md, react → references/feature-passkeys/auth0-react.md) — the leaf has the exact API surface and the required ceremony; do not implement from framework-{framework}/index.md alone. +Then Read the detected SDK's passkey leaf from the hub's "Example code snippets" table (e.g. nextjs → nextjs-auth0.md; react-native/expo → ONLY react-native-auth0.md, which covers react-native-web — never auth0-react.md) — it has the exact API and ceremony; don't implement from framework-{framework}/index.md alone. Read: references/tooling-{tooling}/index.md If framework detected: Read references/framework-{framework}/index.md ``` diff --git a/main/.mintlify/skills/auth0/references/feature-audit-remediation/index.md b/main/.mintlify/skills/auth0/references/feature-audit-remediation/index.md index 6b5d040acf..1f8c726377 100644 --- a/main/.mintlify/skills/auth0/references/feature-audit-remediation/index.md +++ b/main/.mintlify/skills/auth0/references/feature-audit-remediation/index.md @@ -15,16 +15,16 @@ For each item, build the command. **Use a first-class subcommand when one exists | Breached password detection | `auth0 protection breached-password-detection update` | `PATCH attack-protection/breached-password-detection` | | Suspicious IP throttling | `auth0 protection suspicious-ip-throttling update` | `PATCH attack-protection/suspicious-ip-throttling` | | Branding (universal login, colors, logo) | `auth0 universal-login update` (alias `auth0 ul update`) | `PATCH branding` | -| Custom domains | `auth0 domains create` / `update ` | `POST custom-domains` / `PATCH custom-domains/` | -| Connections (DB, social, enterprise) | (none) | `PATCH connections/` (full options blob) | +| Custom domains | `auth0 domains create` / `update ` / `domains default set ` / `domains default show` | `POST custom-domains` / `PATCH custom-domains/` | +| Connections (DB, social, enterprise) | `auth0 connections create` / `update ` / `delete --force` | `PATCH connections/` (full options blob) | | APIs / resource servers | `auth0 apis update ` | `PATCH resource-servers/` | | Apps / clients (callbacks, origins, grant types, refresh tokens) | `auth0 apps update ` | `PATCH clients/` | | Roles | `auth0 roles update ` | `PATCH roles/` | | Actions | `auth0 actions create/update /deploy ` | `POST actions/actions` / `PATCH actions/actions/` / `POST actions/actions//deploy` | | Log streams | `auth0 logs streams create ` / `update ` (provider is required: `eventbridge`, `eventgrid`, `http`, `datadog`, `splunk`, or `sumo`) | `POST log-streams` / `PATCH log-streams/` | | Email provider/templates | `auth0 email provider update` / `auth0 email templates update` | `PATCH emails/provider` / `PATCH email-templates/` | -| MFA factor toggles | (none) | `PUT guardian/factors/` | -| MFA policies | (none) | `PUT guardian/policies` | +| MFA factor toggles | `auth0 guardian factors set --enabled` | `PUT guardian/factors/` | +| MFA policies | `auth0 guardian policies set --policy ` | `PUT guardian/policies` | | Prompts customization | `auth0 universal-login prompts update ` (alias `auth0 ul prompts update`) | `PUT prompts//custom-text/` | | Network ACLs | `auth0 network-acl create` / `update ` | `POST network-acls` / `PATCH network-acls/` | | Auth0 Organizations | `auth0 orgs create` / `update ` | `POST organizations` / `PATCH organizations/` | @@ -102,7 +102,7 @@ Even in Express mode, these commands are blocked unless the user explicitly type - `auth0 logout` - `auth0 tenants delete` - `auth0 apps delete` (any app, especially the CheckMate app) -- `auth0 api delete "connections/"` (no first-class delete command exists for connections) +- `auth0 connections delete --force` - `auth0 api delete ` ## Closing the run diff --git a/main/.mintlify/skills/auth0/references/feature-audit/index.md b/main/.mintlify/skills/auth0/references/feature-audit/index.md index d99dc3ed6e..dce79d0884 100644 --- a/main/.mintlify/skills/auth0/references/feature-audit/index.md +++ b/main/.mintlify/skills/auth0/references/feature-audit/index.md @@ -55,7 +55,7 @@ Checks to run in parallel (no chat output during checks): | CLI installed | `auth0 --version` | version or missing | | Tenant session | `auth0 tenants list --json` | first tenant or none | | CheckMate app | `auth0 apps list --json \| jq '.[]\|select(.name\|test("CheckMate";"i"))'` | client_id or none | -| M2M scopes | `auth0 api get client-grants?client_id=` | scope count or none | +| M2M scopes | `auth0 client-grants list --client-id ` | scope count or none | | CheckMate npm | `command -v a0checkmate` | path or missing | | Node version | `node -v` | version or missing | | Reviewer | read `state/operator.json` | name or missing | @@ -132,7 +132,7 @@ For non-interactive shells (CI, agent without TTY), or private cloud tenants, us When an access token expires, the CLI prompts to confirm the default tenant (`Continue login with default tenant 'your-tenant.auth0.com'? [y/N]`) or lets you pick a different one — select `y` to proceed with the default, `N` to choose another. Note that CLI usage consumes Management API rate limits according to the subscription plan. ### 1.2 Pin tenant -Save the tenant domain returned by `auth0 tenants list --json` (`.[0].domain` if only one, otherwise ask the user to pick) into `state/setup.json.tenant_domain`. **Don't parse region from the domain suffix** — use the value the CLI returns. Custom domains (private cloud) are valid here. +Save the tenant domain returned by `auth0 tenants list --json` (`.[] | select(.active) | .name` for the active tenant; if several tenants, ask the user to pick) into `state/setup.json.tenant_domain`. **Don't parse region from the domain suffix** — use the value the CLI returns. Custom domains (private cloud) are valid here. **This pinned `tenant_domain` is the canonical Auth0-hosted URL.** Every report reference to the tenant URL — header right rail, "authentication is served from ``" narrative, CLI commands — reads from `state/setup.json.tenant_domain`. Never derive it from the company context, never parse it from the company domain. The company context provides company-level fields (name, products, business model, integrations) — never the tenant URL. @@ -168,13 +168,11 @@ read:guardian_factors read:mfa_policies read:actions read:log_streams read:logs read:network_acls read:event_streams read:hooks read:rules ``` -Grant via the Management API (the CLI `auth0 api` is a raw wrapper): +Grant the Management API scopes with a client grant: ```bash -auth0 api post "client-grants" --data '{ - "client_id":"", - "audience":"https:///api/v2/", - "scope":["read:tenant_settings","read:custom_domains","read:prompts","read:clients","read:connections","read:connections_options","read:resource_servers","read:client_grants","read:roles","read:branding","read:email_provider","read:email_templates","read:phone_providers","read:phone_templates","read:shields","read:attack_protection","read:self_service_profiles","read:guardian_factors","read:mfa_policies","read:actions","read:log_streams","read:logs","read:network_acls","read:event_streams","read:hooks","read:rules"] -}' +auth0 client-grants create --client-id "" \ + --audience "https:///api/v2/" \ + --scopes "read:tenant_settings,read:custom_domains,read:prompts,read:clients,read:connections,read:connections_options,read:resource_servers,read:client_grants,read:roles,read:branding,read:email_provider,read:email_templates,read:phone_providers,read:phone_templates,read:shields,read:attack_protection,read:self_service_profiles,read:guardian_factors,read:mfa_policies,read:actions,read:log_streams,read:logs,read:network_acls,read:event_streams,read:hooks,read:rules" ``` Some tenants reject `read:hooks` / `read:rules` (deprecated). On 400, retry without those two and proceed. @@ -279,11 +277,11 @@ The Phase 5 report needs more than CheckMate alone provides. Run these in parall ```bash auth0 apps list --json # apps_list — count + names for Section 1, 3, 4 auth0 logs list --number 50 --json # logs_sample — to flag "Active" login activity -auth0 api get tenants/settings # tenant_settings — for "Current Auth0 Tier" detection (look for plan/subscription hints; fallback "Free Plan"). Map detected features against the pricing reference to infer the tier when no explicit plan field is present. -auth0 api get custom-domains # custom_domains — empty array → triggers "Branding Gap" -auth0 api get connections # connections — for enterprise-connection check -auth0 api get log-streams # log_streams — empty array → triggers "Observability Gap" -auth0 api get attack-protection/breached-password-detection # for "Account Security" section +auth0 tenant-settings show --json # tenant_settings — for "Current Auth0 Tier" detection (look for plan/subscription hints; fallback "Free Plan"). Map detected features against the pricing reference to infer the tier when no explicit plan field is present. +auth0 domains list # custom_domains — empty array → triggers "Branding Gap" +auth0 connections list # connections — for enterprise-connection check +auth0 logs streams list # log_streams — empty array → triggers "Observability Gap" +auth0 protection breached-password-detection show # for "Account Security" section ``` These outputs feed directly into the Phase 5 fusion. diff --git a/main/.mintlify/skills/auth0/references/feature-branding/index.md b/main/.mintlify/skills/auth0/references/feature-branding/index.md index 7d4ce46215..df78197c01 100644 --- a/main/.mintlify/skills/auth0/references/feature-branding/index.md +++ b/main/.mintlify/skills/auth0/references/feature-branding/index.md @@ -7,7 +7,7 @@ Style Auth0 Universal Login to match a brand. Covers the theme (colors, typograp When this skill is invoked **with a specific intent** in the opening message (e.g., "brand my tenant from ferrari.com", "reset the theme", "check if Universal Login is on"), parse the intent and route directly to the matching capability below. Do not show a picker. -When this skill is invoked **without intent** (bare `/auth0-branding`, or a vague "help me with branding"), show the table below and ask in one line: "Pick a number, name one, or describe what you want." Parse the reply — accept `1`, `"brand my tenant"`, or `"make it look like acme.com"` equivalently. +When this skill is invoked **without intent** (just "auth0 branding" or a vague "help me with branding"), show the table below and ask in one line: "Pick a number, name one, or describe what you want." Parse the reply — accept `1`, `"brand my tenant"`, or `"make it look like acme.com"` equivalently. | # | Capability | What it does | |---|---|---| @@ -19,6 +19,12 @@ When this skill is invoked **without intent** (bare `/auth0-branding`, or a vagu The **Prerequisites** section applies to all capabilities. +## When to ask + +For a non-destructive change, ask only when information is missing or ambiguous. If the request already gives what the step needs (the values, the target screen and language, and a tenant that matches the active one), restate the change in one line and apply it in the same turn; do not end on a question the request already answers. Ask and wait when something is missing or unclear: no brand color or logo URL, an ambiguous screen, or a tenant that does not match. + +This does not relax destructive paths. Capability 4 (reset), deletes, and empty-body custom-text clears keep their backup offer, their confirmations, and the production confirmation, in every mode. + ## Prompt style Prefer free-text prompts. The skill should parse natural replies, not force clicks. Use `AskUserQuestion` **only** when one of these applies: @@ -104,9 +110,9 @@ auth0 tenants list # shows all tenants; the active one is marked with → auth0 tenants use # switch active tenant; prompts for browser login if not already authenticated ``` -**Before any write operation in any capability, run `auth0 tenants list`, show the active tenant to the user, and get explicit confirmation to proceed.** If it's the wrong tenant, stop. Tell the user to run `auth0 tenants use ` (or `auth0 login` if the target isn't in the list) themselves and re-invoke the skill. Do not try to switch tenants on the user's behalf. +**Before any write operation in any capability, run `auth0 tenants list` and show the active tenant to the user.** For a non-destructive change, if the user's request already identifies the tenant (by name or domain, or as "our tenant" with a single tenant in the list) and the active tenant matches, state it in one line and carry on in the same turn. Otherwise, and always for resets and deletes, get explicit confirmation to proceed before writing. If it's the wrong tenant, stop. Tell the user to run `auth0 tenants use ` (or `auth0 login` if the target isn't in the list) themselves and re-invoke the skill. Do not try to switch tenants on the user's behalf. -For non-interactive or multi-tenant automation, skip the CLI and call the **Management API** directly with an explicit domain + bearer token per call. (see the cURL examples section below) +If the `auth0` CLI is not installed or is not logged in to any tenant, call the **Management API** directly with an explicit domain and bearer token per call (see the cURL examples section below). A different active tenant is not a reason to fall back: stop as described above. Otherwise, use the CLI, including for non-interactive runs. **Tooling note.** The `auth0 ul` commands below are one way to write branding settings. The loaded tooling reference has the equivalent for infrastructure-as-code projects: the Terraform `auth0_branding` resource (`logo_url`, `favicon_url`, `colors` block). The Auth0 MCP server exposes **no** branding/Universal Login tool — for an MCP-only session, fall back to the CLI, Terraform, or the Management API directly. This interactive branding workflow (extract → propose → apply) stays CLI/API-driven regardless, because it is a guided flow rather than a static config write. @@ -208,10 +214,12 @@ Complete Management API endpoints, CLI commands, configuration options, and erro | PATCH | `/api/v2/branding/themes/{themeId}` | Update a theme | `update:branding` | | DELETE | `/api/v2/branding/themes/{themeId}` | Delete a theme | `delete:branding` | +**No `auth0 ul themes` subcommand exists yet — use `auth0 api` for all theme CRUD (GET/POST/PATCH/DELETE `branding/themes/...`).** + **Theme behavior notes:** - `GET /branding/themes/default` returns 404 if no theme has been created yet. Create one with POST first. -- PATCH requires all top-level sections (`colors`, `fonts`, `borders`, `widget`, `page_background`). To update one field, GET the current theme, merge your change, then PATCH the full object. -- Each theme has a `displayName` string field (optional, used for identification). +- PATCH requires all top-level sections (`colors`, `fonts`, `borders`, `widget`, `page_background`). To update one field, GET the current theme, merge your change, then PATCH the full object. Carry `displayName` over too: a PATCH without it resets the theme name to "Unnamed Theme". +- On a tenant with a theme, the theme sets the colors that users see. In an Organization context, configured Organization branding can override tenant branding on out-of-the-box Universal Login prompts, including primary and page background colors. The button color is `colors.primary_button`; send color changes with a GET, merge and PATCH on `branding/themes/`. - The response includes a `themeId` string used in subsequent PATCH/DELETE calls. ### Universal Login Templates @@ -229,6 +237,8 @@ Complete Management API endpoints, CLI commands, configuration options, and erro | GET | `/api/v2/prompts//custom-text/` | Get custom text | `read:prompts` | | PUT | `/api/v2/prompts//custom-text/` | Set custom text (replaces all) | `update:prompts` | +With the CLI: read with `auth0 ul prompts show -l ` and write with `auth0 ul prompts update -l --data '...'`. + ## CLI Commands ### Branding Settings @@ -241,7 +251,8 @@ auth0 ul show --json # Update branding (interactive) auth0 ul update -# Update branding (non-interactive) +# Update branding (non-interactive). --accent and --background set classic +# branding colors only; on a tenant with a theme, change colors on the theme instead. auth0 ul update --accent "#0059DB" --background "#FFFFFF" \ --logo "https://example.com/logo.svg" \ --favicon "https://example.com/favicon.ico" \ @@ -268,9 +279,9 @@ auth0 ul templates update auth0 ul prompts show login auth0 ul prompts show signup -l es -# Update custom text (interactive) -auth0 ul prompts update login -auth0 ul prompts update signup -l es +# Update custom text (non-interactive; replaces the prompt's existing text, so show it first and merge) +auth0 ul prompts update login --data '{"login":{"title":"Welcome back"}}' +auth0 ul prompts update signup -l es --data @signup-es.json ``` ### Customization Editor @@ -608,23 +619,27 @@ Common prompts you can customize (not a complete list; Auth0 supports additional ### API Behavior -The `PUT /api/v2/prompts//custom-text/` endpoint **replaces** all custom text for that prompt and language. To update one screen without losing others, first GET the current text, merge your changes, then PUT the full object back. +`auth0 ul prompts update -l --data '...'` **replaces** all custom text for that prompt and language (it sends a `PUT` to `/api/v2/prompts//custom-text/`). To update one screen without losing others, first read the current text, merge your changes, then write the full object back. `GET` returns only the keys you have explicitly set, not the full set of Auth0 default strings. An empty object (`{}`) means no custom text is set and Auth0's defaults are used. ```bash -# Get current text, modify, then set -CURRENT=$(auth0 api get "prompts/login/custom-text/en") -# Merge changes into $CURRENT -auth0 api put "prompts/login/custom-text/en" --data "$UPDATED" +# 1. Read the current custom text for the prompt +auth0 ul prompts show login-id -l en + +# 2. Merge your changes into that object, then write the whole object back +auth0 ul prompts update login-id -l en \ + --data '{"login-id":{"title":"Welcome back","buttonText":"Continue"}}' ``` +Use `auth0 api put "prompts//custom-text/" --data '...'` only when the typed command is not available in your CLI version. + ### Delete Custom Text Send an empty object to remove all custom text for a prompt: ```bash -auth0 api put "prompts/login/custom-text/en" --data '{}' +auth0 ul prompts update login -l en --data '{}' ``` --- @@ -645,7 +660,9 @@ The custom-text API is **per-prompt, not per-screen**. Multiple screens under th ## Login -**Identifier-first note:** `login-id` and `login-password` are each their own prompt, not screens nested under the `login` prompt. Each takes a separate `PUT /prompts/{prompt}/custom-text/{lang}` call with a body keyed by the screen name matching the prompt name (e.g., `{ "login-id": { ... } }`). Do not batch them under `login`. +**Identifier-first note:** `login-id` and `login-password` are each their own prompt, not screens nested under the `login` prompt. Each takes a separate `auth0 ul prompts update -l --data '...'` call with a body keyed by the screen name matching the prompt name (e.g., `auth0 ul prompts update login-id -l en --data '{"login-id":{...}}'`). Do not batch them under `login`. + +**Turning identifier-first on:** custom text does not change the login flow. The tenant-wide setting is `identifier_first` on `/prompts`, and the CLI has no typed command for it, so use `auth0 api patch prompts --data '{"identifier_first":true}'`. It sends only that field, so other login settings are untouched. Read the current value first with `auth0 api get prompts`. | Prompt | Screen | |---|---| @@ -961,8 +978,8 @@ auth0 ul show --json > branding-settings.json auth0 ul templates show > login-template.liquid # Export custom text for prompts you've customized -auth0 api get "prompts/login/custom-text/en" > text-login-en.json -auth0 api get "prompts/signup/custom-text/en" > text-signup-en.json +auth0 ul prompts show login -l en > text-login-en.json +auth0 ul prompts show signup -l en > text-signup-en.json ``` ### Deploy branding in a pipeline @@ -1025,13 +1042,13 @@ SOURCE_TENANT=source-tenant.auth0.com TARGET_TENANT=target-tenant.auth0.com # Export from source tenant -BRANDING=$(auth0 api get "branding" --tenant "$SOURCE_TENANT") +BRANDING=$(auth0 ul show --json --tenant "$SOURCE_TENANT") THEME=$(auth0 api get "branding/themes/default" --tenant "$SOURCE_TENANT" 2>/dev/null || true) TEMPLATE=$(auth0 api get "branding/templates/universal-login" --tenant "$SOURCE_TENANT" 2>/dev/null || true) -LOGIN_TEXT=$(auth0 api get "prompts/login/custom-text/en" --tenant "$SOURCE_TENANT" 2>/dev/null || true) +LOGIN_TEXT=$(auth0 ul prompts show login -l en --tenant "$SOURCE_TENANT" 2>/dev/null || true) # Import to target tenant -printf '%s' "$BRANDING" | auth0 api patch "branding" --tenant "$TARGET_TENANT" +auth0 ul update --data "$BRANDING" --tenant "$TARGET_TENANT" if [ -n "$THEME" ]; then THEME_BODY=$(printf '%s' "$THEME" | jq 'del(.themeId)') @@ -1048,7 +1065,7 @@ if [ -n "$TEMPLATE" ]; then fi if [ -n "$LOGIN_TEXT" ]; then - printf '%s' "$LOGIN_TEXT" | auth0 api put "prompts/login/custom-text/en" --tenant "$TARGET_TENANT" + auth0 ul prompts update login -l en --data "$LOGIN_TEXT" --tenant "$TARGET_TENANT" fi ``` @@ -1065,9 +1082,9 @@ auth0 test login "{yourAppClientId}" auth0 test login --organization org_abc123 # Verify via API -auth0 api get "branding" | jq '.colors' +auth0 ul show --json | jq '.colors' auth0 api get "branding/themes/default" | jq '.colors.primary_button' -auth0 api get "branding/templates/universal-login" | jq '.template' | head -1 +auth0 ul templates show | head -1 ``` --- @@ -1223,7 +1240,7 @@ Editable knobs and what each reply means: ## Confirm target tenant -Before any write, run `auth0 tenants list` and present the active tenant: +Before any write, run `auth0 tenants list` and present the active tenant. For a non-destructive change where the request already identifies a matching tenant, state it in one line and continue instead of waiting on the prompt below; resets and deletes always wait: ```text Target tenant: acme-prod (active in the Auth0 CLI) @@ -1247,7 +1264,7 @@ Before writing, validate any URL-valued fields (logo, favicon, font, background 3. **Page template** (only if the user pasted one via `[edit]` AND the tenant has a custom domain): `PUT /api/v2/branding/templates/universal-login`. Refuse the PUT if the template is missing `auth0:head` or `auth0:widget`. 4. **Voice rewrites** (only if `[edit] → voice rewriting` was enabled): hand off to the Match Brand Voice section with the primary-color/font context so it doesn't re-ask. -Before writing, diff the proposed changes against current tenant state. In production environments, require explicit confirmation. Auth0 does not retain prior theme/template/text versions; if the user wants a backup, suggest exporting current state locally before applying (see the backup flow in the Rollback section below). +Before writing, diff the proposed changes against current tenant state. In production environments, require explicit confirmation, even when the request is fully specified. Auth0 does not retain prior theme/template/text versions; if the user wants a backup, suggest exporting current state locally before applying (see the backup flow in the Rollback section below). Report what was written and what was skipped (for example, "page template skipped — no custom domain configured"). If voice rewriting was opted in, chain into Capability 3 after the theme write succeeds. @@ -1326,16 +1343,16 @@ The user never needs to know the API field names or which surface a setting live ## Flow 1. Load current tenant state once at the start of the session: theme (`GET /branding/themes/default`), tenant branding (`GET /branding`), and (lazily) current page template + custom text when the request targets them. Cache for the session so disambiguation prompts can show current values. -2. Ask: **"What do you want to change?"** +2. If the user's latest message already says what to change, skip this question. Otherwise ask: **"What do you want to change?"** 3. Parse the user's request and resolve it to one or more specific fields using the **Intent mapping** table below. 4. Disambiguate only when needed. If the mapped target is unique, skip ahead. If multiple fields are plausible, ask one question and show current values so the user can see what they'd be changing: > "'button color'; which one? > [a] Primary button fill (currently `#533AFD`) > [b] Primary button label/text (currently `#FFFFFF`) > [c] Secondary button border (currently `#CCCCCC`)" -5. Restate the concrete change in plain language ("change primary button fill from `#533AFD` to `#FF5733`") and confirm. +5. Restate the concrete change in plain language ("change primary button fill from `#533AFD` to `#FF5733`"). Confirm only if something is ambiguous; when the request gave exact values, apply it, except on a production tenant, where Apply still requires explicit confirmation. 6. Stage the change in an in-memory bundle. Do not write to the tenant yet. -7. Ask **"anything else?"**; loop to step 2 if yes. +7. In an interactive session, ask **"anything else?"** and loop to step 2 if yes. If the request is fully handled, finish and report instead of asking. 8. Show the consolidated diff of all staged changes vs current tenant state. 9. Apply as a batch; see **Apply** below. @@ -1347,13 +1364,14 @@ Map freeform phrasing to the underlying surface + field. This is a starting tabl |---|---| | "logo" | `widget.logo_url` (theme) and `logo_url` (tenant branding). If both are set, ask which; if only one, update that one. Offer to set both if only one is set today | | "favicon" | `favicon_url` (tenant branding) | -| "primary color" / "brand color" | Ask: theme primary button fill, tenant `colors.primary` (used on Classic pages), or both? Default to updating both if the user says "everywhere" | -| "button color" | Disambiguate fill vs label/text. If the user means a specific button (secondary, tertiary), map to the matching theme field | +| "primary color" / "brand color" | Ask: theme primary button fill, tenant `colors.primary` (used on Classic pages), or both? Default to updating both if the user says "everywhere". Do not ask when the tenant has a theme and the request names the login button: that is the theme's `colors.primary_button` | +| "button color" | Fill vs label/text: the fill (`colors.primary_button`) unless the user says text or label; do not ask for a plain "button color" request. If the user means a specific button (secondary, tertiary), map to the matching theme field | | "page background" / "background color" | `colors.page_background` (solid) or `page_background.background_image_url` (image). Ask if ambiguous | | "widget background" / "card background" | `colors.widget_background` | | "text color" / "body text" | `colors.body_text`; disambiguate from widget title / input label if needed | | "corner radius" / "rounded corners" / "sharper corners" | Ask which element: buttons (`borders.button_border_radius`), inputs (`borders.input_border_radius`), widget (`borders.widget_corner_radius`). If the user says "everywhere", update all three | | "font" | `fonts.font_url` + `fonts.reference_text_size` family. Resolve the family name to a Google Fonts URL if possible (see per-surface mechanics) | +| "identifier first" / "ask for email first, password next" | Tenant setting, not custom text: `auth0 api patch prompts --data '{"identifier_first":true}'` (see the identifier-first note under Login) | | "headline" / "title on the [login/signup/reset/...] screen" | Custom text: `{prompt}.title` on the specified screen. Confirm the prompt + screen + language | | "description" / "subtitle on [screen]" | Custom text: `{prompt}.description` | | "button label on [screen]" | Custom text: `{prompt}.buttonText` (or the screen-specific label key) | @@ -1399,9 +1417,9 @@ After the user finishes staging changes, batch the writes by surface: 1. All theme field changes → one `GET /branding/themes/default` + one `PATCH /branding/themes/{themeId}` with the merged full object. 2. All tenant-level branding setting changes → one `PATCH /api/v2/branding` with the merged body. 3. Page template change (if any) → one `PUT /api/v2/branding/templates/universal-login` after verifying `auth0:head` and `auth0:widget` are present. -4. Per-screen text changes → one `PUT /api/v2/prompts/{prompt}/custom-text/{lang}` per affected prompt/language (GET-merge-PUT; do not overwrite other screens in that prompt). +4. Per-screen text changes → one `auth0 ul prompts update -l --data '...'` per affected prompt and language (read, merge, then write; do not overwrite other screens in that prompt). -Before writing, show the consolidated diff **and the target tenant name** (per the "CLI Tenant Context" prerequisite in SKILL.md). Require explicit confirmation for the whole batch. Auth0 does not retain prior versions, so there is no automatic rollback; suggest the user export current state locally first if they want a backup. +Before writing, show the consolidated diff **and the target tenant name** (per the "CLI Tenant Context" prerequisite above). Confirm the whole batch when the changes are ambiguous or destructive; when the request gave exact values for each change, state the batch and apply it. Auth0 does not retain prior versions, so there is no automatic rollback; suggest the user export current state locally first if they want a backup. After the batch completes, run the "Verify in browser (post-apply)" step from SKILL.md. @@ -1472,7 +1490,7 @@ Reset is destructive and one-way. Auth0 does not maintain prior versions of them ## Confirm -Show the concrete plan, including the target tenant (per the "CLI Tenant Context" prerequisite in SKILL.md): +Show the concrete plan, including the target tenant (per the "CLI Tenant Context" prerequisite above): ```text Target tenant: acme-prod (active in the Auth0 CLI) @@ -1676,13 +1694,13 @@ Show each locale's proposed text so the user can spot-check and edit any transla ### Step 4: Apply -Before writing, show the target tenant name and the prompt/locale pairs about to be updated, and get explicit confirmation (per the "CLI Tenant Context" prerequisite in SKILL.md). +Before writing, show the target tenant name and the prompt/locale pairs about to be updated, and get explicit confirmation (per the "CLI Tenant Context" prerequisite above). -Batch by prompt: one `PUT /api/v2/prompts/{prompt}/custom-text/{lang}` per prompt-locale pair, with approved new keys merged across all screens under that prompt and any existing overrides preserved. +Batch by prompt: one `auth0 ul prompts update -l --data '...'` per prompt-locale pair, with approved new keys merged across all screens under that prompt and any existing overrides preserved. Before writing, strip any key whose approved value is identical to the Auth0 default for that key. Comparison is an **exact byte-for-byte string match** after trimming trailing whitespace/newlines — no case folding, no HTML-entity decoding, no whitespace collapsing inside the string. If the approved value differs only in a trailing newline or leading/trailing spaces, treat it as identical and strip it. Any other difference (casing, punctuation, HTML entities, internal whitespace) is a genuine override and must be written. Only include keys that are genuinely different from the default — sending a default value creates a stored override that has no effect but adds noise and makes future resets less clean. -Never PUT without merging; PUT replaces the full object for that prompt/lang. The custom-text API is per-prompt, not per-screen, so screens under the same prompt share one PUT call. +Never write without merging; the update replaces the full object for that prompt/lang. The custom-text API is per-prompt, not per-screen, so screens under the same prompt share one `auth0 ul prompts update` call. **Rate limits.** A multi-prompt, multi-locale rewrite can produce 20+ PUTs in quick succession. The Management API's default per-tenant write budget is a few hundred requests per minute, but concurrent writes are the real risk: run PUTs **sequentially**, not in parallel. If the API returns **429 Too Many Requests**, back off and retry the failed PUT only — don't re-run the batch. Use exponential backoff: wait 5s, 10s, 20s, 30s, 60s; stop after five attempts and surface the failed prompt/locale pair to the user. Honor the `Retry-After` response header if present (seconds to wait before the next attempt). Successful PUTs don't need to be retried; the per-prompt design means each PUT is independent. diff --git a/main/.mintlify/skills/auth0/references/feature-custom-domains/index.md b/main/.mintlify/skills/auth0/references/feature-custom-domains/index.md index d1ddeab6a0..393a5c8318 100644 --- a/main/.mintlify/skills/auth0/references/feature-custom-domains/index.md +++ b/main/.mintlify/skills/auth0/references/feature-custom-domains/index.md @@ -201,11 +201,11 @@ auth0 domains update # Delete a custom domain (use --force to skip the CLI's interactive prompt) auth0 domains delete --force -# Set the default custom domain (no dedicated CLI subcommand; use API passthrough) -auth0 api patch "custom-domains/default" --data '{"domain": ""}' +# Set the default custom domain +auth0 domains default set # Get the current default -auth0 api get "custom-domains/default" +auth0 domains default show ``` ### CLI vs API value conventions @@ -217,7 +217,7 @@ The dedicated `auth0 domains` subcommands and the `auth0 api` passthrough use di | Certificate type (Auth0-managed) | `--type auth0` | `"type": "auth0_managed_certs"` | | Certificate type (self-managed) | `--type self` | `"type": "self_managed_certs"` | | Relying party identifier | **not supported on the CLI** (no `--rpid` flag); use API passthrough | `"relying_party_identifier"` | -| Default domain | **not supported on the CLI** (no `default` subcommand); use API passthrough | `PATCH /custom-domains/default` with `{"domain": "..."}` | +| Default domain | `auth0 domains default set ` (read: `auth0 domains default show`) | `PATCH /custom-domains/default` with `{"domain": "..."}` | ## Domain Object Properties @@ -379,18 +379,16 @@ The skill's primary flow creates one domain. To add another, invoke the skill ag When multiple domains are configured, one is designated the **default**. The default is used when a Management API call that triggers a notification (password reset email, verification email, etc.) is made **without** an `auth0-custom-domain` header. -Set the default. Two endpoints exist; **prefer `PATCH /custom-domains/default`** — it accepts the human-readable domain name and is the endpoint the skill uses in the Manage capability. The `tenants/settings` form is the older path, still supported, and handy when you already have the `custom_domain_id` (e.g., from a list response). Both are idempotent and produce the same result; pick whichever keeps the surrounding code simpler. +Set the default. Two paths exist; **prefer the native CLI subcommand** — it accepts the domain name directly. The `tenants/settings` API form is the older path, still supported, and handy when you already have the `custom_domain_id` and prefer scripting against the raw API. Both are idempotent and produce the same result; pick whichever keeps the surrounding code simpler. ```bash -# Preferred: PATCH /custom-domains/default (pass domain name, not ID): -auth0 api patch "custom-domains/default" --data '{"domain": "login.example.com"}' +# Preferred: native CLI subcommand (pass the domain name): +auth0 domains default set -# Alternative: tenant settings endpoint (pass the custom_domain_id): +# Alternative: tenant settings endpoint via API passthrough (pass the custom_domain_id): auth0 api patch "tenants/settings" --data '{"default_custom_domain_id": "cd_abc123"}' ``` -The Auth0 CLI does not have a dedicated `auth0 domains default` subcommand; the API passthrough is the only way. - ### The `auth0-custom-domain` header For any Management API endpoint that triggers user-facing notifications, include the header to route through a specific custom domain: @@ -483,7 +481,7 @@ Fresh records can take 5-60 minutes to propagate across resolvers. If `dig +shor If the record is correct in DNS but Auth0 still reports `pending_verification`: 1. Do not delete and recreate the domain. This can cause a service interruption. 2. Wait at least 4 hours. -3. Retry verification with `auth0 api post "custom-domains//verify"`. +3. Retry verification with `auth0 domains verify `. ### When to open a support ticket @@ -1116,7 +1114,7 @@ Ask questions one at a time as plain conversational text. Do not present all inp Minimal create (Auth0-managed certs, defaults everywhere): ```bash -auth0 api post "custom-domains" --data '{ +auth0 domains create --data '{ "domain": "login.example.com", "type": "auth0_managed_certs" }' @@ -1125,7 +1123,7 @@ auth0 api post "custom-domains" --data '{ Full-featured create with optional fields (omit any that don't apply): ```bash -auth0 api post "custom-domains" --data '{ +auth0 domains create --data '{ "domain": "login.example.com", "type": "auth0_managed_certs", "verification_method": "txt", @@ -1152,7 +1150,7 @@ The response contains `custom_domain_id`, `status: "pending_verification"`, and **If the API returns 403**: the tenant is a Free tenant without a credit card on file. Direct the user to **Dashboard → Tenant Settings → Billing** (or the Teams section for Teams-managed tenants) to add a card, then retry. The card is not charged. This is the correct diagnosis on Free tier; do not suggest a plan upgrade. -**If the API returns 409**: the domain already exists on this or another tenant. `auth0 api get "custom-domains"` to list existing. If it's already on this tenant and just needs verification, skip to the verify step below with the existing `custom_domain_id`. +**If the API returns 409**: the domain already exists on this or another tenant. `auth0 domains list` to list existing. If it's already on this tenant and just needs verification, skip to the verify step below with the existing `custom_domain_id`. See the Examples section below for curl, node-auth0, and auth0-python code patterns. @@ -1191,7 +1189,7 @@ Execute the tier-specific flow from the sub-file you opened above. For Tiers 2 a ## Trigger Auth0 verification ```bash -auth0 api post "custom-domains//verify" +auth0 domains verify ``` ## Poll until ready @@ -1258,7 +1256,7 @@ Surface the active tenant to the user and require explicit confirmation ("the ac After tenant confirmation, fetch the current custom domain list once. Cache it for the session so disambiguation prompts can show current values. ```bash -auth0 api get "custom-domains" +auth0 domains list ``` Also fetch tenant settings for the current default: @@ -1305,11 +1303,9 @@ The API **rejects** `type`, `domain`, `verification_method`. To change any of th ## Set or change the default ```bash -auth0 api patch "custom-domains/default" --data '{"domain": "login.example.com"}' +auth0 domains default set ``` -The Auth0 CLI does not have a dedicated `auth0 domains default` subcommand; use the API passthrough above. - Effects to explain to the user: - Notification-triggering Management API calls (password reset tickets, verification emails) will route through this domain when no `auth0-custom-domain` header is sent. - Email template links will use this domain by default. @@ -1331,7 +1327,7 @@ The RPID must be a registrable suffix of the custom domain (you can't set `googl ### Execute the PATCH ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "relying_party_identifier": "example.com" }' ``` @@ -1348,7 +1344,7 @@ Before sending, show the diff: `current rpId: {value or "(default: domain hostna To revert to the default (RPID = custom domain hostname), PATCH with `null`: ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "relying_party_identifier": null }' ``` @@ -1358,7 +1354,7 @@ auth0 api patch "custom-domains/" --data '{ `tls_policy` governs the TLS posture for Auth0-managed certificate domains. Default and recommended value is `"recommended"`. Only set explicitly when a compliance mandate requires a specific policy. ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "tls_policy": "recommended" }' ``` @@ -1381,7 +1377,7 @@ Pick the value that matches what the proxy in front of Auth0 emits. Only one val ### Execute the PATCH ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "custom_client_ip_header": "cf-connecting-ip" }' ``` @@ -1389,7 +1385,7 @@ auth0 api patch "custom-domains/" --data '{ To clear, PATCH with `null`: ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "custom_client_ip_header": null }' ``` @@ -1420,7 +1416,7 @@ Set the tag once on the domain; every authentication that hits that domain surfa Metadata is returned as `domain_metadata` on the domain object. Load once at the start of the Manage existing domains flow (see top of this file); no extra call needed. ```bash -auth0 api get "custom-domains/" +auth0 domains show ``` ### Add or update metadata (canonical pattern: GET → merge → PATCH) @@ -1432,7 +1428,7 @@ Always read current metadata, merge the user's changes into it locally, and PATC 3. PATCH the full merged object. ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "domain_metadata": { "region": "us-east", "brand": "acme" @@ -1449,7 +1445,7 @@ Omit the key from the merged object and PATCH the full result. Don't rely on `nu ```bash # Current: { "region": "us-east", "brand": "acme" } # User wants to drop "brand": -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "domain_metadata": { "region": "us-east" } @@ -1459,7 +1455,7 @@ auth0 api patch "custom-domains/" --data '{ To clear all metadata, PATCH with an empty object: ```bash -auth0 api patch "custom-domains/" --data '{ +auth0 domains update --data '{ "domain_metadata": {} }' ``` @@ -1534,7 +1530,7 @@ Surface the active tenant to the user and confirm it's the one they want checked ### 1. List custom domains on the tenant ```bash -auth0 api get "custom-domains" +auth0 domains list ``` Pull for each: `domain`, `custom_domain_id`, `status`, `type`, `primary`. @@ -1684,7 +1680,7 @@ A custom domain that's stuck in `pending_verification`, or verification that kee ## Inputs -- The `custom_domain_id` or the domain name (look up the ID via `auth0 api get "custom-domains"` if only the name is known). +- The `custom_domain_id` or the domain name (look up the ID via `auth0 domains list` if only the name is known). - Confirmation that the user has already gone through the Set up a custom domain flow at some point (if not, route them to the Set up a custom domain flow first). ## Pre-flight: surface the active tenant @@ -1700,7 +1696,7 @@ Surface the active tenant and ask the user to confirm it is the one hosting the ## Get the current state from Auth0 ```bash -auth0 api get "custom-domains/" +auth0 domains show ``` From the response, pull: @@ -1776,13 +1772,13 @@ Look for a `PrivateZone: true` entry. If that's the zone the record went into, t After applying a fix, trigger verification: ```bash -auth0 api post "custom-domains//verify" +auth0 domains verify ``` Then poll for up to ~5 minutes: ```bash -auth0 api get "custom-domains/" +auth0 domains show ``` ## What not to do @@ -1843,7 +1839,7 @@ The user can proceed anyway, but they should plan to set a new default right aft ### 2. Is this the only custom domain? ```bash -auth0 api get "custom-domains" +auth0 domains list ``` If the list has only this one domain, warn: @@ -1992,7 +1988,7 @@ If the scan found references, pause here and let the user decide whether to fix ## Delete in Auth0 ```bash -auth0 api delete "custom-domains/" --force +auth0 domains delete --force ``` `--force` is important: without it the CLI prints its own confirmation prompt, which duplicates the skill's confirmation and hangs in non-interactive contexts. The skill has already obtained explicit yes from the user, so pass `--force`. diff --git a/main/.mintlify/skills/auth0/references/feature-custom-token-exchange/index.md b/main/.mintlify/skills/auth0/references/feature-custom-token-exchange/index.md index 6bce14f59e..1d1a1e32ad 100644 --- a/main/.mintlify/skills/auth0/references/feature-custom-token-exchange/index.md +++ b/main/.mintlify/skills/auth0/references/feature-custom-token-exchange/index.md @@ -166,9 +166,10 @@ The tenant setup (steps 1–3) is the deliverable; step 4 only confirms it works always runnable in a given environment. Notes: -- `auth0 apps update` has **no** `--is-first-party` or `--oidc-conformant` flag. Apps created in your - own tenant are already first-party; if you must set either on an existing client, patch it: - `auth0 api patch "clients/" --data '{"is_first_party":true,"oidc_conformant":true}'`. +- `auth0 apps update` has an `--is-first-party` flag, but **no** `--oidc-conformant` flag. Apps created in + your own tenant are already first-party; set it explicitly with `auth0 apps update --is-first-party=true`. + `oidc_conformant` has no dedicated flag — set it via the JSON passthrough: + `auth0 apps update --data '{"oidc_conformant":true}'`. - `--type` only accepts `custom_authentication` (CTE). `on_behalf_of_token_exchange` is a different (OBO) profile type and is out of scope here. - `subject_token_type`: 8–100 chars, a valid URI, no reserved prefix, unique per tenant (409 on duplicate). @@ -177,7 +178,7 @@ Notes: Management API. If a *separate* requirement needs them: "Allow Skip User Consent" is a per-API setting on a *custom* API (`auth0 api patch "resource-servers/"`) — the Management API instead relies on the client's first-party status — and authorizing an M2M app for the - Management API uses `auth0 api post "client-grants"`. + Management API uses `auth0 client-grants create`. Verify subcommands and flag names with `auth0 token-exchange --help` and `auth0 actions --help` rather than inferring them; use `auth0 api` for Management API calls without a dedicated diff --git a/main/.mintlify/skills/auth0/references/feature-dpop/index.md b/main/.mintlify/skills/auth0/references/feature-dpop/index.md index 52925eb240..5b289f3e1f 100644 --- a/main/.mintlify/skills/auth0/references/feature-dpop/index.md +++ b/main/.mintlify/skills/auth0/references/feature-dpop/index.md @@ -60,10 +60,10 @@ key — a stolen token alone cannot be replayed by an attacker. ```bash # Inspect current resource server settings -auth0 api get "resource-servers" | jq '.[] | select(.identifier == "https://your-api-identifier")' +auth0 apis list | jq '.[] | select(.identifier == "https://your-api-identifier")' # Enable DPoP token dialect on the API -auth0 api patch "resource-servers/{API_ID}" \ +auth0 apis update {API_ID} \ --data '{"token_dialect": "access_token_authz"}' ``` @@ -75,7 +75,7 @@ Sender-constraining is set on the resource server (via a `proof_of_possession` setting with `mechanism: "dpop"`) and, for a mandatory client, on the client. There is no tenant-wide DPoP toggle. The loaded tooling reference has the exact syntax: -- CLI: `auth0 api patch resource-servers/{API_ID}` with the `proof_of_possession` payload +- CLI: `auth0 apis update {API_ID}` with the `proof_of_possession` payload - Terraform: `auth0_resource_server` `proof_of_possession` block + `auth0_client` `require_proof_of_possession` - MCP: `auth0_update_resource_server` accepts `proof_of_possession`; the client-side toggle is **not** exposed by MCP — set it via CLI or Terraform. diff --git a/main/.mintlify/skills/auth0/references/feature-mfa/index.md b/main/.mintlify/skills/auth0/references/feature-mfa/index.md index adb0986cf1..414a1ac462 100644 --- a/main/.mintlify/skills/auth0/references/feature-mfa/index.md +++ b/main/.mintlify/skills/auth0/references/feature-mfa/index.md @@ -220,21 +220,21 @@ The CLI anchor for the tenant-wide path (enable factors, then enforce the policy ```bash # TOTP / Authenticator app -auth0 api put "guardian/factors/otp" --data '{"enabled": true}' +auth0 guardian factors set otp --enabled -# SMS — three steps required -auth0 api put "guardian/factors/sms" --data '{"enabled": true}' -auth0 api put "guardian/factors/phone/message-types" --data '{"message_types": ["sms"]}' -auth0 api put "guardian/factors/phone/selected-provider" --data '{"provider": "auth0"}' +# SMS — three separate commands required +auth0 guardian factors set sms --enabled +auth0 guardian factors phone set-message-types --message-type sms +auth0 guardian factors phone set-provider --provider auth0 # legacy phone config only; unified-phone tenants set the provider in Dashboard > Branding > Phone Provider # Email -auth0 api put "guardian/factors/email" --data '{"enabled": true}' +auth0 guardian factors set email --enabled -# Enforce MFA for all applications (PUT replaces the whole list; wrong verb returns 404) -auth0 api put "guardian/policies" --data '["all-applications"]' +# Enforce MFA for all applications +auth0 guardian policies set --policy all-applications -# Verify with the list endpoint only — do not GET individual factors, they return 404 -auth0 api get "guardian/factors" +# Verify +auth0 guardian factors list ``` The full factor set, the `confidence-score` (adaptive) policy, the Terraform @@ -286,8 +286,8 @@ which uses the `mfa_token` and the MFA API surface instead: | Ignoring `mfa_required` from a silent token call | The step-up silently fails and the action proceeds unverified | Catch it and re-authenticate interactively | | Preferring SMS by default | SMS is vulnerable to SIM-swap | Prefer TOTP or WebAuthn; treat SMS as a fallback | | No recovery codes enabled | Users get locked out when they lose a device | Enable recovery codes during enrollment | -| Wrong HTTP verb on `guardian/policies` | Returns a misleading 404 | Use `PUT` with a bare JSON array | -| Sending `message_type` or `provider` to `guardian/factors/sms` directly | Returns a 400 — those fields are not accepted on that endpoint | Use `PUT guardian/factors/phone/message-types` for the message type and `PUT guardian/factors/phone/selected-provider` for the provider | +| Wrong HTTP verb on `guardian/policies` | Returns a misleading 404 | Use `auth0 guardian policies set --policy all-applications` | +| Sending `message_type` or `provider` to `guardian/factors/sms` directly | Returns a 400 — those fields are not accepted on that endpoint | Use `auth0 guardian factors phone set-message-types --message-type sms` for the message type and `auth0 guardian factors phone set-provider --provider auth0` for the provider (legacy phone config only — on the unified phone experience, set the provider in Dashboard > Branding > Phone Provider) | | Using the Management API to list or remove a user's own factors during the sign-in flow | Forces the app to hold Management API admin scopes and ignores the `mfa_token` the flow already issued | List and challenge through the SDK's MFA client on the `mfa_token`; remove with a post-MFA `remove:authenticators` access token (mfa audience); reserve the Management API for admin / out-of-band | | Assuming an already-enrolled factor needs no challenge and jumping straight to verify | Diverges from the SDK's documented enrolled-factor flow and breaks for out-of-band factors (SMS/push), whose challenge is what delivers the code | Challenge the enrolled authenticator, then verify | diff --git a/main/.mintlify/skills/auth0/references/feature-migration/index.md b/main/.mintlify/skills/auth0/references/feature-migration/index.md index d353cb56ee..24dae71aa7 100644 --- a/main/.mintlify/skills/auth0/references/feature-migration/index.md +++ b/main/.mintlify/skills/auth0/references/feature-migration/index.md @@ -73,10 +73,10 @@ Import users via Dashboard, CLI, or Management API. **Quick start:** ```bash -# Via Auth0 CLI -auth0 api post "jobs/users-imports" \ - --data "connection_id=con_ABC123" \ - --data "users=@users.json" +# Via Auth0 CLI (handles multipart upload; pipe the file so large imports don't hit the argument size limit) +cat users.json | auth0 users import \ + --connection-name "Username-Password-Authentication" \ + --upsert ``` **For detailed instructions, see the sections below:** @@ -1285,13 +1285,13 @@ auth0 login **Import users:** ```bash -# Get connection ID -auth0 api get connections +# Get connection name +auth0 connections list -# Import users -auth0 api post "jobs/users-imports" \ - --data "connection_id=con_ABC123" \ - --data "users=@users.json" +# Import users (--connection-name takes the connection name, not the ID) +cat users.json | auth0 users import \ + --connection-name "Username-Password-Authentication" \ + --upsert ``` **Check import status:** @@ -1477,11 +1477,9 @@ curl "https://YOUR_DOMAIN.auth0.com/api/v2/jobs/{job-id}/errors" \ # Split into 5000-user chunks split -l 5000 users.json users-chunk- -# Import each chunk +# Import each chunk (each file must be a valid JSON array of users) for file in users-chunk-*; do - auth0 api post "jobs/users-imports" \ - --data "connection_id=con_ABC123" \ - --data "users=@$file" + cat "$file" | auth0 users import --connection-name "Username-Password-Authentication" --upsert done ``` diff --git a/main/.mintlify/skills/auth0/references/feature-organizations/index.md b/main/.mintlify/skills/auth0/references/feature-organizations/index.md index 56b717fe8c..ca11feb7f7 100644 --- a/main/.mintlify/skills/auth0/references/feature-organizations/index.md +++ b/main/.mintlify/skills/auth0/references/feature-organizations/index.md @@ -148,7 +148,7 @@ Reading connections back returns a **bare array**, so use `jq '.[]'`, not Two settings control whether and how an app uses organization login. They live on the **application (client)**, not on the organization, and are set with -`auth0 api patch "clients/"`: +`auth0 apps update --organization-usage ... --organization-require-behavior ...`: | Field | Values | Meaning | |---|---|---| @@ -163,42 +163,45 @@ the only option: - Accept invitations, but org is otherwise optional -> `organization_usage: allow` with `organization_require_behavior: no_prompt` ```bash -# Org-only login with an up-front org selector - set both fields in one PATCH. -auth0 api patch "clients/" \ - --data '{"organization_usage":"require","organization_require_behavior":"pre_login_prompt"}' +# Org-only login with an up-front org selector - set both fields in one call. +auth0 apps update \ + --organization-usage require --organization-require-behavior pre_login_prompt ``` +`auth0 apps update` and `auth0 apps show ` leave `client_secret` out of their output +unless you pass `--reveal-secrets`, so the secret stays out of your context. + ### Finding or creating a login connection Reuse an existing database connection when the tenant has one; create one only if it does not: ```bash -# List database connections in the tenant and pick one explicitly by name - -# the API defines no ordering, so `.[0]` silently grabs an arbitrary connection. -auth0 api get "connections?strategy=auth0" | jq -r '.[] | select(.name=="") | .id' +# Look up a database connection by name. Filtering on `name` returns the exact match - +# the API defines no ordering, so `.[0]` on an unfiltered list grabs an arbitrary connection. +auth0 connections list --query '{"strategy":["auth0"],"name":""}' --json | jq -r '.[].id' # Create one only if there is none matching. `name` must match # ^[a-zA-Z0-9](-[a-zA-Z0-9]|[a-zA-Z0-9])*$, max 128 chars. -auth0 api post connections --data '{"name":"","strategy":"auth0"}' +auth0 connections create --data '{"name":"","strategy":"auth0"}' # Enable it for the organization - without this, org members have no way to log in. auth0 api post "organizations//enabled_connections" \ --data '{"connection_id":"","assign_membership_on_login":true}' # Check which apps already have this connection enabled. -auth0 api get "connections//clients" | jq -r '.clients[].client_id' +auth0 connections enabled-clients show --json | jq -r '.[].client_id' # ONLY if the app is not already listed above: enable the connection for it. # This is a separate setting from org login (see note below), so skip it on a # connection the tenant already had enabled for the app. status false disables; max 50 per call. -auth0 api patch "connections//clients" \ +# This is a PATCH: it changes only the clients in the payload and keeps every other +# client's status, so a single entry does not replace the existing list. +auth0 connections enabled-clients update \ --data '[{"client_id":"","status":true}]' ``` -Both connection reads are checkpoint-paginated (`take` defaults to 50): omit `from` on the -first call, then while the response carries a `next` value pass it as `from` until it is -absent. The lookup above only inspects the first page, so page through all results before -concluding a connection is absent, and fail unless exactly one matches rather than guessing. +`enabled-clients show` returns every enabled client, across pages. Fail unless exactly one +connection matches the name rather than guessing. A connection added to the organization's `enabled_connections` is what appears at that org's login prompt and lets members authenticate. Enabling the connection for a client @@ -220,13 +223,13 @@ a link, authenticates, and becomes a member. # 1. Without this: "The specified client_id (...) does not allow organizations." # allow/no_prompt is the minimum for invitations; for org-only login use # require/pre_login_prompt instead (see "Application (client) organization settings"). -auth0 api patch "clients/" \ - --data '{"organization_usage":"allow","organization_require_behavior":"no_prompt"}' +auth0 apps update \ + --organization-usage allow --organization-require-behavior no_prompt # 2. Without this: "A default login route is required to generate the invitation url." # Read the current value FIRST - the setting is tenant-wide, and you may need # to restore it. An empty response means it's currently unset. -auth0 api get "tenants/settings" | jq -r '.default_redirection_uri // ""' +auth0 tenant-settings show --json | jq -r '.default_redirection_uri // ""' auth0 api patch "tenants/settings" \ --data '{"default_redirection_uri":"https://app.example.com/callback"}' @@ -295,8 +298,9 @@ Your app must read **both** params from the URL and forward **both** to the `/au | Granting global roles instead of org-level roles | Use the org member roles endpoint, not the user roles endpoint | | Not enabling a connection for the org | `auth0 api post "organizations//enabled_connections"`, or Dashboard → Organization → Connections | | A space or underscore in a new connection's `name` | Alphanumerics and hyphens only, starting and ending alphanumeric. Anything else is a 400 | -| Creating a connection and enabling it for no app | Nothing can use it. `auth0 api patch "connections//clients" --data '[{"client_id":"","status":true}]'` | -| Reading or writing `enabled_clients` on the connection object | "NOT RECOMMENDED" on write, deprecated on read. Use `GET`/`PATCH connections//clients` | +| Creating a connection and enabling it for no app | Nothing can use it. `auth0 connections enabled-clients update --data '[{"client_id":"","status":true}]'` | +| Reading or writing `enabled_clients` on the connection object | "NOT RECOMMENDED" on write, deprecated on read. Read with `auth0 connections enabled-clients show ` and write with `auth0 connections enabled-clients update `, which sends a PATCH to `connections//clients` | +| Reading or setting a client field with `auth0 api` | Use `auth0 apps show ` or `auth0 apps update `, which leave `client_secret` out unless you pass `--reveal-secrets`. For a raw call, pipe through `jq` to keep only the fields you need | | Overwriting `default_redirection_uri` without reading it first | It is tenant-wide. Capture the old value, and restore or disclose it | | Guessing a `auth0 orgs` subcommand for membership, roles, or connections | Verify with `auth0 commands orgs --detailed`, and use `auth0 api post organizations/...` for whatever has no dedicated subcommand | | Prefixing `auth0 api` paths with `/api/v2/` | Paths are relative to the API root. `/api/v2/organizations/...` returns 404 | diff --git a/main/.mintlify/skills/auth0/references/feature-passkeys/index.md b/main/.mintlify/skills/auth0/references/feature-passkeys/index.md index 0dd7cc184b..5a0919da0e 100644 --- a/main/.mintlify/skills/auth0/references/feature-passkeys/index.md +++ b/main/.mintlify/skills/auth0/references/feature-passkeys/index.md @@ -144,7 +144,7 @@ A passkey login can still hit MFA if the tenant/connection requires a second fac | `auth0-server-python` | 1.0.0b13 | signup, login | `references/feature-passkeys/auth0-server-python.md` | | `Auth0.swift` (iOS/macOS/visionOS) | 2.12.0 · 2.13.0 (enrollment) | signup, login, enrollment | `references/feature-passkeys/auth0-swift.md` | | `Auth0.Android` | 3.2.0 | signup, login | `references/feature-passkeys/auth0-android.md` | -| `react-native-auth0` | 5.7.0 | signup, login, enrollment | `references/feature-passkeys/react-native-auth0.md` | +| `react-native-auth0` | 5.7.0 (native) · 5.11.0 (web) | signup, login, enrollment | `references/feature-passkeys/react-native-auth0.md` | ## Common mistakes @@ -157,6 +157,7 @@ A passkey login can still hit MFA if the tenant/connection requires a second fac | Treating a passkey as a second factor | Passkeys here are the primary credential; the MFA reference covers the second-factor case | For step-up, use `feature-mfa`; for passwordless primary login, use this reference | | Reusing a signup challenge for login (or vice-versa) | Registration and assertion are different ceremonies | Use the signup challenge with `create()` and the login challenge with `get()` | | Returning the token-exchange result (raw tokens / server-side session state) in the HTTP response, or logging it | Leaks Auth0 access / ID / refresh tokens to the client | Let the SDK persist the session in its state store; respond with success/redirect only and read claims server-side | +| Swapping in `@auth0/auth0-react` / `@auth0/auth0-spa-js` (or hand-rolled `/me/v1` fetches) for the **web build of a React Native app** | A different session/token model from react-native-auth0; splits the flow across two SDKs | Keep react-native-auth0 (`5.11.0`+ for web) on every platform; branch only the WebAuthn ceremony (`navigator.credentials` on web). See `react-native-auth0.md` → "react-native-web — one SDK, branch only the ceremony" | ## References diff --git a/main/.mintlify/skills/auth0/references/feature-passkeys/react-native-auth0.md b/main/.mintlify/skills/auth0/references/feature-passkeys/react-native-auth0.md index 956cfe82c7..8e22075c6c 100644 --- a/main/.mintlify/skills/auth0/references/feature-passkeys/react-native-auth0.md +++ b/main/.mintlify/skills/auth0/references/feature-passkeys/react-native-auth0.md @@ -1,10 +1,10 @@ # react-native-auth0 — Passkeys -**Minimum version:** `5.7.0` (the passkey methods on the `useAuth0()` hook / `Auth0` client). Requires **iOS 16.6+**, **Android API 28+**, or a WebAuthn-capable browser; native platforms need Associated Domains (iOS) / Digital Asset Links (Android) on the custom domain. +**Minimum version:** `5.7.0` on **iOS/Android** (the passkey methods on the `useAuth0()` hook / `Auth0` client, plus My Account enrollment); `5.11.0` on **web** (react-native-web) — passkeys and the My Account API were added for the web platform in 5.11.0. Requires **iOS 16.6+**, **Android API 28+**, or a WebAuthn-capable browser; native platforms need Associated Domains (iOS) / Digital Asset Links (Android) on the custom domain. Framework-specific surface only. The shared 3-step mechanic, the tenant configuration (custom domain + passkey grant + connection auth method), the feature-level protocol symbols, and the MFA-interplay error semantics live in `feature-passkeys/index.md` — do not restate them here. -react-native-auth0 is **low-level for the challenge**: it returns the challenge, the native module runs the WebAuthn ceremony, and `getTokenByPasskey()` exchanges the credential for `Credentials`. It also exposes passkey **enrollment** via the My Account API. +react-native-auth0 is **low-level for the challenge**: it returns the challenge and `getTokenByPasskey()` exchanges the credential for `Credentials`, but **it does not run the WebAuthn ceremony itself** — you run that step with a passkey library you add yourself (native: e.g. `react-native-passkey` or a native module; web: the browser's `navigator.credentials`). See "Ceremony library + native platform setup" below. It also exposes passkey **enrollment** via the My Account API. ## Signup / Login @@ -24,7 +24,7 @@ const loginChallenge = await passkeyLoginChallenge({ // realm, organization optional }); -// --- native module runs the WebAuthn ceremony with authParamsPublicKey --- +// --- your passkey library runs the WebAuthn ceremony with authParamsPublicKey (the SDK does NOT) --- // Token exchange → Credentials const credentials = await getTokenByPasskey({ @@ -40,6 +40,17 @@ const credentials = await getTokenByPasskey({ The database connection is passed as **`realm`**, not `connection`. (`connection` is only a field on the *enrollment* challenge below — easy to conflate.) +### react-native-web — one SDK, branch only the ceremony + +**Requires react-native-auth0 `5.11.0`+** — earlier 5.x versions have no web passkey or My Account support, so if the project pins `<5.11.0` and ships a web build, bump the dependency first. + +A React Native app that also ships a web build (react-native-web) uses the **same react-native-auth0 surface on every platform** — `passkeySignupChallenge`, `passkeyLoginChallenge`, `getTokenByPasskey`, and `myAccount.passkeyEnrollmentChallenge` / `enrollPasskey`. Only the WebAuthn **ceremony** differs per platform, and you branch *just that step* (via `Platform.OS` or a `.web.ts` / `.native.ts` split): + +- **native** → your passkey library / native module produces the `authResponse` string. +- **web** → the browser's `navigator.credentials.create()` / `.get()` produces a `PublicKeyCredential`. + +**Do NOT swap in `@auth0/auth0-react` or `@auth0/auth0-spa-js` for the web build**, and do NOT hand-roll `fetch` calls to `/me/v1/authentication-methods`. The browser SDKs are a different session/token model; the challenge and token-exchange calls stay on react-native-auth0 on all platforms — only the ceremony is platform-specific. + ## Enrollment (add a passkey — My Account API) Requires an access token with `create:me:authentication_methods`, minted for the `https://{yourDomain}/me/` audience via `getApiCredentials(...)` (fetching a token for that different audience from the session refresh token is the MRRT mechanism — see the hub's Enrollment section): @@ -53,7 +64,7 @@ const challenge = await myAccount.passkeyEnrollmentChallenge({ // userIdentity?, connection? optional }); -// 2. Native module runs the WebAuthn registration ceremony +// 2. Your passkey library runs the WebAuthn registration ceremony (the SDK does NOT) // 3. Verify → PasskeyAuthenticationMethod const method = await myAccount.enrollPasskey({ @@ -67,6 +78,21 @@ const method = await myAccount.enrollPasskey({ - `myAccount.passkeyEnrollmentChallenge({ accessToken, userIdentity?, connection? })` → `Promise`. `accessToken` is **required**. - `myAccount.enrollPasskey({ accessToken, authenticationMethodId, authSession, authResponse, authParamsPublicKey })` → `Promise` — a passkey-specific shape (`id`, `type`, `keyId`, `publicKey`, `userHandle`, `credentialDeviceType`, `aaguid`, `relyingPartyId`, …), **not** the generic `AuthenticationMethod` the other `enroll*` methods return. +- `myAccount` is a **property on `useAuth0()`** whose methods each take `accessToken`. It is **not** a `myAccount({ token })` factory (that is the browser SDKs' `@auth0/auth0-react` / nextjs shape) — don't construct a client; destructure it and pass the `/me/`-audience token into each call as shown. + +## Ceremony library + native platform setup (required) + +The SDK issues the challenge and exchanges the credential, but **does not run the WebAuthn ceremony** — you must add the ceremony step yourself, and the flow will not work without it: + +- **Native:** add a passkey library to `package.json` `dependencies` — e.g. `react-native-passkey` (or a native module calling `ASAuthorizationController` on iOS / `CredentialManager` on Android). It consumes `authParamsPublicKey` and returns the `authResponse` string you pass into `getTokenByPasskey` / `enrollPasskey`. **Declare the dependency** — don't lazily `require()` it without adding it to `package.json`. +- **Web** (react-native-web, `5.11.0`+): no library — call the browser's `navigator.credentials.create()` / `.get()` and pass the resulting `PublicKeyCredential` as `authResponse`. + +Native platforms also need the verified custom domain wired as a relying party. Both bindings are mandatory — the OS silently refuses the ceremony without them: + +- **iOS 16.6+** — Associated Domains entitlement containing `webcredentials:` (e.g. `webcredentials:auth.example.com`), set in the target's `.entitlements` / Signing & Capabilities. +- **Android API 28+** — an `assetlinks.json` served at `https:///.well-known/assetlinks.json` (App Links / Digital Asset Links) listing the app's package name and signing-cert SHA-256 fingerprint. + +If the scaffold's constraints block creating the `.entitlements` or `assetlinks.json` artifact, **state the required capability in a code comment or the README** rather than silently dropping it — the relying-party binding is not optional, and omitting it is the most common reason a correctly-coded flow still fails at runtime. ## Error classes @@ -77,7 +103,7 @@ MFA: on **web**, a step-up surfaces as the typed `PASSKEY_MFA_REQUIRED` — call ## SDK-specific gotchas -- Native platforms need Associated Domains (iOS) / Digital Asset Links (Android) pointed at the verified custom domain. +- The ceremony library and the iOS/Android relying-party binding are both required — see "Ceremony library + native platform setup" above. - Carry the challenge's `authSession` into `getTokenByPasskey`. -- `authParamsPublicKey` is the WebAuthn options the native ceremony consumes (typed `Record`) — pass it through unchanged. +- `authParamsPublicKey` is the WebAuthn options the ceremony consumes (typed `Record`) — pass it through unchanged on both native and web. - Enrollment mints its `/me/`-audience token via `getApiCredentials` off the session refresh token (the MRRT mechanism); without a refresh token that scoped token cannot be obtained. diff --git a/main/.mintlify/skills/auth0/references/framework-android/index.md b/main/.mintlify/skills/auth0/references/framework-android/index.md index cda5c1f84b..b6f695838e 100644 --- a/main/.mintlify/skills/auth0/references/framework-android/index.md +++ b/main/.mintlify/skills/auth0/references/framework-android/index.md @@ -1037,12 +1037,15 @@ if [ -z "$PACKAGE_NAME" ]; then exit 1 fi -# List existing apps and prompt to pick or create +# Fastest path — auto-detects framework, creates the Auth0 app, and writes strings.xml: +# auth0 qs setup --app --framework android --type native +# +# Manual alternative (full control over callback URLs): auth0 apps list read -p "Enter app ID (or press Enter to create a new one): " APP_ID if [ -z "$APP_ID" ]; then - DOMAIN=$(auth0 tenants list --csv --no-input 2>/dev/null | grep '→' | cut -d',' -f2 | tr -d ' ') + DOMAIN=$(auth0 tenants list --json-compact | jq -r '.[] | select(.active) | .name') CALLBACK_URL="${SCHEME}://${DOMAIN}/android/${PACKAGE_NAME}/callback" CLIENT_JSON=$(auth0 apps create \ --name "${PACKAGE_NAME}-android" \ @@ -1050,29 +1053,22 @@ if [ -z "$APP_ID" ]; then --auth-method none \ --callbacks "$CALLBACK_URL" \ --logout-urls "$CALLBACK_URL" \ - --json \ + --json-compact \ --no-input) - CLIENT_ID=$(echo "$CLIENT_JSON" | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + CLIENT_ID=$(echo "$CLIENT_JSON" | jq -r '.client_id') else - CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) - DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) + CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') + DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') CALLBACK_URL="${SCHEME}://${DOMAIN}/android/${PACKAGE_NAME}/callback" fi # Check / create database connection -CONNECTIONS_JSON=$(auth0 api get connections --no-input 2>/dev/null || echo "[]") -CONNECTION_ID=$(echo "$CONNECTIONS_JSON" | python3 -c " -import sys, json -data = json.load(sys.stdin) -for c in data: - if c.get('name') == 'Username-Password-Authentication': - print(c['id']) - break -" 2>/dev/null) +CONNECTIONS_JSON=$(auth0 connections list --json-compact --no-input 2>/dev/null || echo "[]") +CONNECTION_ID=$(echo "$CONNECTIONS_JSON" | jq -r '.[] | select(.name=="Username-Password-Authentication") | .id' 2>/dev/null) if [ -z "$CONNECTION_ID" ]; then - CONNECTION_ID=$(auth0 api post connections \ - --data "{\"strategy\":\"auth0\",\"name\":\"Username-Password-Authentication\"}" \ - --no-input | python3 -c "import sys, json; print(json.load(sys.stdin)['id'])" 2>/dev/null) + CONNECTION_ID=$(auth0 connections create \ + --data '{"strategy":"auth0","name":"Username-Password-Authentication"}' \ + --json-compact --no-input | jq -r '.id' 2>/dev/null) fi if [ -z "$CONNECTION_ID" ]; then echo "Failed to find or create the Username-Password-Authentication connection." >&2 @@ -1081,7 +1077,7 @@ fi # Enable the connection for this app. Only the client_id sent changes, so re-running # this is safe. -auth0 api patch "connections/$CONNECTION_ID/clients" \ +auth0 connections enabled-clients update "$CONNECTION_ID" \ --data "[{\"client_id\":\"$CLIENT_ID\",\"status\":true}]" \ --no-input > /dev/null diff --git a/main/.mintlify/skills/auth0/references/framework-angular/index.md b/main/.mintlify/skills/auth0/references/framework-angular/index.md index 165cac0c3b..0efd91fdcf 100644 --- a/main/.mintlify/skills/auth0/references/framework-angular/index.md +++ b/main/.mintlify/skills/auth0/references/framework-angular/index.md @@ -817,32 +817,41 @@ if ! auth0 tenants list &> /dev/null; then auth0 login fi -# Create or select app -auth0 apps list -read -p "Enter your Auth0 app ID (or press Enter to create new): " APP_ID - -if [ -z "$APP_ID" ]; then - APP_NAME="${PWD##*/}-angular-app" - APP_ID=$(auth0 apps create \ - --name "$APP_NAME" \ - --type spa \ - --auth-method None \ - --callbacks "http://localhost:4200" \ - --logout-urls "http://localhost:4200" \ - --origins "http://localhost:4200" \ - --web-origins "http://localhost:4200" \ - --metadata "created_by=agent_skills" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) -fi +# qs setup replaces an existing environment.ts, so use it only when the file doesn't exist yet. +if [ ! -f src/environments/environment.ts ]; then + if ! auth0 qs setup --app --framework angular --type spa; then + echo "❌ auth0 qs setup failed" + exit 1 + fi + echo "✅ Configuration complete! Auth0 settings written to src/environments/environment.ts" +else + # Create or select app + auth0 apps list + read -p "Enter your Auth0 app ID (or press Enter to create new): " APP_ID + + if [ -z "$APP_ID" ]; then + APP_NAME="${PWD##*/}-angular-app" + APP_ID=$(auth0 apps create \ + --name "$APP_NAME" \ + --type spa \ + --auth-method None \ + --callbacks "http://localhost:4200" \ + --logout-urls "http://localhost:4200" \ + --origins "http://localhost:4200" \ + --web-origins "http://localhost:4200" \ + --metadata "created_by=agent_skills" \ + --json-compact | jq -r '.client_id') + fi -# Get credentials -AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + # Get credentials + AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') + AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') -echo "✅ Configuration complete!" -echo "Update src/environments/environment.ts with:" -echo " domain: '$AUTH0_DOMAIN'" -echo " clientId: '$AUTH0_CLIENT_ID'" + echo "✅ Configuration complete!" + echo "Update src/environments/environment.ts with:" + echo " domain: '$AUTH0_DOMAIN'" + echo " clientId: '$AUTH0_CLIENT_ID'" +fi ``` --- diff --git a/main/.mintlify/skills/auth0/references/framework-aspnetcore-api/index.md b/main/.mintlify/skills/auth0/references/framework-aspnetcore-api/index.md index a6046194f0..d1c4567206 100644 --- a/main/.mintlify/skills/auth0/references/framework-aspnetcore-api/index.md +++ b/main/.mintlify/skills/auth0/references/framework-aspnetcore-api/index.md @@ -7,7 +7,7 @@ Protect ASP.NET Core Web API endpoints with JWT access token validation using Au - .NET 8.0 SDK or higher - Auth0 API configured (not Application - must be API resource) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use @@ -713,7 +713,7 @@ public class ApiTests : IClassFixture> public async Task ProtectedEndpoint_WithValidToken_Returns200() { // Option 1: Real token from Auth0 CLI (requires network, good for integration tests) - // auth0 test token --audience https://my-api.example.com + // auth0 test token --audience https://my-api.example.com // // Option 2: Mock JWT for fast unit tests — override auth in WebApplicationFactory: // _factory.WithWebHostBuilder(b => b.ConfigureTestServices(services => @@ -857,7 +857,7 @@ Note the double underscore `__` separator for nested config in environment varia ```bash # Get access token for testing -auth0 test token \ +auth0 test token \ --audience https://my-api.example.com ``` diff --git a/main/.mintlify/skills/auth0/references/framework-expo/index.md b/main/.mintlify/skills/auth0/references/framework-expo/index.md index 397a803d52..4cab772512 100644 --- a/main/.mintlify/skills/auth0/references/framework-expo/index.md +++ b/main/.mintlify/skills/auth0/references/framework-expo/index.md @@ -1007,7 +1007,7 @@ If using refresh token rotation, configure a token overlap period of at least ** > > 1. **Pre-flight checks:** > - Verify Auth0 CLI is installed: `command -v auth0` -> - Verify logged in: `auth0 tenants list --csv --no-input` +> - Verify logged in: `auth0 tenants list --json-compact | jq -r '.[] | select(.active) | .name'` > - If any check fails, guide user to install/login, or fall back to manual setup > > 2. **Read the project's app.json** to extract: @@ -1030,18 +1030,18 @@ If using refresh token rotation, configure a token overlap period of at least ** > > 4. **Enable database connection** for the new client: > ```bash -> auth0 api get "connections" --query "name=Username-Password-Authentication" --no-input +> auth0 connections list --query '{"name":"Username-Password-Authentication"}' --no-input > ``` > Parse the response to extract the connection `id` as `CONNECTION_ID`. If it doesn't exist, create it and parse `id` from the create response as `CONNECTION_ID` instead: > > ```bash -> auth0 api post "connections" --data '{"strategy":"auth0","name":"Username-Password-Authentication"}' --no-input +> auth0 connections create --name "Username-Password-Authentication" --strategy auth0 --no-input > ``` > > Then enable it for the client, using the `CONNECTION_ID` found above (existing) or just created: > > ```bash -> auth0 api patch "connections/CONNECTION_ID/clients" --data '[{"client_id":"NEW_CLIENT_ID","status":true}]' --no-input +> auth0 connections enabled-clients update CONNECTION_ID --data '[{"client_id":"NEW_CLIENT_ID","status":true}]' --no-input > ``` > > 5. **Write the plugin config to app.json** using the Edit tool — add `react-native-auth0` to the plugins array with the domain and custom scheme. Do not echo credentials in your response. diff --git a/main/.mintlify/skills/auth0/references/framework-express-jwt/index.md b/main/.mintlify/skills/auth0/references/framework-express-jwt/index.md index 83cbdf7dd2..3236d1c26d 100644 --- a/main/.mintlify/skills/auth0/references/framework-express-jwt/index.md +++ b/main/.mintlify/skills/auth0/references/framework-express-jwt/index.md @@ -15,7 +15,7 @@ The `express-oauth2-jwt-bearer` package provides Express middleware for validati - **Express** 4.x or 5.x - **npm** or **yarn** - An **Auth0 account** with a configured API (Resource Server) -- **Auth0 CLI** (for automatic setup): `npm install -g @auth0/auth0-cli` +- **Auth0 CLI** (for automatic setup): `brew install auth0` (macOS) or `curl -sSfL https://raw.githubusercontent.com/auth0/auth0-cli/main/install.sh | sh -s -- -b /usr/local/bin` (Linux) ## When NOT to Use diff --git a/main/.mintlify/skills/auth0/references/framework-express/index.md b/main/.mintlify/skills/auth0/references/framework-express/index.md index a6c4ab57bf..23f2cd831b 100644 --- a/main/.mintlify/skills/auth0/references/framework-express/index.md +++ b/main/.mintlify/skills/auth0/references/framework-express/index.md @@ -712,8 +712,8 @@ Then ask the user for explicit confirmation before proceeding — do not continu - Options: "Yes, append to existing .env" / "No, I'll update it manually" - If neither exists, ask: - - Question: "This setup will create a `.env.local` file containing Auth0 credentials (CLIENT_ID, ISSUER_BASE_URL, SECRET) and a placeholder for CLIENT_SECRET. Do you want to proceed?" - - Options: "Yes, create .env.local" / "No, I'll configure it manually" + - Question: "This setup will create a `.env` file containing Auth0 settings (ISSUER_BASE_URL, CLIENT_ID, SECRET, BASE_URL). Do you want to proceed?" + - Options: "Yes, create .env" / "No, I'll configure it manually" **Do not proceed with writing to any env file unless the user selects the confirmation option.** @@ -738,34 +738,39 @@ fi # Login auth0 login 2>/dev/null || auth0 login -# Create/select app -auth0 apps list -read -p "Enter app ID (or Enter to create): " APP_ID - -if [ -z "$APP_ID" ]; then - APP_ID=$(auth0 apps create --name "${PWD##*/}-express" --type regular \ - --callbacks "http://localhost:3000/callback" \ - --logout-urls "http://localhost:3000" \ - --metadata "created_by=agent_skills" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) -fi +# qs setup writes .env and replaces an existing one, so use it only when no env file exists yet. +if [ ! -f .env ] && [ ! -f .env.local ]; then + if ! auth0 qs setup --app --framework express --type regular; then + echo "❌ auth0 qs setup failed" + exit 1 + fi + echo "✅ Auth0 credentials written to .env" +else + # Create/select app + auth0 apps list + read -p "Enter app ID (or Enter to create): " APP_ID + + if [ -z "$APP_ID" ]; then + APP_ID=$(auth0 apps create --name "${PWD##*/}-express" --type regular \ + --callbacks "http://localhost:3000/callback" \ + --logout-urls "http://localhost:3000" \ + --metadata "created_by=agent_skills" \ + --json-compact | jq -r '.client_id') + fi -# Get credentials -DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) -SECRET=$(openssl rand -hex 32) + # Get credentials + DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') + CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') + SECRET=$(openssl rand -hex 32) -# Determine target env file -if [ -f .env.local ]; then - TARGET_FILE=".env.local" -elif [ -f .env ]; then - TARGET_FILE=".env" -else - TARGET_FILE=".env.local" -fi + # Append to .env.local if it exists, otherwise to .env + if [ -f .env.local ]; then + TARGET_FILE=".env.local" + else + TARGET_FILE=".env" + fi -# Append Auth0 credentials -cat >> "$TARGET_FILE" << ENVEOF + cat >> "$TARGET_FILE" << ENVEOF SECRET=$SECRET BASE_URL=http://localhost:3000 CLIENT_ID=$CLIENT_ID @@ -773,11 +778,12 @@ CLIENT_SECRET='YOUR_CLIENT_SECRET' ISSUER_BASE_URL=https://$DOMAIN ENVEOF -echo "✅ Auth0 credentials written to $TARGET_FILE" + echo "✅ Auth0 credentials written to $TARGET_FILE" +fi ``` After the script runs, remind the user to: -1. Open the env file that was written and replace `YOUR_CLIENT_SECRET` with the actual client secret from Auth0. +1. If an env file already existed (the `apps create` path), replace `YOUR_CLIENT_SECRET` with the actual client secret from Auth0 — it's only needed when calling APIs (`response_type: 'code'`). 2. Ensure the env file is listed in `.gitignore` to avoid accidentally committing secrets. --- diff --git a/main/.mintlify/skills/auth0/references/framework-fastapi-api/index.md b/main/.mintlify/skills/auth0/references/framework-fastapi-api/index.md index ba8c4ec3bd..f9a1d10caf 100644 --- a/main/.mintlify/skills/auth0/references/framework-fastapi-api/index.md +++ b/main/.mintlify/skills/auth0/references/framework-fastapi-api/index.md @@ -9,7 +9,7 @@ Protect FastAPI API endpoints with JWT access token validation using `auth0-fast - FastAPI application (Python 3.9+) - Auth0 API resource configured (not an Application — must be an API) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use diff --git a/main/.mintlify/skills/auth0/references/framework-fastify-api/index.md b/main/.mintlify/skills/auth0/references/framework-fastify-api/index.md index 5f9c8b195b..4a57b9a4cb 100644 --- a/main/.mintlify/skills/auth0/references/framework-fastify-api/index.md +++ b/main/.mintlify/skills/auth0/references/framework-fastify-api/index.md @@ -9,7 +9,7 @@ Protect Fastify API endpoints with JWT access token validation using @auth0/auth - Fastify API application (v5.x or newer) - Node.js 20 LTS or newer - Auth0 API configured (not Application - must be API resource) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use diff --git a/main/.mintlify/skills/auth0/references/framework-fastify/index.md b/main/.mintlify/skills/auth0/references/framework-fastify/index.md index 5ce7d9e3c9..751dbd32df 100644 --- a/main/.mintlify/skills/auth0/references/framework-fastify/index.md +++ b/main/.mintlify/skills/auth0/references/framework-fastify/index.md @@ -30,7 +30,13 @@ npm install @auth0/auth0-fastify fastify @fastify/view ejs dotenv ### 2. Configure Environment -Create `.env`: +If the project has no `.env` yet, `auth0 qs setup` creates the Auth0 app and writes `.env` in one step (it replaces an existing `.env`, so skip it when one exists): + +```bash +[ ! -f .env ] && auth0 qs setup --app --framework fastify --type regular +``` + +Otherwise, add these to `.env`: ```bash AUTH0_DOMAIN=your-tenant.auth0.com diff --git a/main/.mintlify/skills/auth0/references/framework-flask/index.md b/main/.mintlify/skills/auth0/references/framework-flask/index.md index 2cee2b5ba5..db824193fd 100644 --- a/main/.mintlify/skills/auth0/references/framework-flask/index.md +++ b/main/.mintlify/skills/auth0/references/framework-flask/index.md @@ -966,12 +966,12 @@ if [ -z "$APP_ID" ]; then --callbacks "http://localhost:5000/callback" \ --logout-urls "http://localhost:5000" \ --metadata "created_by=agent_skills" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + --json-compact | jq -r '.client_id') fi # Get credentials -DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) +DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') +CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') SECRET=$(openssl rand -hex 64) # Determine target env file diff --git a/main/.mintlify/skills/auth0/references/framework-go/index.md b/main/.mintlify/skills/auth0/references/framework-go/index.md index 6549fe60a2..ae69f6875a 100644 --- a/main/.mintlify/skills/auth0/references/framework-go/index.md +++ b/main/.mintlify/skills/auth0/references/framework-go/index.md @@ -19,7 +19,7 @@ Protect Go HTTP API endpoints with JWT access token validation using github.com/ - Go 1.21 or higher - Auth0 API configured (not Application - must be API resource) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use @@ -304,21 +304,13 @@ mux.Handle("/api/private-scoped", middleware.CheckJWT(http.HandlerFunc(privateSc > Parse the JSON to extract `client_id`. Do NOT use `--reveal-secrets` — instead, if the client secret is needed, have the user run `auth0 apps show --reveal-secrets` in their own terminal so secrets stay out of the agent context. > Then create a client grant: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > > **If the user chose "Use existing":** > Ask for the Client ID. Then create a client grant to authorize it for this API: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > If the grant already exists (409 conflict), that's fine — the app is already authorized. @@ -1338,19 +1330,11 @@ Setup instructions for Go API applications. > Parse the JSON output to extract the `client_id`. **Do NOT use `--reveal-secrets`** — instead, rather than handling client secrets in agent context, tell the user: _"Your M2M app has been created. To get the client secret, run `auth0 apps show --reveal-secrets` in your terminal."_ > Then create a client grant to authorize the app for the API: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > - **Option B: "Use an existing application"** — Ask the user for the `client_id` of their existing application. Then create a client grant to authorize it for this API: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > If the grant already exists (409 conflict), that's fine — the app is already authorized. > @@ -1439,11 +1423,7 @@ auth0 apps create \ Note the `client_id` from the JSON output. Then authorize it for your API by creating a client grant: ```bash -auth0 api post "client-grants" --data '{ - "client_id": "YOUR_M2M_CLIENT_ID", - "audience": "https://my-api.example.com", - "scope": ["read:messages"] -}' +auth0 client-grants create --client-id YOUR_M2M_CLIENT_ID --audience https://my-api.example.com --scopes "read:messages,write:messages" ``` To retrieve the client secret for manual token requests, run in your terminal: @@ -1451,7 +1431,7 @@ To retrieve the client secret for manual token requests, run in your terminal: auth0 apps show YOUR_M2M_CLIENT_ID --reveal-secrets ``` -If you already have an application you'd like to use, run the same `auth0 api post "client-grants"` command with your existing app's `client_id` to authorize it for this API. +If you already have an application you'd like to use, run the same `auth0 client-grants create` command with your existing app's `client_id` to authorize it for this API. ### Step 2: Add configuration @@ -1539,11 +1519,7 @@ auth0 apps create \ Note the `client_id` from the output. To get the client secret, run `auth0 apps show --reveal-secrets` in your terminal. Then authorize the app for your API: ```bash -auth0 api post "client-grants" --data '{ - "client_id": "YOUR_M2M_CLIENT_ID", - "audience": "https://my-api.example.com", - "scope": ["read:messages"] -}' +auth0 client-grants create --client-id YOUR_M2M_CLIENT_ID --audience https://my-api.example.com --scopes "read:messages,write:messages" ``` ### Via Auth0 CLI diff --git a/main/.mintlify/skills/auth0/references/framework-ionic-angular/index.md b/main/.mintlify/skills/auth0/references/framework-ionic-angular/index.md index a6cf49835d..2f328c9bb4 100644 --- a/main/.mintlify/skills/auth0/references/framework-ionic-angular/index.md +++ b/main/.mintlify/skills/auth0/references/framework-ionic-angular/index.md @@ -1029,8 +1029,8 @@ node --version # Verify Auth0 CLI is installed auth0 --version --no-input -# Verify logged in to Auth0 -auth0 tenants list --csv --no-input +# Verify logged in to Auth0 and capture active tenant domain +AUTH0_DOMAIN=$(auth0 tenants list --json-compact | jq -r '.[] | select(.active) | .name') ``` If the Auth0 CLI is not installed, instruct the user: @@ -1056,10 +1056,10 @@ auth0 login #### Step A3: Get the active tenant domain ```bash -auth0 tenants list --csv --no-input +AUTH0_DOMAIN=$(auth0 tenants list --json-compact | jq -r '.[] | select(.active) | .name') ``` -Parse the output to find the line containing `→` — the second CSV column on that line is the active domain. +The output is the active tenant domain. #### Step A4: Create a Native Auth0 application @@ -1081,7 +1081,7 @@ Extract `client_id` from the JSON output. #### Step A5: Enable Username-Password-Authentication connection ```bash -auth0 api get connections +auth0 connections list --query '{"name":"Username-Password-Authentication"}' ``` Parse the JSON array to find the connection with `"name": "Username-Password-Authentication"`. @@ -1089,7 +1089,7 @@ Parse the JSON array to find the connection with `"name": "Username-Password-Aut - **If it doesn't exist**, create it and parse `id` from the response as `CONNECTION_ID`: ```bash - auth0 api post connections --data '{"strategy":"auth0","name":"Username-Password-Authentication"}' + auth0 connections create --name "Username-Password-Authentication" --strategy auth0 ``` - Then enable it for the new client, using the `CONNECTION_ID` found above (existing) or @@ -1097,7 +1097,7 @@ Parse the JSON array to find the connection with `"name": "Username-Password-Aut no check first: ```bash - auth0 api patch "connections/CONNECTION_ID/clients" --data '[{"client_id":"NEW_CLIENT_ID","status":true}]' + auth0 connections enabled-clients update CONNECTION_ID --data '[{"client_id":"NEW_CLIENT_ID","status":true}]' ``` #### Step A6: Write config file diff --git a/main/.mintlify/skills/auth0/references/framework-ionic-react/index.md b/main/.mintlify/skills/auth0/references/framework-ionic-react/index.md index 2a14b863ca..9cb94e4a10 100644 --- a/main/.mintlify/skills/auth0/references/framework-ionic-react/index.md +++ b/main/.mintlify/skills/auth0/references/framework-ionic-react/index.md @@ -865,10 +865,10 @@ npx cap open android # Build and run on device from Android Studio > **Agent instruction:** Run these pre-flight checks before creating the Auth0 application. Do NOT run `auth0 login` from the agent — it is interactive and will hang. > > 1. **Check Auth0 CLI**: `command -v auth0`. If missing, install it: `brew install auth0`. -> 2. **Check Auth0 login**: `auth0 tenants list --csv --no-input`. If it fails or returns empty: +> 2. **Check Auth0 login**: `AUTH0_DOMAIN=$(auth0 tenants list --json-compact | jq -r '.[] | select(.active) | .name')`. If it fails or returns empty: > - Tell the user: _"Please run `auth0 login` in your terminal and let me know when done."_ > - Wait for confirmation, then re-run the check. Retry up to 3 times before treating as a persistent failure. -> 3. **Confirm active tenant**: Parse the `→` line from the CSV output. Tell the user: _"Your active Auth0 tenant is: ``. Is this correct?"_ +> 3. **Confirm active tenant**: The output of step 2 is the active tenant domain. Tell the user: _"Your active Auth0 tenant is: ``. Is this correct?"_ > - If no, ask the user to run `auth0 tenants use `, then re-run step 2. > > Once confirmed, run the following steps: @@ -881,7 +881,7 @@ npx cap open android # Build and run on device from Android Studio > auth0 apps create \ > --name "APP_NAME" \ > --type native \ -> --auth-method None \ +> --auth-method none \ > --callbacks "PACKAGE_ID://DOMAIN/capacitor/PACKAGE_ID/callback" \ > --logout-urls "PACKAGE_ID://DOMAIN/capacitor/PACKAGE_ID/callback" \ > --origins "capacitor://localhost,http://localhost" \ diff --git a/main/.mintlify/skills/auth0/references/framework-ionic-vue/index.md b/main/.mintlify/skills/auth0/references/framework-ionic-vue/index.md index 0880d719cf..72982719e6 100644 --- a/main/.mintlify/skills/auth0/references/framework-ionic-vue/index.md +++ b/main/.mintlify/skills/auth0/references/framework-ionic-vue/index.md @@ -1004,10 +1004,10 @@ npx cap open android # Build and run on device from Android Studio > #### Step B — Verify Auth0 CLI login session > > ```bash -> auth0 tenants list --csv --no-input +> AUTH0_DOMAIN=$(auth0 tenants list --json-compact | jq -r '.[] | select(.active) | .name') > ``` > -> - **If the command succeeds** and returns CSV output with tenant rows: proceed to Step C. +> - **If the command succeeds** and returns a domain string: proceed to Step C. > - **If the command fails** (exit code non-zero, or output contains "login" / "unauthorized" / is empty): > - Tell the user: _"You're not logged in to the Auth0 CLI. Please run `auth0 login` in your terminal and let me know when done."_ > - Use `AskUserQuestion` to wait for confirmation. @@ -1018,16 +1018,7 @@ npx cap open android # Build and run on device from Android Studio > > #### Step C — Detect active Auth0 tenant domain > -> Parse the CSV output from Step B. The active tenant line contains `→` (Unicode arrow U+2192). -> -> ``` -> Example output: -> ACTIVE,DOMAIN -> →,dev-example.us.auth0.com -> ,dev-other.us.auth0.com -> ``` -> -> Extract the domain from the second column of the `→` line (e.g., `dev-example.us.auth0.com`). +> The output of Step B is the active tenant domain (e.g., `dev-example.us.auth0.com`). > > Tell the user: _"Your active Auth0 tenant is: ``. Is this correct?"_ > - If no, ask the user to run `auth0 tenants use `, then re-run Step B. diff --git a/main/.mintlify/skills/auth0/references/framework-java-mvc/index.md b/main/.mintlify/skills/auth0/references/framework-java-mvc/index.md index 9da228a646..08551876c9 100644 --- a/main/.mintlify/skills/auth0/references/framework-java-mvc/index.md +++ b/main/.mintlify/skills/auth0/references/framework-java-mvc/index.md @@ -1107,7 +1107,7 @@ Or manually in Auth0 Dashboard: ```bash # List existing connections -auth0 api get connections +auth0 connections list # Enable your app on the default database connection # (done automatically if using Option A: Automatic Setup) diff --git a/main/.mintlify/skills/auth0/references/framework-kmp/index.md b/main/.mintlify/skills/auth0/references/framework-kmp/index.md index 356cf233cd..e39a77af81 100644 --- a/main/.mintlify/skills/auth0/references/framework-kmp/index.md +++ b/main/.mintlify/skills/auth0/references/framework-kmp/index.md @@ -143,7 +143,7 @@ echo it. The app resource does **not** include the tenant domain; fetch it separately: ```bash -auth0 tenants list --json | jq -r '.[0].domain' +auth0 tenants list --json | jq -r '.[] | select(.active) | .name' ``` Write both `client_id` and the tenant domain into the project (see Step 3). diff --git a/main/.mintlify/skills/auth0/references/framework-laravel-api/index.md b/main/.mintlify/skills/auth0/references/framework-laravel-api/index.md index 6fd6bd26ab..490e13634a 100644 --- a/main/.mintlify/skills/auth0/references/framework-laravel-api/index.md +++ b/main/.mintlify/skills/auth0/references/framework-laravel-api/index.md @@ -21,7 +21,7 @@ Protect Laravel API endpoints with JWT access token validation using `auth0/logi - PHP 8.2+ with extensions: `mbstring`, `openssl`, `json` - Composer installed - Auth0 API resource configured (not an Application - must be an API) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use @@ -292,11 +292,7 @@ Claims are accessed via: > Parse JSON with `jq` to extract `client_id`. Do NOT use `--reveal-secrets`; instead, use only the `client_id` — the client secret is not needed for the token flow below. > Then create a client grant: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > > **If the user chose "Use existing":** diff --git a/main/.mintlify/skills/auth0/references/framework-nextjs/index.md b/main/.mintlify/skills/auth0/references/framework-nextjs/index.md index 500963c382..28cf0a44c7 100644 --- a/main/.mintlify/skills/auth0/references/framework-nextjs/index.md +++ b/main/.mintlify/skills/auth0/references/framework-nextjs/index.md @@ -699,7 +699,7 @@ Then ask the user for explicit confirmation before proceeding — do not continu - Options: "Yes, append to existing .env" / "No, I'll update it manually" - If neither exists, ask: - - Question: "This setup will create a `.env.local` file containing Auth0 credentials (AUTH0_CLIENT_ID, AUTH0_DOMAIN, AUTH0_SECRET) and a placeholder for AUTH0_CLIENT_SECRET that you will need to fill in manually. Do you want to proceed?" + - Question: "This setup will create a `.env.local` file containing Auth0 credentials (AUTH0_DOMAIN, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_SECRET, APP_BASE_URL). Do you want to proceed?" - Options: "Yes, create .env.local" / "No, I'll configure it manually" **Do not proceed with writing to any env file unless the user selects the confirmation option.** @@ -728,38 +728,44 @@ if ! auth0 tenants list &> /dev/null; then auth0 login fi -# Create/select app -auth0 apps list -read -p "Enter app ID (or Enter to create new): " APP_ID - -if [ -z "$APP_ID" ]; then - APP_ID=$(auth0 apps create \ - --name "${PWD##*/}-nextjs" \ - --type regular \ - --callbacks "http://localhost:3000/auth/callback" \ - --logout-urls "http://localhost:3000" \ - --metadata "created_by=agent_skills" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) -fi +# qs setup writes .env (and replaces an existing one); Next.js keeps secrets in .env.local. +# Use it only when neither file exists, then move its output to .env.local. +if [ ! -f .env ] && [ ! -f .env.local ]; then + if ! { auth0 qs setup --app --framework nextjs --type regular && mv .env .env.local; }; then + echo "❌ auth0 qs setup failed" + exit 1 + fi + echo "✅ Auth0 credentials written to .env.local" +else + # Create/select app + auth0 apps list + read -p "Enter app ID (or Enter to create new): " APP_ID + + if [ -z "$APP_ID" ]; then + APP_ID=$(auth0 apps create \ + --name "${PWD##*/}-nextjs" \ + --type regular \ + --callbacks "http://localhost:3000/auth/callback" \ + --logout-urls "http://localhost:3000" \ + --metadata "created_by=agent_skills" \ + --json-compact | jq -r '.client_id') + fi -# Get credentials -AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + # Get credentials + AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') + AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') -# Generate secret -AUTH0_SECRET=$(openssl rand -hex 32) + # Generate secret + AUTH0_SECRET=$(openssl rand -hex 32) -# Determine target env file -if [ -f .env.local ]; then - TARGET_FILE=".env.local" -elif [ -f .env ]; then - TARGET_FILE=".env" -else - TARGET_FILE=".env.local" -fi + # Append to .env.local if it exists, otherwise to .env + if [ -f .env.local ]; then + TARGET_FILE=".env.local" + else + TARGET_FILE=".env" + fi -# Append Auth0 credentials -cat >> "$TARGET_FILE" << ENVEOF + cat >> "$TARGET_FILE" << ENVEOF AUTH0_SECRET=$AUTH0_SECRET APP_BASE_URL=http://localhost:3000 AUTH0_DOMAIN=$AUTH0_DOMAIN @@ -767,11 +773,12 @@ AUTH0_CLIENT_ID=$AUTH0_CLIENT_ID AUTH0_CLIENT_SECRET='YOUR_CLIENT_SECRET' ENVEOF -echo "✅ Auth0 credentials written to $TARGET_FILE" + echo "✅ Auth0 credentials written to $TARGET_FILE" +fi ``` After the script runs, remind the user to: -1. Open the env file that was written and replace `YOUR_CLIENT_SECRET` with the actual client secret from Auth0. +1. If an env file already existed (the `apps create` path), replace `YOUR_CLIENT_SECRET` with the actual client secret from Auth0. On a new project `qs setup` writes the real secret. 2. Ensure the env file is listed in `.gitignore` to avoid accidentally committing secrets. --- diff --git a/main/.mintlify/skills/auth0/references/framework-php-api/index.md b/main/.mintlify/skills/auth0/references/framework-php-api/index.md index ce5837ef54..ff4e663be4 100644 --- a/main/.mintlify/skills/auth0/references/framework-php-api/index.md +++ b/main/.mintlify/skills/auth0/references/framework-php-api/index.md @@ -15,7 +15,7 @@ Protect PHP API endpoints with JWT access token validation using `auth0/auth0-ph - PHP 8.2+ with extensions: `mbstring`, `openssl`, `json` - Composer installed - Auth0 API resource configured (not an Application - must be an API) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use @@ -324,21 +324,13 @@ CORS must be handled before auth so that preflight `OPTIONS` requests short-circ > Parse the JSON with `jq` to extract `client_id`. Do NOT use `--reveal-secrets` - never expose client secrets in agent context. Instead, use only the `client_id`; the client-credentials/client-grant flow below does not require the secret in agent context. > Then create a client grant: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > > **If the user chose "Use existing":** > Ask for the Client ID. Then create a client grant to authorize it for this API: > ```bash -> auth0 api post "client-grants" --data '{ -> "client_id": "", -> "audience": "", -> "scope": [""] -> }' +> auth0 client-grants create --client-id --audience --scopes "" > ``` > If the grant already exists (409 conflict), that's fine - the app is already authorized. @@ -1240,7 +1232,7 @@ class ApiTest extends TestCase ```bash # Get a test token via Auth0 CLI -TOKEN=$(auth0 test token --audience https://my-api.example.com --no-input 2>/dev/null) +TOKEN=$(auth0 test token --audience https://my-api.example.com --no-input 2>/dev/null) # Test protected endpoint curl -s http://localhost:8000/api/private \ @@ -1425,7 +1417,7 @@ export AUTH0_AUDIENCE=https://my-api.example.com ```bash # Get access token for testing -auth0 test token \ +auth0 test token \ --audience https://my-api.example.com ``` diff --git a/main/.mintlify/skills/auth0/references/framework-react/index.md b/main/.mintlify/skills/auth0/references/framework-react/index.md index 458085f08f..015cf96379 100644 --- a/main/.mintlify/skills/auth0/references/framework-react/index.md +++ b/main/.mintlify/skills/auth0/references/framework-react/index.md @@ -1055,18 +1055,19 @@ Complete setup instructions with automated scripts and manual configuration opti Before writing to `.env`, check whether the file already exists: ```bash -test -f .env && echo "EXISTS" || echo "NOT_FOUND" +test -f .env.local && echo "ENV_LOCAL_EXISTS" || echo "ENV_LOCAL_NOT_FOUND" +test -f .env && echo "ENV_EXISTS" || echo "ENV_NOT_FOUND" ``` Then ask the user for explicit confirmation before proceeding — do not continue until the user confirms: -- If `.env` does **not** exist, ask: +- If neither `.env` nor `.env.local` exists, ask: - Question: "This setup will create a `.env` file containing Auth0 credentials (domain and client ID). Do you want to proceed?" - Options: "Yes, create .env" / "No, I'll configure it manually" -- If `.env` **already exists**, ask: - - Question: "A `.env` file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to it without modifying existing content. Do you want to proceed?" - - Options: "Yes, append to existing .env" / "No, I'll update it manually" +- If `.env.local` or `.env` **already exists**, ask: + - Question: "An env file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to `.env.local` (if present, since it overrides `.env`) or `.env`, without modifying existing content. Do you want to proceed?" + - Options: "Yes, append to the existing env file" / "No, I'll update it manually" **Do not proceed with writing to `.env` unless the user selects the confirmation option.** @@ -1132,53 +1133,63 @@ if ! auth0 tenants list &> /dev/null; then echo "✅ Successfully logged in to Auth0!" fi -# Detect if Vite or CRA -if grep -q '"vite"' package.json 2>/dev/null; then - PREFIX="VITE_AUTH0" -elif grep -q '"react-scripts"' package.json 2>/dev/null; then - PREFIX="REACT_APP_AUTH0" +# qs setup replaces an existing .env (and Vite lets .env.local override it), so use it +# only for a Vite project with neither file yet. +if [ ! -f .env ] && [ ! -f .env.local ] && { [ -f vite.config.ts ] || [ -f vite.config.js ] || [ -f vite.config.mjs ]; }; then + if ! auth0 qs setup --app --framework react --build-tool vite --type spa --port 5173; then + echo "❌ auth0 qs setup failed" + exit 1 + fi else - echo "Detecting React project type..." - PREFIX="VITE_AUTH0" # Default to Vite -fi - -# List apps and prompt for selection -echo "Your Auth0 applications:" -auth0 apps list + # Detect if Vite or CRA + if grep -q '"vite"' package.json 2>/dev/null; then + PREFIX="VITE_AUTH0" + elif grep -q '"react-scripts"' package.json 2>/dev/null; then + PREFIX="REACT_APP_AUTH0" + else + echo "Detecting React project type..." + PREFIX="VITE_AUTH0" # Default to Vite + fi -read -p "Enter your Auth0 app ID (or press Enter to create a new one): " APP_ID - -if [ -z "$APP_ID" ]; then - echo "Creating new Auth0 SPA application..." - APP_NAME="${PWD##*/}-react-app" - APP_ID=$(auth0 apps create \ - --name "$APP_NAME" \ - --type spa \ - --auth-method None \ - --callbacks "http://localhost:3000,http://localhost:5173" \ - --logout-urls "http://localhost:3000,http://localhost:5173" \ - --origins "http://localhost:3000,http://localhost:5173" \ - --web-origins "http://localhost:3000,http://localhost:5173" \ - --metadata "created_by=agent_skills" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) - echo "Created app with ID: $APP_ID" -fi + # List apps and prompt for selection + echo "Your Auth0 applications:" + auth0 apps list + + read -p "Enter your Auth0 app ID (or press Enter to create a new one): " APP_ID + + if [ -z "$APP_ID" ]; then + echo "Creating new Auth0 SPA application..." + APP_NAME="${PWD##*/}-react-app" + APP_ID=$(auth0 apps create \ + --name "$APP_NAME" \ + --type spa \ + --auth-method None \ + --callbacks "http://localhost:3000,http://localhost:5173" \ + --logout-urls "http://localhost:3000,http://localhost:5173" \ + --origins "http://localhost:3000,http://localhost:5173" \ + --web-origins "http://localhost:3000,http://localhost:5173" \ + --metadata "created_by=agent_skills" \ + --json-compact | jq -r '.client_id') + echo "Created app with ID: $APP_ID" + fi -# Get app details and create .env file -echo "Fetching Auth0 credentials..." -AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + # Get app details and append Auth0 credentials to .env + echo "Fetching Auth0 credentials..." + AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') + AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') -# Append Auth0 credentials to .env -cat >> .env << EOF + # Append to .env.local if it exists (it overrides .env), otherwise to .env + TARGET_FILE=$([ -f .env.local ] && echo .env.local || echo .env) + cat >> "$TARGET_FILE" << EOF ${PREFIX}_DOMAIN=$AUTH0_DOMAIN ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID EOF + echo "Appended to $TARGET_FILE:" + echo " ${PREFIX}_DOMAIN=$AUTH0_DOMAIN" + echo " ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID" +fi echo "✅ Auth0 configuration complete!" -echo "Appended to .env:" -echo " ${PREFIX}_DOMAIN=$AUTH0_DOMAIN" -echo " ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID" ``` #### PowerShell Script (Windows) diff --git a/main/.mintlify/skills/auth0/references/framework-spa-js/index.md b/main/.mintlify/skills/auth0/references/framework-spa-js/index.md index b8e1762f6b..4817c7de52 100644 --- a/main/.mintlify/skills/auth0/references/framework-spa-js/index.md +++ b/main/.mintlify/skills/auth0/references/framework-spa-js/index.md @@ -850,18 +850,19 @@ Complete setup instructions with automated scripts and manual configuration opti Before writing to `.env`, check whether the file already exists: ```bash -test -f .env && echo "EXISTS" || echo "NOT_FOUND" +test -f .env.local && echo "ENV_LOCAL_EXISTS" || echo "ENV_LOCAL_NOT_FOUND" +test -f .env && echo "ENV_EXISTS" || echo "ENV_NOT_FOUND" ``` Then ask the user for explicit confirmation before proceeding — do not continue until the user confirms: -- If `.env` does **not** exist, ask: +- If neither `.env` nor `.env.local` exists, ask: - Question: "This setup will create a `.env` file containing Auth0 credentials (domain and client ID). Do you want to proceed?" - Options: "Yes, create .env" / "No, I'll configure it manually" -- If `.env` **already exists**, ask: - - Question: "A `.env` file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to it without modifying existing content. Do you want to proceed?" - - Options: "Yes, append to existing .env" / "No, I'll update it manually" +- If `.env.local` or `.env` **already exists**, ask: + - Question: "An env file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to `.env.local` (if present, since it overrides `.env`) or `.env`, without modifying existing content. Do you want to proceed?" + - Options: "Yes, append to the existing env file" / "No, I'll update it manually" **Do not proceed with writing to `.env` unless the user selects the confirmation option.** @@ -907,50 +908,60 @@ if ! auth0 tenants list &> /dev/null; then echo "✅ Successfully logged in to Auth0!" fi -# Detect env var prefix from project -if grep -q '"vite"' package.json 2>/dev/null; then - PREFIX="VITE_AUTH0" -elif grep -q '"react-scripts"' package.json 2>/dev/null; then - PREFIX="REACT_APP_AUTH0" +# qs setup replaces an existing .env (and Vite lets .env.local override it), so use it +# only for a Vite project with neither file yet. +if [ ! -f .env ] && [ ! -f .env.local ] && { [ -f vite.config.ts ] || [ -f vite.config.js ] || [ -f vite.config.mjs ]; }; then + if ! auth0 qs setup --app --framework vanilla-javascript --build-tool vite --type spa --port 5173; then + echo "❌ auth0 qs setup failed" + exit 1 + fi else - PREFIX="VITE_AUTH0" # Default to Vite -fi - -# List apps and prompt for selection -echo "Your Auth0 applications:" -auth0 apps list + # Detect env var prefix from project + if grep -q '"vite"' package.json 2>/dev/null; then + PREFIX="VITE_AUTH0" + elif grep -q '"react-scripts"' package.json 2>/dev/null; then + PREFIX="REACT_APP_AUTH0" + else + PREFIX="VITE_AUTH0" # Default to Vite + fi -read -p "Enter your Auth0 app ID (or press Enter to create a new one): " APP_ID - -if [ -z "$APP_ID" ]; then - echo "Creating new Auth0 SPA application..." - APP_NAME="${PWD##*/}-spa" - APP_ID=$(auth0 apps create \ - --name "$APP_NAME" \ - --type spa \ - --auth-method None \ - --callbacks "http://localhost:3000,http://localhost:5173" \ - --logout-urls "http://localhost:3000,http://localhost:5173" \ - --origins "http://localhost:3000,http://localhost:5173" \ - --web-origins "http://localhost:3000,http://localhost:5173" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) - echo "Created SPA app with ID: $APP_ID" -fi + # List apps and prompt for selection + echo "Your Auth0 applications:" + auth0 apps list + + read -p "Enter your Auth0 app ID (or press Enter to create a new one): " APP_ID + + if [ -z "$APP_ID" ]; then + echo "Creating new Auth0 SPA application..." + APP_NAME="${PWD##*/}-spa" + APP_ID=$(auth0 apps create \ + --name "$APP_NAME" \ + --type spa \ + --auth-method None \ + --callbacks "http://localhost:3000,http://localhost:5173" \ + --logout-urls "http://localhost:3000,http://localhost:5173" \ + --origins "http://localhost:3000,http://localhost:5173" \ + --web-origins "http://localhost:3000,http://localhost:5173" \ + --json-compact | jq -r '.client_id') + echo "Created SPA app with ID: $APP_ID" + fi -# Get app details -AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + # Get app details and append Auth0 credentials to .env + AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') + AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') -# Append to .env -cat >> .env << EOF + # Append to .env.local if it exists (it overrides .env), otherwise to .env + TARGET_FILE=$([ -f .env.local ] && echo .env.local || echo .env) + cat >> "$TARGET_FILE" << EOF ${PREFIX}_DOMAIN=$AUTH0_DOMAIN ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID EOF + echo "Appended to $TARGET_FILE:" + echo " ${PREFIX}_DOMAIN=$AUTH0_DOMAIN" + echo " ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID" +fi echo "✅ Auth0 configuration complete!" -echo "Appended to .env:" -echo " ${PREFIX}_DOMAIN=$AUTH0_DOMAIN" -echo " ${PREFIX}_CLIENT_ID=$AUTH0_CLIENT_ID" ``` #### PowerShell Script (Windows) diff --git a/main/.mintlify/skills/auth0/references/framework-springboot-api/index.md b/main/.mintlify/skills/auth0/references/framework-springboot-api/index.md index c764d598fe..f14231df99 100644 --- a/main/.mintlify/skills/auth0/references/framework-springboot-api/index.md +++ b/main/.mintlify/skills/auth0/references/framework-springboot-api/index.md @@ -18,7 +18,7 @@ Protect Spring Boot API endpoints with JWT access token validation using `com.au - Java 17+ and Spring Boot 3.2+ - Maven 3.6+ or Gradle 7+ - Auth0 API configured (not Application — must be API resource) -- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apps create`) +- If Auth0 isn't set up yet, set it up first with the Auth0 CLI (`auth0 login`, then `auth0 apis create`) ## When NOT to Use @@ -936,7 +936,7 @@ class ApiControllerTest { ```bash # Get a test token -TOKEN=$(auth0 test token --audience https://my-springboot-api --json | jq -r '.access_token') +TOKEN=$(auth0 test token --audience https://my-springboot-api --json | jq -r '.access_token') # Test protected endpoint curl http://localhost:8080/api/protected \ @@ -1141,7 +1141,7 @@ Or use Spring profiles (`application-prod.yml`). ### Via Auth0 CLI (Client Credentials) ```bash -auth0 test token \ +auth0 test token \ --audience https://my-springboot-api ``` diff --git a/main/.mintlify/skills/auth0/references/framework-swift/index.md b/main/.mintlify/skills/auth0/references/framework-swift/index.md index ac09e7e117..97f80e0e16 100644 --- a/main/.mintlify/skills/auth0/references/framework-swift/index.md +++ b/main/.mintlify/skills/auth0/references/framework-swift/index.md @@ -964,10 +964,10 @@ func fetchData() async throws -> [Item] { > **Pre-flight checks:** > > 1. **Check Auth0 CLI**: `command -v auth0`. If missing, install it: `brew install auth0`. -> 2. **Check Auth0 login**: redirect to a private temp file the same way (`OUT=$(mktemp -t auth0-tenants); auth0 tenants list --csv --no-input > "$OUT"`). Read `$OUT` to check the result, then `rm -f "$OUT"`. If it fails or returns empty: +> 2. **Check Auth0 login**: redirect to a private temp file the same way (`OUT=$(mktemp -t auth0-tenants); auth0 tenants list --json-compact > "$OUT"`). Read `$OUT` to check the result. If it fails or returns empty: > - Tell the user: _"Please run `auth0 login` in your terminal and let me know when done."_ > - Wait for confirmation, then re-run the check. Retry up to 3 times before treating as a persistent failure. -> 3. **Confirm active tenant**: Parse the `→` line from step 2's output to extract the domain. Tell the user using a masked format: _"Your active Auth0 tenant is: `your-te****.us.auth0.com`. Is this correct? (Recommend using a development/test tenant rather than production.)"_ — mask all but the first 7 characters of the subdomain. +> 3. **Confirm active tenant**: Extract the domain from step 2's file with `jq -r '.[] | select(.active) | .name' "$OUT"`, save it as `TENANT_DOMAIN`, then `rm -f "$OUT"`. Tell the user using a masked format: _"Your active Auth0 tenant is: `your-te****.us.auth0.com`. Is this correct? (Recommend using a development/test tenant rather than production.)"_ — mask all but the first 7 characters of the subdomain. > - If no, ask the user to run `auth0 tenants use `, then re-run step 2. > > **Detect project settings:** @@ -997,7 +997,7 @@ func fetchData() async throws -> [Item] { > > ```bash > OUT=$(mktemp -t auth0-connections) -> auth0 api get connections --no-input > "$OUT" +> auth0 connections list --query '{"name":"Username-Password-Authentication"}' --no-input > "$OUT" > ``` > > Read `$OUT` to check existing connections, then `rm -f "$OUT"`. @@ -1006,8 +1006,7 @@ func fetchData() async throws -> [Item] { > > ```bash > OUT=$(mktemp -t auth0-connection-created) -> auth0 api post connections \ -> --data '{"strategy":"auth0","name":"Username-Password-Authentication"}' \ +> auth0 connections create --name "Username-Password-Authentication" --strategy auth0 \ > --no-input > "$OUT" > ``` > @@ -1015,7 +1014,7 @@ func fetchData() async throws -> [Item] { > - Then enable it for the client, whether or not the connection already existed: > > ```bash -> auth0 api patch connections/CONNECTION_ID/clients \ +> auth0 connections enabled-clients update CONNECTION_ID \ > --data '[{"client_id":"CLIENT_ID","status":true}]' \ > --no-input > /dev/null 2>&1 > ``` diff --git a/main/.mintlify/skills/auth0/references/framework-tanstack-start/index.md b/main/.mintlify/skills/auth0/references/framework-tanstack-start/index.md index ab2556407c..efe5c546a2 100644 --- a/main/.mintlify/skills/auth0/references/framework-tanstack-start/index.md +++ b/main/.mintlify/skills/auth0/references/framework-tanstack-start/index.md @@ -682,21 +682,22 @@ else TARGET_FILE=".env" fi -# Append Auth0 credentials (never overwrites existing content) +# Append Auth0 credentials (never overwrites existing content). The client secret +# is intentionally left as a placeholder — do NOT fetch it in the agent; the user +# runs --reveal-secrets in their own terminal so the secret stays out of agent context. cat >> "$TARGET_FILE" << ENVEOF AUTH0_DOMAIN=$AUTH0_DOMAIN AUTH0_CLIENT_ID=$AUTH0_CLIENT_ID -AUTH0_CLIENT_SECRET='YOUR_CLIENT_SECRET' +AUTH0_CLIENT_SECRET=YOUR_CLIENT_SECRET AUTH0_SECRET=$AUTH0_SECRET APP_BASE_URL=http://localhost:3000 ENVEOF -echo "✅ Auth0 credentials written to $TARGET_FILE" +echo "✅ Auth0 config written to $TARGET_FILE" +echo " Set AUTH0_CLIENT_SECRET: run 'auth0 apps show $APP_ID --reveal-secrets' in your own terminal (keeps the secret out of agent output)." ``` -After the script runs, remind the user to: -1. Open the env file that was written and replace `YOUR_CLIENT_SECRET` with the actual client secret from the Auth0 Dashboard (Applications → your app → Settings). -2. Ensure the env file is listed in `.gitignore` so secrets are never committed. +Ensure the env file is listed in `.gitignore` so secrets are never committed. ## Manual Setup diff --git a/main/.mintlify/skills/auth0/references/framework-vue/index.md b/main/.mintlify/skills/auth0/references/framework-vue/index.md index a36a543382..b086009fe2 100644 --- a/main/.mintlify/skills/auth0/references/framework-vue/index.md +++ b/main/.mintlify/skills/auth0/references/framework-vue/index.md @@ -811,18 +811,19 @@ Complete setup instructions with automated scripts and manual configuration opti Before writing to `.env`, check whether the file already exists: ```bash -test -f .env && echo "EXISTS" || echo "NOT_FOUND" +test -f .env.local && echo "ENV_LOCAL_EXISTS" || echo "ENV_LOCAL_NOT_FOUND" +test -f .env && echo "ENV_EXISTS" || echo "ENV_NOT_FOUND" ``` Then ask the user for explicit confirmation before proceeding — do not continue until the user confirms: -- If `.env` does **not** exist, ask: +- If neither `.env` nor `.env.local` exists, ask: - Question: "This setup will create a `.env` file containing Auth0 credentials (domain and client ID). Do you want to proceed?" - Options: "Yes, create .env" / "No, I'll configure it manually" -- If `.env` **already exists**, ask: - - Question: "A `.env` file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to it without modifying existing content. Do you want to proceed?" - - Options: "Yes, append to existing .env" / "No, I'll update it manually" +- If `.env.local` or `.env` **already exists**, ask: + - Question: "An env file already exists and may contain secrets unrelated to Auth0. This setup will append Auth0 credentials to `.env.local` (if present, since it overrides `.env`) or `.env`, without modifying existing content. Do you want to proceed?" + - Options: "Yes, append to the existing env file" / "No, I'll update it manually" **Do not proceed with writing to `.env` unless the user selects the confirmation option.** @@ -867,43 +868,53 @@ if ! auth0 tenants list &> /dev/null; then auth0 login fi -# List apps and prompt for selection -echo "Your Auth0 applications:" -auth0 apps list - -read -p "Enter your Auth0 app ID (or press Enter to create new): " APP_ID - -if [ -z "$APP_ID" ]; then - echo "Creating new Auth0 SPA application..." - APP_NAME="${PWD##*/}-vue-app" - APP_ID=$(auth0 apps create \ - --name "$APP_NAME" \ - --type spa \ - --auth-method None \ - --callbacks "http://localhost:5173,http://localhost:3000" \ - --logout-urls "http://localhost:5173,http://localhost:3000" \ - --origins "http://localhost:5173,http://localhost:3000" \ - --web-origins "http://localhost:5173,http://localhost:3000" \ - --metadata "created_by=agent_skills" \ - --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) - echo "Created app with ID: $APP_ID" -fi +# qs setup replaces an existing .env (and Vite lets .env.local override it), so use it +# only for a Vite project with neither file yet. +if [ ! -f .env ] && [ ! -f .env.local ] && { [ -f vite.config.ts ] || [ -f vite.config.js ] || [ -f vite.config.mjs ]; }; then + if ! auth0 qs setup --app --framework vue --build-tool vite --type spa --port 5173; then + echo "❌ auth0 qs setup failed" + exit 1 + fi +else + # List apps and prompt for selection + echo "Your Auth0 applications:" + auth0 apps list + + read -p "Enter your Auth0 app ID (or press Enter to create new): " APP_ID + + if [ -z "$APP_ID" ]; then + echo "Creating new Auth0 SPA application..." + APP_NAME="${PWD##*/}-vue-app" + APP_ID=$(auth0 apps create \ + --name "$APP_NAME" \ + --type spa \ + --auth-method None \ + --callbacks "http://localhost:5173,http://localhost:3000" \ + --logout-urls "http://localhost:5173,http://localhost:3000" \ + --origins "http://localhost:5173,http://localhost:3000" \ + --web-origins "http://localhost:5173,http://localhost:3000" \ + --metadata "created_by=agent_skills" \ + --json-compact | jq -r '.client_id') + echo "Created app with ID: $APP_ID" + fi -# Get app details and create .env file -echo "Fetching Auth0 credentials..." -AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json | grep -o '"domain":"[^"]*' | cut -d'"' -f4) -AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json | grep -o '"client_id":"[^"]*' | cut -d'"' -f4) + # Get app details and append Auth0 credentials to .env + echo "Fetching Auth0 credentials..." + AUTH0_DOMAIN=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.domain') + AUTH0_CLIENT_ID=$(auth0 apps show "$APP_ID" --json-compact | jq -r '.client_id') -# Append Auth0 credentials to .env -cat >> .env << EOF + # Append to .env.local if it exists (it overrides .env), otherwise to .env + TARGET_FILE=$([ -f .env.local ] && echo .env.local || echo .env) + cat >> "$TARGET_FILE" << EOF VITE_AUTH0_DOMAIN=$AUTH0_DOMAIN VITE_AUTH0_CLIENT_ID=$AUTH0_CLIENT_ID EOF + echo "Appended to $TARGET_FILE:" + echo " VITE_AUTH0_DOMAIN=$AUTH0_DOMAIN" + echo " VITE_AUTH0_CLIENT_ID=$AUTH0_CLIENT_ID" +fi echo "✅ Auth0 configuration complete!" -echo "Appended to .env:" -echo " VITE_AUTH0_DOMAIN=$AUTH0_DOMAIN" -echo " VITE_AUTH0_CLIENT_ID=$AUTH0_CLIENT_ID" ``` #### PowerShell Script (Windows) diff --git a/main/.mintlify/skills/auth0/references/tooling-cli/agent-mode.md b/main/.mintlify/skills/auth0/references/tooling-cli/agent-mode.md index 7e63553b37..9e2de0538e 100644 --- a/main/.mintlify/skills/auth0/references/tooling-cli/agent-mode.md +++ b/main/.mintlify/skills/auth0/references/tooling-cli/agent-mode.md @@ -200,9 +200,11 @@ object, not on every command** — this table (or ` --help`) says which | `orgs`, `client-grants` | — | — | `connections enabled-clients update` also takes `--data` / `--schema`. A resource -outside the ✅ rows (e.g. `orgs`, `client-grants`) has no structured input — use -its named flags, or fall back to `auth0 api` with `--data @file` as the JSON-body -escape hatch. +outside the ✅ rows (e.g. `orgs`, `client-grants`) has no structured input, but it +does have typed commands with named flags (for example `auth0 client-grants create` +and `auth0 orgs create`). Prefer those. Fall back to `auth0 api` with `--data @file` +only for an operation that has no typed command, and check +`auth0 commands ` first. Several **configuration commands** accept structured input beyond the classic resources — custom domains, email templates, universal-login (including prompts), diff --git a/main/.mintlify/skills/auth0/references/tooling-cli/index.md b/main/.mintlify/skills/auth0/references/tooling-cli/index.md index fb28fe7265..4e16654146 100644 --- a/main/.mintlify/skills/auth0/references/tooling-cli/index.md +++ b/main/.mintlify/skills/auth0/references/tooling-cli/index.md @@ -217,7 +217,7 @@ auth0 apps update --help | jq -r '.[0].flags[].name' | Custom login logic | `auth0 actions create --trigger post-login` | | Reusable code shared across actions | `auth0 actions modules create` + `--module` | | Multi-step self-service journeys | `auth0 forms` / `auth0 flows` | -| Branding the login page | `auth0 ul update --logo ... --accent ...` | +| Branding the login page | `auth0 ul update --logo ...` (colors on a tenant with a theme: see Universal Login — Branding) | | Custom domain for login | `auth0 domains create --domain "auth.myapp.com"` | | Debugging a failed login | `auth0 logs tail --filter "type:f"` | | Testing a login flow | `auth0 test login ` | @@ -309,6 +309,9 @@ auth0 connections enabled-clients update \ --data '[{"client_id":"","status":true}]' ``` +`enabled-clients update` changes only the clients in the payload and keeps the +status of every other client, so a single entry does not replace the existing list. + Strategies include `auth0` (database), `google-oauth2`, `samlp`, `oidc`, `waad`, `ad`, `oauth2`, and more. @@ -398,7 +401,7 @@ Alias: `auth0 mfa`. ```bash auth0 guardian policies set --policy all-applications # or: confidence-score, or --none auth0 guardian factors list -auth0 guardian factors set # enable/disable a factor +auth0 guardian factors set sms --enabled # enable/disable a factor (--enabled=false) auth0 guardian enrollments create-ticket --user-id "auth0|123" \ --factor push-notification --send-email ``` @@ -563,13 +566,24 @@ auth0 domains default set # pick the tenant's default custom d ### Universal Login — Branding ```bash -auth0 ul update --accent "#FF6600" --background "#FFFFFF" \ - --logo "https://myapp.com/logo.png" +auth0 ul update --logo "https://myapp.com/logo.png" \ + --favicon "https://myapp.com/favicon.ico" auth0 ul update --data @branding.json # or drive it with a JSON body ``` +`auth0 ul update` writes the tenant's classic branding settings (`/branding`: logo, favicon, +font, colors). On a tenant that has a theme, the theme sets the colors users see (Organization +branding can override them in an Organization context), with the button color in +`colors.primary_button`. Send color changes with a GET, merge and PATCH on +`branding/themes/` using `auth0 api`, carrying `displayName` and every top-level +section over (see the `feature-branding` reference). + +`auth0 ul prompts update -l --data '...'` sets a prompt's custom text +and replaces the existing text for that prompt, so read it first with +`auth0 ul prompts show -l ` and write the merged object back. + `auth0 ul update` and `auth0 ul prompts update` are non-interactive and take -`--data` / `--schema`. `auth0 ul customize` and `templates update` are +`--data`. `auth0 ul customize` and `templates update` are interactive editors that fail fast in agent mode (see agent-mode.md); for non-interactive advanced rendering (ACUL), use `auth0 acul config ...`. @@ -688,7 +702,7 @@ is already JSON so you rarely need them. There is **no `--csv`**. ```bash auth0 api get connections -auth0 api post client-grants --data '{"client_id":"...","audience":"...","scope":["read:data"]}' +auth0 api post "organizations//members" --data '{"members":[""]}' auth0 api get stats/daily -q "from=20240101" -q "to=20240131" auth0 api delete "actions/actions/" --force auth0 api post clients --data @client.json # @file @@ -699,6 +713,12 @@ cat data.json | auth0 api post clients # or pipe the body via stdin defaults to `GET` without data and `POST` with data. If a call returns 403, re-run `auth0 login --scopes ""`. +**Secrets.** To read or change a client, use `auth0 apps show ` or +`auth0 apps update `: they leave `client_secret` out unless you pass `--reveal-secrets`. +A raw `auth0 api` call on `clients/` returns the full client including the secret, +so pipe it through `jq` and keep only the fields you need, for example +`jq '{name, organization_usage}'`, to keep the secret out of your context. + **Paths are relative to the API root.** Write `connections`, not `/api/v2/connections`. The prefixed form returns a flat `404: Not Found` that reads like a missing resource.