# Palo Alto Cortex XDR Integration

Connect your Palo Alto Cortex XDR tenant to Capsule Security to inventory your managed endpoints and discover the AI coding agents and AI apps in use across them.

## Overview

This integration uses the Cortex XDR public API to sync:

- **Devices** - Endpoint inventory from the Endpoints API (hostnames, OS type and version, agent version, IP addresses, signed-in users, groups, last-seen time)
- **AI coding agents** - Claude Code, Cursor, GitHub Copilot, Codex, Gemini CLI, Windsurf, and similar developer agents detected from process-launch telemetry
- **AI apps** - Browser and web-app usage of AI services, detected from network and DNS telemetry


Device inventory comes from the synchronous Endpoints list. Shadow-AI detection comes from two XQL queries run over a rolling window that advances from a saved checkpoint. Capsule connects with a read-only API key and never installs software on endpoints or writes to your Cortex tenant.

## Prerequisites

Before you begin, ensure you have:

- An active **Cortex XDR Pro** deployment with endpoints reporting to the tenant
- Access to create an **API key** in the Cortex console (an instance administrator role)
- Your tenant-specific **API URL** (e.g. `https://api-acme.xdr.us.paloaltonetworks.com`)
- A **Capsule Security** account with admin access


> **Required - XQL query quota.** Runtime detection of AI agents and AI apps runs on XQL, which requires a **Cortex XDR Pro per Endpoint** or **Pro per TB** license and consumes your tenant's query quota. Capsule issues **12 XQL queries per day**, plus 14 on the first sync - see [Query volume](#query-volume) for the breakdown. If XQL is unavailable, the integration still installs and provides full device inventory - see [Feature availability](#feature-availability) below.


## Step 1: Create an API Key in the Cortex Console

Capsule authenticates to Cortex XDR with a long-lived API key and its key ID. Cortex XDR does not use OAuth - you generate the key once in the console and Capsule stores it encrypted. There is no automatic refresh, so key rotation is operator-managed.

### Steps

1. Sign in to your **Cortex console** at your tenant URL (e.g. `https://acme.xdr.us.paloaltonetworks.com`).
2. Navigate to **Settings → Configurations → Integrations → API Keys**.
3. Click **New Key**.
  - **Security Level**: Choose **Advanced** (recommended) or **Standard**. **This cannot be changed later** - note which one you picked, because Capsule asks for it during setup.
  - **Role**: Grant **Instance Administrator**, which is what the XQL APIs require.
  - **Comment**: Enter a descriptive name (e.g. `Capsule Security Integration`)
4. Generate the key and **copy it immediately**. Cortex shows the key only once; if you lose it you must generate a new one.
5. Note the **ID** shown next to the key in the API Keys table - this is the numeric **API Key ID** Capsule needs alongside the key itself.
6. Note your **API URL**. From the **API Keys** page, use **Copy URL** to get the exact address, or derive it from your console URL by prefixing the first label with `api-`: a console at `https://acme.xdr.us.paloaltonetworks.com` has an API URL of `https://api-acme.xdr.us.paloaltonetworks.com`. Capsule adds the `api-` prefix for you if you paste the console URL.


> **Reference:** Palo Alto's [Get Started with Cortex XDR APIs](https://docs-cortex.paloaltonetworks.com/r/Cortex-XDR/Cortex-XDR-API/Get-Started-with-Cortex-XDR-APIs) documents key creation for your console version.


### Standard vs Advanced security level

**Advanced** is the recommended level and Palo Alto's default. The key itself is never transmitted: each request carries a hash of the key combined with a random nonce and a timestamp, which the server recomputes. A captured request cannot be replayed.

**Standard** sends the key verbatim in the `Authorization` header on every request.

A key's level is fixed at creation. Capsule cannot detect which level a key uses - a standard key sent with advanced headers is simply rejected - so you must select the matching level during setup.

### Security notes

- Store the API key in a secrets manager. Cortex displays it only once at creation.
- Anyone holding the key and key ID can read your tenant data within the key's role. Treat both as secrets.
- If the key is ever exposed, **revoke it** in **Settings → Configurations → Integrations → API Keys** and generate a new one.
- Capsule stores the key encrypted at rest and uses it only to call the Cortex XDR public API over HTTPS.


## Step 2: Configure the Integration in Capsule

Once you have the **API URL**, **API Key ID**, **API Key** and **security level**, you can install the integration.

### Steps

