# Ada AI knowledge-base authentication

The three project-management skills (`project-binding`, `kb-summarize`,
`kb-retrieve`) talk to the Ada AI **knowledge base**, which lives entirely
under `/me/*`. The knowledge base now accepts **two** credentials, both owned
by the same user:

1. **An `sk-rc-…` API key** (`ADA_API_KEY`) — the same key you already use for
   `/v1/*` (model inference). This is the simplest path: no browser session,
   no refresh, nothing to expire. Recommended for CLI/agent use.
2. **A Stytch browser session** (`ADA_SESSION_JWT` + `ADA_STYTCH_SESSION_TOKEN`)
   — kept for callers that already export the dashboard cookies.

The OpenAI-compatible data plane (`/v1/*`) has always accepted the `sk-rc-…`
key; the knowledge base is the deliberate exception to the rest of `/me/*`,
which remains Stytch-session-only (invokers, usage, organization and key
management). Verified against `infra/backend/serving-api/proxy`:
`requireKBAuth` (in `auth_apikeys_handlers.go`) gates only the
`/me/projects*` and `/me/organizations/{id}/projects*` routes and accepts
either a user-scoped key (resolved to a user id, the same value `requireAuth`
would place in the context) or a Stytch JWT; `TestMeUsageRejectsNonSessionCredentials`
still pins `/me/usage` to session-only.

## What to export

### Option A — API key (recommended)

```sh
export ADA_API_KEY=sk-rc-…      # mint one at https://ada.ai/keys or via /login ada
```

That's it. The client sends `Authorization: Bearer <key>` with no refresh; a
401 means the key is invalid, revoked, or predates backend API-key support.

### Option B — browser session (cookies)

| Env var | What it is | Where it comes from | Lifetime |
|---|---|---|---|
| `ADA_SESSION_JWT` | Stytch **session JWT** | browser cookie `rb_session` (httpOnly) on `ada.ai` | short — refreshed from the session token |
| `ADA_STYTCH_SESSION_TOKEN` | Stytch **session token** | browser cookie `rb_stytch_session` on `ada.ai` | 7 days (`stytchSessionDurationMinutes` in `stytch_proxy.go`) |

`ADA_SESSION_JWT` is required for any call on this path. `ADA_STYTCH_SESSION_TOKEN`
is optional but **strongly recommended**: with it, the shared client
(`skills/lib/kb-client.mjs`) refreshes the JWT automatically on `401` via
`POST /auth/stytch/refresh`, so the skills stay usable for the full 7-day
session window. Without it, re-export `ADA_SESSION_JWT` whenever it expires.

### Shared (either option)

| Env var | What it is | Default |
|---|---|---|
| `ADA_API_BASE` | gateway base URL | `https://api.ada.ai` |
| `ADA_ORG_ID` | scope projects to an org | personal projects by default |

## How to get the cookie values (Option B)

1. Sign in at <https://ada.ai> in your browser.
2. Open devtools → **Application** (Chrome/Edge) or **Storage** (Firefox) →
   **Cookies** → `https://ada.ai`.
3. Copy the **Value** column for:
   - `rb_session` → `export ADA_SESSION_JWT='…'`
   - `rb_stytch_session` → `export ADA_STYTCH_SESSION_TOKEN='…'`
4. (Optional) To use an organization's knowledge base instead of your personal
   one, find the org id in the dashboard URL (`ada.ai/organizations/<id>`) and
   `export ADA_ORG_ID='<id>'`. You must be a member; admins can write,
   members can read.

Put the exports in your shell profile (e.g. `~/.zshrc`) so every pi session
inherits them. **Treat all three values like passwords** — the session token
is a 7-day login. Never write them to files you commit. Sign out
(`ada.ai` → sign out, which calls `/auth/stytch/revoke`) to invalidate the
session cookies; revoke an API key from the **Keys** page at
[ada.ai/keys](https://ada.ai/keys).

## Verifying it works

```sh
node ./skills/kb-retrieve/scripts/list-docs.mjs
```

A successful project/document list means the credentials are wired up. A
`401 … API key` (Option A) or `401 … Stytch session JWT` (Option B) message
points at the env var to fix.
