# Agent Identity Lifecycle

Last updated: January 2026

This doc describes how agent identities (OAuth-based) are created, connected, refreshed, and revoked. For route reference see [API.md](API.md) and [API_ENTRY_POINTS.md](API_ENTRY_POINTS.md).

---

## Overview

- **Identity** = one OAuth connection per agent per provider (e.g. Google, Microsoft). Used so an agent can act as a user (e.g. read calendar, send email).
- **Flow:** Create identity → connect (user completes OAuth in browser) → callback exchanges code for tokens → tokens stored encrypted. **Refresh** before expiry; **revoke** to disconnect.

---

## 1. Create identity

**POST** `/api/agents/:id/identity`

Body: `{ "provider": "google" | "microsoft", "emailAlias?: string", "scopes?: string[]" }`

Creates a record; status is inactive until connect completes.

---

## 2. Connect (start OAuth)

**POST** `/api/agents/:id/identity/:identityId/auth/connect`

Returns `{ "connectUrl": "https://..." }`. Redirect the user (or open in a new tab) to `connectUrl`. The user signs in with the provider; the provider redirects back to your **callback URL**.

---

## 3. Callback URL (redirect URI)

The backend must be reachable at this URL for the OAuth redirect:

```
{BACKEND_BASE}/api/agents/auth/callback/{provider}
```

- **provider** = `google` or `microsoft`.
- **BACKEND_BASE** = backend root URL. Set via:
  - **AGENT_IDENTITY_OAUTH_BASE_URL** (backend env), or
  - **NEXT_PUBLIC_API_URL** (if frontend and backend share the same origin in your setup), or
  - default from request host when not set.

**Configure in the OAuth provider console:**

- **Google:** APIs & Services → Credentials → your OAuth 2.0 Client → Authorized redirect URIs → add `https://your-backend.netlify.app/api/agents/auth/callback/google` (or your backend URL).
- **Microsoft:** App registration → Authentication → Redirect URIs → add `https://your-backend.netlify.app/api/agents/auth/callback/microsoft`.

After the user completes OAuth, the callback exchanges the code for access and refresh tokens, stores them encrypted, and returns a success page (“You can close this tab”).

---

## 4. Refresh tokens

**POST** `/api/agents/:id/identity/:identityId/auth/refresh`

Uses the stored `refresh_token` to get a new access token (and optionally a new refresh token). Call this when the access token is expired or near expiry, or on a schedule.

- **Auth:** `X-User-Email` or Bearer (session).
- **Response:** `{ "ok": true, "identity": { ... } }`.

If the refresh fails (e.g. token revoked at provider), the identity may need to be reconnected (user goes through connect again).

---

## 5. Revoke

**POST** `/api/agents/:id/identity/:identityId/revoke`

Clears stored tokens and marks the identity as revoked/inactive. The user can create a new identity or connect again later.

- Does not necessarily call the provider’s revoke endpoint; it’s a local disconnect. For full revocation at the provider, that may be added in a future release.

---

## 6. Health and reconnect

**GET** `/api/agents/:id/identity/health`

Returns health status (e.g. stale if not used for a long time, or token expired). Use this to show “Reconnect” in the UI when the identity is unhealthy.

**Recovery:** If refresh fails or health is bad, direct the user to connect again (same connect URL flow). No need to delete the identity first; connect overwrites the stored tokens.

---

## 7. Audits

**GET** `/api/agents/:id/identity/audits?identityId=...&limit=...`

Lists audit events for the identity (e.g. `auth_callback`, `auth_refresh`, `revoke`). Useful for debugging and compliance.

---

## Env (backend)

| Variable | Purpose |
|----------|---------|
| **GOOGLE_CLIENT_ID** / **GOOGLE_CLIENT_SECRET** | Google OAuth for agent identity. |
| **MICROSOFT_CLIENT_ID** / **MICROSOFT_CLIENT_SECRET** | Microsoft OAuth for agent identity. |
| **AGENT_IDENTITY_OAUTH_BASE_URL** | Base URL for OAuth redirect (callback). Defaults to request host if unset. |

Ensure the callback URL derived from this base is registered in each provider’s console.
