@coder/ai-sdk-provider 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +127 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -115,6 +115,133 @@ createCoder({
115
115
  | `providers` | `{ openai?, anthropic? }` | `openai` / `anthropic` | Override the admin-configured provider path segments. |
116
116
  | `fetch` | `typeof fetch` | global `fetch` | Custom fetch (testing / middleware). |
117
117
 
118
+ ## Enterprise governance & security
119
+
120
+ Reference for security reviewers evaluating this package. The boundary between
121
+ the two kinds of claims below matters: **client behavior** (what this package
122
+ puts on the wire) is verifiable in [`src/provider.ts`](./src/provider.ts) —
123
+ ~175 lines with no dependencies beyond the official AI SDK provider packages —
124
+ while **gateway behavior** (key custody, audit capture, retention) is a
125
+ property of your Coder deployment, enforced server-side regardless of what any
126
+ client does, and documented in the
127
+ [AI Gateway docs](https://coder.com/docs/ai-coder/ai-gateway).
128
+
129
+ ### Data flow
130
+
131
+ ```text
132
+ your app ──HTTP(S)──▶ your Coder deployment ──▶ upstream provider
133
+ (this package) (AI Gateway intercepts (Anthropic, OpenAI,
134
+ /api/v2/aibridge/…) Bedrock, Copilot, …)
135
+ ```
136
+
137
+ **What leaves your app.** This package's only network destination is the
138
+ `baseURL` you configure. It never contacts upstream vendors directly and adds
139
+ no telemetry of its own; each request is exactly what the AI SDK builds for a
140
+ normal provider call:
141
+
142
+ - **URL** — `POST <baseURL>/api/v2/aibridge/<provider>/v1/chat/completions`
143
+ (OpenAI surface; `…/v1/embeddings` for `textEmbeddingModel`) or
144
+ `…/v1/messages` (Anthropic surface). `/api/v2/aibridge` is this package's
145
+ default; deployments also serve the post-rename alias `/api/v2/ai-gateway`
146
+ (see `aiGatewayPath`).
147
+ - **Auth headers** — per the mode matrix below.
148
+ - **Body** — standard OpenAI-/Anthropic-format JSON: the model id (passed
149
+ through unchanged), your full prompt/message content, tool definitions, and
150
+ sampling parameters. Prompt content is visible to the Gateway — that is what
151
+ enables auditing.
152
+ - Anything you add via the `headers` option.
153
+
154
+ Transport security follows the scheme of your `baseURL` — the client does not
155
+ enforce `https://` (an `http://` URL sends tokens, keys, and prompts in
156
+ plaintext). Always use an HTTPS deployment URL outside trusted local
157
+ environments.
158
+
159
+ **What the Gateway does before forwarding** _(server-side —
160
+ [authentication docs](https://coder.com/docs/ai-coder/ai-gateway/auth))_: it
161
+ authenticates the token as an active Coder user and rejects the request
162
+ outright when it is missing or invalid (nothing is forwarded upstream), strips
163
+ all Coder credentials from the outbound request, and attaches the upstream
164
+ credential for the mode in use.
165
+
166
+ ### Credential isolation: centralized vs. BYOK
167
+
168
+ | | **Centralized (default)** | **BYOK** |
169
+ | ------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
170
+ | Your app holds | Coder API token only | Coder API token **+** the user's own upstream key |
171
+ | On the wire | `Authorization: Bearer <Coder token>` (both surfaces) | `X-Coder-AI-Governance-Token: <Coder token>`; upstream key in `Authorization: Bearer` (OpenAI surface) / `x-api-key` (Anthropic surface) |
172
+ | Upstream provider keys live | On the deployment, admin-configured — never distributed to developers | With the individual user; forwarded per request, bypassing the deployment's central key pool |
173
+ | Coder token forwarded upstream? | **No** — stripped and replaced by the deployment's provider key | **No** — the governance header is stripped before forwarding |
174
+ | Admin control | Provider and key configuration, rotation, failover | Can be disabled deployment-wide (`CODER_AI_GATEWAY_ALLOW_BYOK=false` rejects requests carrying the governance header with `403`) |
175
+
176
+ Both modes are audited identically: audit records store _which credential
177
+ kind_ was used (`centralized` / `byok`), not the credential itself.
178
+
179
+ ### Audit capture
180
+
181
+ Every request is attributed to the Coder user whose token authenticated it —
182
+ per user, per request, in both modes. Per intercepted request the Gateway
183
+ records _(server-side —
184
+ [audit docs](https://coder.com/docs/ai-coder/ai-gateway/audit))_:
185
+
186
+ - **Identity & metadata** — initiating user, provider, model, client,
187
+ credential kind, timestamps.
188
+ - **Last user prompt** — earlier turns and system prompts are not stored.
189
+ - **Token usage** — input / output / cache counts.
190
+ - **Tool calls** — tool name and arguments; tool _results_ are not stored.
191
+ - **Model reasoning** — extended-thinking / reasoning-summary content when
192
+ present.
193
+
194
+ Model-generated response text is **discarded**, not stored. Retention defaults
195
+ to **60 days** and is configurable (`CODER_AI_GATEWAY_RETENTION`; `0` keeps
196
+ data indefinitely). Auditors browse sessions and causal tool-call chains in
197
+ the deployment dashboard under `/ai-gateway/sessions`.
198
+
199
+ ### Required Coder permissions
200
+
201
+ | To… | You need |
202
+ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
203
+ | Send requests through the Gateway | An active Coder user with a valid API token — no extra role. (RBAC: members hold create/update on `aibridge_interception`, i.e. recording their own traffic.) |
204
+ | Read audit data (prompts, tool calls, usage) | The **Owner** or **Auditor** role. Regular members cannot read interceptions back — not even their own. |
205
+ | Configure providers / keys, toggle BYOK | Deployment administrator (server flags / deployment configuration). |
206
+ | Use the feature at all | A deployment licensed for [AI Governance](https://coder.com/docs/ai-coder/ai-governance) — the Gateway is license-gated server-side. |
207
+
208
+ ### Security FAQ
209
+
210
+ - **Does prompt data ever go anywhere other than my deployment?** This package
211
+ only ever _initiates_ requests to `baseURL`; onward traffic to the upstream
212
+ vendor originates from your deployment (or its standalone gateway replicas),
213
+ using the providers your admins configured. One standard-`fetch` caveat:
214
+ redirects are followed by default, so a cross-origin redirect issued by your
215
+ deployment or an intermediary would resend the request — prompt body and
216
+ non-`Authorization` headers (in BYOK mode that includes `x-api-key` and the
217
+ governance token) — to the redirect target. To forbid this, supply a custom
218
+ fetch: `fetch: (url, init) => fetch(url, { ...init, redirect: "error" })`.
219
+ - **Do developers ever handle raw provider keys?** Centralized mode: no —
220
+ developers only ever hold a Coder token. BYOK mode: they supply their own
221
+ personal key, which is forwarded per request without entering central custody.
222
+ - **What is the blast radius of a leaked Coder token?** A Coder API token is
223
+ not an AI-only credential — it grants the bearer the user's **full Coder API
224
+ permissions** (workspaces, templates, and anything else that user's roles
225
+ allow), and, until revoked or expired, AI usage through your Gateway (fully
226
+ attributed to that user). What it can _not_ do is authenticate to upstream
227
+ vendors: under normal Gateway forwarding it is stripped and does not leave
228
+ your deployment (the cross-origin-redirect caveat above is the exception —
229
+ a redirect can resend non-`Authorization` headers, including the governance
230
+ header, before the Gateway ever sees them). Treat a leak as a Coder account
231
+ compromise — revoke the token — and prefer short-lived, dedicated tokens
232
+ for AI workloads.
233
+ - **Is model-generated content stored?** Partially. Assistant _response text_
234
+ is discarded, but two model-generated artifacts are retained for auditing:
235
+ reasoning content (extended thinking / reasoning summaries) and tool-call
236
+ arguments — alongside the last user prompt and token counts.
237
+ - **Can I verify the client claims myself?** Yes: [`src/provider.ts`](./src/provider.ts)
238
+ is the entire wire-facing surface — it only selects base URLs and auth
239
+ headers, then delegates request construction to the official AI SDK provider
240
+ packages. [`test/provider.test.ts`](./test/provider.test.ts) asserts the
241
+ request URL, auth headers, and model pass-through for the chat/messages
242
+ routes in both auth modes; the underlying AI SDK packages add their own
243
+ protocol headers (e.g. `anthropic-version`) and are not re-tested here.
244
+
118
245
  ## Examples
119
246
 
120
247
  Runnable scripts live in [`examples/`](./examples) (run against a real deployment via `tsx`):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coder/ai-sdk-provider",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Vercel AI SDK provider for Coder AI Gateway. Point the AI SDK at your Coder deployment with a Coder API token and use any model your deployment proxies — across AI Gateway's OpenAI- and Anthropic-compatible surfaces.",
5
5
  "keywords": [
6
6
  "ai",