> For the complete documentation index, see [llms.txt](https://cortex-docs.paloaltonetworks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cortex-docs.paloaltonetworks.com/xdr-5-api/broker-vm-on-appliance/auth-bootstrap.md).

# Auth (bootstrap)

Two-step bootstrap on first connection — reset the factory password, then obtain a short-lived Bearer token used by every other endpoint in this spec. These two endpoints carry no Bearer themselves and are rate-limited at 5/min/IP.

{% hint style="info" %}
The on-appliance Broker API is available on Broker VM version 32 and later. Ubuntu-based brokers do not support this API.
{% endhint %}

## Replace the factory-default admin password

> Replace the broker's factory-default admin password with one of\
> the operator's choosing. This is the \*\*first\*\* call that must\
> succeed against a freshly-provisioned broker — every other\
> endpoint (including \[\`generateToken\`]\(#operation/generateToken))\
> is blocked by \`InitialPasswordGateMiddleware\` until this returns\
> \`200\`.\
> \
> \- \*\*Authentication:\*\* the factory default password is the\
> &#x20; credential. No Bearer token is required.\
> \- \*\*Rate limit:\*\* 5 requests per minute per source IP.\
> \- \*\*Idempotency:\*\* \*\*not idempotent\*\* — the second call with the\
> &#x20; factory password returns \`403\`\
> &#x20; (\`PasswordAlreadyReset\`) because the password is no longer\
> &#x20; the factory default.\
> \- \*\*Password policy:\*\* structural minimum is one character;\
> &#x20; Django's \`AUTH\_PASSWORD\_VALIDATORS\` enforce strength rules\
> &#x20; and emit \`400\` with the full validator error chain.<br>

```json
{"openapi":"3.0.3","info":{"title":"Cortex Broker Direct Public API (on-appliance)","version":"1.0.0"},"tags":[{"name":"auth","description":"Two-step bootstrap on first connection — reset the factory password,\nthen obtain a short-lived Bearer token used by every other endpoint\nin this spec. These two endpoints carry no Bearer themselves and are\nrate-limited at 5/min/IP.\n\n{% hint style=\"info\" %}\nThe on-appliance Broker API is available on Broker VM version 32 and later. Ubuntu-based brokers do not support this API.\n{% endhint %}\n"}],"servers":[{"url":"https://{broker_host}","description":"The broker appliance's on-board HTTPS listener.","variables":{"broker_host":{"default":"broker.example.local","description":"Operator-chosen hostname or IP of the Broker VM appliance.\nReplace with your broker's actual address.\n"}}}],"security":[],"paths":{"/public_api/v1/auth/reset-initial-password":{"post":{"tags":["auth"],"operationId":"resetInitialPassword","summary":"Replace the factory-default admin password","description":"Replace the broker's factory-default admin password with one of\nthe operator's choosing. This is the **first** call that must\nsucceed against a freshly-provisioned broker — every other\nendpoint (including [`generateToken`](#operation/generateToken))\nis blocked by `InitialPasswordGateMiddleware` until this returns\n`200`.\n\n- **Authentication:** the factory default password is the\n  credential. No Bearer token is required.\n- **Rate limit:** 5 requests per minute per source IP.\n- **Idempotency:** **not idempotent** — the second call with the\n  factory password returns `403`\n  (`PasswordAlreadyReset`) because the password is no longer\n  the factory default.\n- **Password policy:** structural minimum is one character;\n  Django's `AUTH_PASSWORD_VALIDATORS` enforce strength rules\n  and emit `400` with the full validator error chain.\n","requestBody":{"required":true,"description":"Carries the factory `current_password` and the new admin `new_password`.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetInitialPasswordRequest"}}}},"responses":{"200":{"description":"Password successfully replaced. Proceed to [`generateToken`](#operation/generateToken).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiSuccessResponse"}}}},"400":{"description":"Request body failed Pydantic validation, or the proposed new\npassword failed Django's password validators.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"401":{"description":"`current_password` does not match the stored factory password.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"Initial password has already been reset on this broker.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"schemas":{"ResetInitialPasswordRequest":{"description":"Body for `resetInitialPassword`. The `current_password` must match the factory default; the `new_password` is validated against Django's password policy server-side.\n","type":"object","required":["current_password","new_password"],"properties":{"current_password":{"type":"string","format":"password","minLength":1,"description":"The factory-default admin password."},"new_password":{"type":"string","format":"password","minLength":1,"description":"New admin password. Structural minimum is one character;\nDjango's `AUTH_PASSWORD_VALIDATORS` enforce real strength\nrules and surface their failures as `400`.\n"}}},"PublicApiSuccessResponse":{"type":"object","description":"Canonical envelope for every successful (`2xx`) JSON response.\nWraps the per-endpoint payload (or `null` when the operation\ncarries no body content).\n","properties":{"reply":{"nullable":true,"description":"Endpoint-specific payload. Schema varies; see each\noperation's `200.content.schema`.\n"}}},"PublicApiErrorResponse":{"type":"object","description":"Canonical envelope for every error (`4xx`/`5xx`) JSON response.\n","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message. Pydantic validation failures\nare rendered as `\"<field>: <message>; <field>: <message>; ...\"`\n(semicolon-separated) by `format_pydantic_errors`.\n"},"reply":{"nullable":true,"description":"Always `null` on error responses. Present in the envelope to\nkeep the JSON shape consistent with success responses.\n"}}}},"responses":{"RateLimited":{"description":"Caller exceeded the per-IP rate limit on this endpoint (5/min\non the two bootstrap endpoints, 1/sec on the six network\nendpoints).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}}}}}
```

## Obtain a 10-minute Bearer token

> Authenticate with the admin password and receive a short-lived\
> opaque API token (TTL \*\*10 minutes\*\*) used to call every other\
> endpoint in this spec. The token is returned \*\*once\*\* — store it\
> immediately.\
> \
> \- \*\*Authentication:\*\* the password in the body is the credential;\
> &#x20; no Bearer required.\
> \- \*\*Rate limit:\*\* 5 requests per minute per source IP.\
> \- \*\*Gating:\*\* requires \[\`resetInitialPassword\`]\(#operation/resetInitialPassword)\
> &#x20; to have already succeeded (otherwise \`403\`).\
> \- \*\*Token lifetime:\*\* 10 minutes from issuance, not from last\
> &#x20; use. To renew, call this endpoint again.<br>

```json
{"openapi":"3.0.3","info":{"title":"Cortex Broker Direct Public API (on-appliance)","version":"1.0.0"},"tags":[{"name":"auth","description":"Two-step bootstrap on first connection — reset the factory password,\nthen obtain a short-lived Bearer token used by every other endpoint\nin this spec. These two endpoints carry no Bearer themselves and are\nrate-limited at 5/min/IP.\n\n{% hint style=\"info\" %}\nThe on-appliance Broker API is available on Broker VM version 32 and later. Ubuntu-based brokers do not support this API.\n{% endhint %}\n"}],"servers":[{"url":"https://{broker_host}","description":"The broker appliance's on-board HTTPS listener.","variables":{"broker_host":{"default":"broker.example.local","description":"Operator-chosen hostname or IP of the Broker VM appliance.\nReplace with your broker's actual address.\n"}}}],"security":[],"paths":{"/public_api/v1/auth/token":{"post":{"tags":["auth"],"operationId":"generateToken","summary":"Obtain a 10-minute Bearer token","description":"Authenticate with the admin password and receive a short-lived\nopaque API token (TTL **10 minutes**) used to call every other\nendpoint in this spec. The token is returned **once** — store it\nimmediately.\n\n- **Authentication:** the password in the body is the credential;\n  no Bearer required.\n- **Rate limit:** 5 requests per minute per source IP.\n- **Gating:** requires [`resetInitialPassword`](#operation/resetInitialPassword)\n  to have already succeeded (otherwise `403`).\n- **Token lifetime:** 10 minutes from issuance, not from last\n  use. To renew, call this endpoint again.\n","requestBody":{"required":true,"description":"Carries the admin `password` (set via `resetInitialPassword`) used to mint a 10-minute Bearer token.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateTokenRequest"}}}},"responses":{"200":{"description":"Token issued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateTokenSuccessResponse"}}}},"400":{"description":"Pydantic validation failure (missing or empty `password`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"401":{"description":"Authentication failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"403":{"description":"Either the initial password has not been reset (call\n[`resetInitialPassword`](#operation/resetInitialPassword) first),\nor the supplied password is still the factory default.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"schemas":{"GenerateTokenRequest":{"description":"Body for `generateToken`. The `password` is the current admin password (post-reset).\n","type":"object","required":["password"],"properties":{"password":{"type":"string","format":"password","minLength":1,"description":"Current admin password (set via [`resetInitialPassword`](#operation/resetInitialPassword))."}}},"GenerateTokenSuccessResponse":{"type":"object","description":"Success envelope for [`generateToken`](#operation/generateToken).","properties":{"reply":{"$ref":"#/components/schemas/GenerateTokenReply"}}},"GenerateTokenReply":{"description":"Payload of the `generateToken` success response. The `api_key` is returned exactly once.\n","type":"object","required":["api_key"],"properties":{"api_key":{"type":"string","description":"Opaque short-lived (10-minute TTL) Bearer token. **Returned\nonce** — store it immediately.\n"}}},"PublicApiErrorResponse":{"type":"object","description":"Canonical envelope for every error (`4xx`/`5xx`) JSON response.\n","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message. Pydantic validation failures\nare rendered as `\"<field>: <message>; <field>: <message>; ...\"`\n(semicolon-separated) by `format_pydantic_errors`.\n"},"reply":{"nullable":true,"description":"Always `null` on error responses. Present in the envelope to\nkeep the JSON shape consistent with success responses.\n"}}}},"responses":{"RateLimited":{"description":"Caller exceeded the per-IP rate limit on this endpoint (5/min\non the two bootstrap endpoints, 1/sec on the six network\nendpoints).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiErrorResponse"}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://cortex-docs.paloaltonetworks.com/xdr-5-api/broker-vm-on-appliance/auth-bootstrap.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