1. Log in to the **Capsule Security** portal.
2. Click **Integrations** in the left sidebar.
3. Find the **Palo Alto Cortex XDR** card and click **Set up Integration**.
4. The setup form asks for four values:
  - **API URL** - your tenant API address (e.g. `https://api-acme.xdr.us.paloaltonetworks.com`). Must be a valid `https` URL.
  - **API Key ID** - the numeric ID shown next to the key in the console.
  - **API Key** - paste the key from Step 1.
  - **Security Level** - **Advanced** or **Standard**, matching how the key was created.
5. Capsule validates the credentials by making a read-only call against your tenant. A green **Connected to Cortex XDR** message confirms the key is accepted.
6. Click **Save**.


### After setup

- Initial sync begins automatically.
- The first sync walks a 7-day backlog in bounded windows, so it may take several runs to catch up on a busy tenant.
- View synced endpoints in **Inventory → Devices**.
- View detected AI coding agents and AI apps in **Discovery → Agents**, mapped back to the device and signed-in user they ran on.


Discovery runs on a recurring schedule to pick up new endpoints, decommissioned endpoints, and newly observed AI activity.

## Query Volume

Use these figures when sizing the integration against your XQL quota. They are per connected Cortex XDR tenant.

| Phase | XQL queries |
|  --- | --- |
| **Steady state** | **12 per day** - 2 per sync, 6 syncs a day |
| **First sync backfill** | **14** - 7 daily windows x 2, once |


- **Each sync runs exactly two queries** - one for process launches, one for network and DNS activity - regardless of how many endpoints you have or how many AI products Capsule looks for. Capsule aggregates inside the query rather than paging raw events, and it does not run a query per AI product.
- **Syncs run every 4 hours**, so a connected tenant issues 2 x 6 = **12 XQL queries per day**.
- **The first sync backfills 7 days** in 24-hour windows - 7 windows x 2 queries = **14 queries**, issued once. Subsequent syncs are back to 2.
- **A failed sync does not add to the total.** Capsule holds its checkpoint and replays the same window on the next sync rather than moving on, so a query that fails is retried, not accumulated.
- **Device inventory costs no XQL quota.** It uses the Endpoints API, which is metered separately.


If your quota is tight, contact support - the window size Capsule walks is configurable, and a larger window means fewer queries to cover the same period.

## Feature Availability

The integration runs with whatever your API key's role and your tenant's licensing allow. Use this matrix to understand what you'll see in Capsule.

| Capsule feature | Requires |
|  --- | --- |
| **Device inventory** (hostnames, OS, agent version, IPs, signed-in users) | API key with read access to endpoints |
| **AI coding-agent detection** (Claude Code, Cursor, Copilot, Codex, and others) | **XQL** available + remaining query quota |
| **AI app detection** (AI services used from the browser) | **XQL** available + remaining query quota |


### Without XQL

If your tenant does not license XQL - or a query fails, times out, or exhausts your quota during a sync - Capsule **downgrades gracefully**: device inventory still syncs in full, and the run completes without error. Capsule also holds its checkpoint, so the window that failed is retried on the next run rather than being skipped.

To enable AI discovery, work with your Palo Alto account team to confirm XQL entitlement and quota - no other reconfiguration is needed.

## Troubleshooting

### `Invalid Cortex XDR API key, key ID, or security level` / connection test fails with 401

- The key, key ID, or security level is wrong. All three must match: a key created as **Standard** fails if **Advanced** is selected, and vice versa.
- The key may have been revoked. Generate a fresh key in **Settings → Configurations → Integrations → API Keys** and re-enter all four values.
- Confirm the **API URL** points at the same tenant the key was issued from - keys are not portable across tenants.


### `Cortex XDR API key lacks the required permissions` (403)

- The key's role is too narrow. Re-issue the key with **Instance Administrator**, which is what the XQL APIs require.


### API URL rejected

- The **API URL** must be a valid `https` URL. `http`, bare hostnames, and non-URL values are rejected. Capsule strips any path or query string and adds the `api-` prefix if you paste a console URL.


### Devices appear but no AI agents or apps are discovered

- This is expected when **XQL** is unavailable or the tenant's query quota is exhausted - device inventory still syncs. See [Feature availability](#feature-availability).
- If XQL is available, confirm AI agents have actually launched, or AI apps have actually been reached, on managed endpoints within the window Capsule is currently processing. A tenant catching up on a backlog processes older windows first.


## Support

For help with this integration:

- **Email**: support@capsule.security
- **Include**: Your tenant ID, integration status, API URL, and any error messages from the Capsule portal


For Cortex XDR API key, role, or quota issues:

- **Cortex console**: **Settings → Configurations → Integrations → API Keys**
- **Reference**: [Get Started with Cortex XDR APIs](https://docs-cortex.paloaltonetworks.com/r/Cortex-XDR/Cortex-XDR-API/Get-Started-with-Cortex-XDR-APIs)