
You replace the personal access token (PAT) ADO Pilot uses by minting a new one in Azure DevOps and pasting it into the **Integration** settings page in your dashboard. There are two times you do this: on a 90-day schedule, and immediately after any suspected compromise.

## When to rotate

### Scheduled rotation (every 90 days)

Azure DevOps PATs expire on a fixed date. We recommend a 90-day expiration window — short enough to limit blast radius, long enough that rotation is a quarterly task instead of a weekly one. Plan to rotate before the existing token expires; if it lapses, reviews stop firing until you replace it.

### Emergency rotation (rotate now)

Rotate immediately if any of these happen:

- The token string was pasted somewhere it shouldn't be — chat, email, a screenshot, an unencrypted note, a public log.
- A laptop or password vault that held the token was lost or compromised.
- The user who created the token has left your organization or had their access revoked.
- You discover the existing token has scopes broader than the three ADO Pilot needs (for example, **Full access**).
- Your security team flags any incident that touches the workstation where the token was created.

When you rotate for an emergency, mint the new PAT first, save it in ADO Pilot, then revoke the old one in Azure DevOps. That sequence avoids a coverage gap.

## Required scopes for the new token

The replacement PAT needs the same scopes as the original. There are no additional scopes for rotation:

ADO Pilot needs the following Azure DevOps personal access token (PAT) scopes. Pick exactly these — do **not** grant **Full access**.

| Scope                    | Permission level | Why ADO Pilot needs it                                                                                                                                                      |
| ------------------------ | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Code**                 | Read             | Read pull request diffs and file contents; creates service hook subscriptions (inherited automatically — you will not see a separate "Service Hooks" option in the ADO UI). |
| **Code**                 | Status           | Post status checks on pull requests (the AI PR Review badge).                                                                                                               |
| **Pull Request Threads** | Read & write     | Post inline review comments on the PR.                                                                                                                                      |

ADO Pilot's onboarding wizard validates the **Code (Read)** scope at connection time for any organization with at least one Azure DevOps project (any organization you'd actually connect will have one), and the **Pull Request Threads** scope too whenever it has a pull request to test against: always true if you pasted a PR URL, and true for **Skip for now** only if the first project and repository the wizard checks already has an existing pull request (otherwise this check is deferred). The **Code (Status)** scope is not checked until ADO Pilot posts your first review's status check. A PAT missing any of the three scopes will fail at connection time (if checked there) or otherwise at first review, with a scope error — re-create the token with all three scopes selected if you see one.

{% callout type="tip" title="Least privilege" %}
These three scopes are the smallest set that lets ADO Pilot post reviews. Notably, this does **not** include Code (Write) — ADO Pilot never pushes code changes. Anything broader (for example, **Full access** or **Code (Read & Write)**) gives the token rights ADO Pilot does not use.
{% /callout %}

{% callout type="note" title="Where is Service Hooks?" %}
"Service Hooks" does not appear as a selectable scope in the Azure DevOps PAT creation UI. Microsoft removed it from the public scope list. It is automatically granted to any token that has **Code (Read)**, so you do not need to add it.
{% /callout %}

## How to rotate

Rotating the PAT is an org-admin action. If you don't see a **Rotate PAT** button on the Integration settings page, ask an ADO Pilot admin for your organization to do it instead.

### Step 1 — Create a new PAT in Azure DevOps

Follow [Creating a Personal Access Token](./creating-a-pat.md) to mint a fresh token with all required scopes and a 90-day expiration. Copy the token string the moment Azure DevOps shows it — you only get one chance.

### Step 2 — Open the Integration settings page

In the ADO Pilot dashboard, go to **Settings** then **Integration**. The **Personal Access Token** card shows the existing token's expiration date and remaining days.

### Step 3 — Paste the new token

{% callout type="info" title="After saving, confirm reviews still fire" %}
After you save the new token, confirm a review runs on your next PR push. If the connection looks off, see [Connection status shows "Unknown"](../troubleshooting/integration-status-unknown.md).
{% /callout %}

1. Click **Rotate PAT**.
2. In the dialog, paste the new token into the **New PAT** field.
3. Click **Save token**.

If you have not signed in recently, ADO Pilot may ask you to re-confirm your identity before saving — this step-up prompt is expected for credential changes.

The dialog notes that **the old token is replaced atomically** — ADO Pilot starts using the new token for its next outbound call. The old PAT is NOT revoked in Azure DevOps automatically; it remains valid in Azure DevOps until its original expiry date or until you manually revoke it (see Step 5). If you want to prevent the old token from being used elsewhere, you must revoke it yourself.

### Step 4 — Confirm the connection is healthy

The Integration page should now show:

- The connection status indicator green.
- Service hook subscriptions re-provisioned and reconciled against Azure DevOps.

Push a small commit to a test branch and open a draft PR to confirm a review fires. If it does not, see [PAT scope errors](../troubleshooting/pat-scope-errors.md) and [Connection status shows "Unknown"](../troubleshooting/integration-status-unknown.md).

### Step 5 — Revoke the old token in Azure DevOps

Go to **User Settings → Personal access tokens** in Azure DevOps, find the previous token by name, and click **Revoke**. Skipping this step is the most common rotation mistake — the old token remains valid until its original expiry date, which defeats the point of rotating after a compromise.

## What stays the same after rotation

- Repository configuration (which repos are reviewed, exclusion patterns, severity thresholds).
- Review history, comments, and status checks already posted on existing PRs.
- Your plan, billing, team membership, and review credit balance.

## What changes

- The stored PAT credential, encrypted at rest in our backend.
- Outbound calls from ADO Pilot to Azure DevOps now sign with the new token.
- Service hook subscriptions in Azure DevOps are re-provisioned and reconciled automatically. They authenticate to ADO Pilot through a separate, per-tenant credential that PAT rotation doesn't touch.

## Troubleshooting rotation

- **Save fails with a scope or token error.** ADO Pilot validates the new token against your Azure DevOps org before saving it, so an invalid token or one missing Code (Read) access is rejected in the dialog rather than saved. A token missing Code (Status) or Pull Request Threads instead passes this check and saves successfully, then fails later when ADO Pilot tries to post a status check or comment — see "Reviews stop firing after rotation" below. Re-check the scopes against [Required PAT scopes](./creating-a-pat.md#required-scopes) and try again.
- **Connection status still shows "Unknown" after a successful save.** ADO Pilot hasn't recorded a fresh health check yet — this isn't caused by the new token itself. See [Connection status shows "Unknown"](../troubleshooting/integration-status-unknown.md).
- **Reviews stop firing after rotation.** If the new token is missing Code (Status) or Pull Request Threads scope, or the service hook update did not propagate cleanly, see [Webhook 401s and reviews stopped firing](../troubleshooting/webhook-401.md).
- **You forgot to copy the new token before closing the Azure DevOps dialog.** The token cannot be recovered. Revoke the half-created token in Azure DevOps and start over.


