{"_id":"@conveo/conveo-sdk","_rev":"4-709a9cc06fde97f80245e1c17ee2dc62","name":"@conveo/conveo-sdk","dist-tags":{"latest":"0.4.1"},"versions":{"0.3.0":{"name":"@conveo/conveo-sdk","version":"0.3.0","license":"UNLICENSED","_id":"@conveo/conveo-sdk@0.3.0","maintainers":[{"name":"boris_conveo","email":"boris@conveo.ai"}],"homepage":"https://github.com/conveo/conveo-sdk#readme","bugs":{"url":"https://github.com/conveo/conveo-sdk/issues"},"bin":{"agentgateway-dev-token":"dist/dev/token.js"},"dist":{"shasum":"d06dd5aa6e0ebe66104304d8ebafd68f673a8572","tarball":"https://registry.npmjs.org/@conveo/conveo-sdk/-/conveo-sdk-0.3.0.tgz","fileCount":25,"integrity":"sha512-rvZWAl6LCsztPoKySWQ+VXVu2IAg8nL9dChLLuOzhJGq0xzrTEMO/U4TZysyD6bNIjlRnAyIhbMtN8d2/YbvrQ==","signatures":[{"sig":"MEYCIQDHkavXnNBKkhLKcOUMTYhRiTtpT2di3xwY1CiSiHPrBAIhAK9xlyfilZKG318ecFPi69zFdDZo+jSBGNRrwQAjIW3C","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61685},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./next":{"types":"./dist/adapters/next.d.ts","default":"./dist/adapters/next.js"},"./server":{"types":"./dist/server.d.ts","default":"./dist/server.js"},"./vercel":{"types":"./dist/adapters/vercel.d.ts","default":"./dist/adapters/vercel.js"},"./supabase":{"types":"./dist/adapters/supabase.d.ts","default":"./dist/adapters/supabase.js"}},"gitHead":"7a27017c29f14b19ba444299a6a2b148194ca09b","scripts":{"dev":"tsc -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest run","build":"tsc -p tsconfig.build.json && pnpm minify && pnpm build:deno","minify":"node scripts/minify.mjs","typecheck":"tsc -p tsconfig.json --noEmit","build:deno":"esbuild src/adapters/supabase.ts --bundle --minify --format=esm --platform=browser --target=es2022 --outfile=dist/deno/agentgateway-supabase.bundle.js"},"_npmUser":{"name":"boris_conveo","email":"boris@conveo.ai"},"repository":{"url":"git+https://github.com/conveo/conveo-sdk.git","type":"git"},"_npmVersion":"11.8.0","description":"SDK for Conveo apps behind the agent gateway: drop-in auth middleware (Next.js / Vercel / Supabase), server helpers, and a dev-token CLI.","directories":{},"_nodeVersion":"22.22.0","dependencies":{"jose":"^6.2.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.5.3","devDependencies":{"next":"^16.2.9","vitest":"^4.1.8","esbuild":"^0.28.1","typescript":"^5.9.3","@types/node":"^24.0.0","@vercel/functions":"^3.7.1"},"peerDependencies":{"next":">=14","@vercel/functions":">=2"},"peerDependenciesMeta":{"next":{"optional":true},"@vercel/functions":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/conveo-sdk_0.3.0_1781706885240_0.9082287320181599","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@conveo/conveo-sdk","version":"0.3.1","license":"UNLICENSED","_id":"@conveo/conveo-sdk@0.3.1","maintainers":[{"name":"boris_conveo","email":"boris@conveo.ai"}],"homepage":"https://github.com/conveo/conveo-sdk#readme","bugs":{"url":"https://github.com/conveo/conveo-sdk/issues"},"bin":{"agentgateway-dev-token":"dist/dev/token.js"},"dist":{"shasum":"b397f4a469d20ed6fffbbdd61935077a1d40ef11","tarball":"https://registry.npmjs.org/@conveo/conveo-sdk/-/conveo-sdk-0.3.1.tgz","fileCount":25,"integrity":"sha512-nRGZZJTIMZFh9T6KIgj1k+uMqB6iT1tyGhU/TXoD7T2shNskN+L+FDeYYinibqEeJOnU+MxWY9BxncH7UL47jQ==","signatures":[{"sig":"MEUCIAbH/vQL4qZ91dMu38Tt150mnDX7QG6V/f/jsyaSZ8oyAiEA7TnUvjk1cSWgzhYmX4PKgLASqCIhRZqXRni4baV8Moo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61683},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./next":{"types":"./dist/adapters/next.d.ts","default":"./dist/adapters/next.js"},"./server":{"types":"./dist/server.d.ts","default":"./dist/server.js"},"./vercel":{"types":"./dist/adapters/vercel.d.ts","default":"./dist/adapters/vercel.js"},"./supabase":{"types":"./dist/adapters/supabase.d.ts","default":"./dist/adapters/supabase.js"}},"gitHead":"63b65a54d8400eaf481206d842da7a9e18c4a9ce","scripts":{"dev":"tsc -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest run","build":"tsc -p tsconfig.build.json && pnpm minify && pnpm build:deno","minify":"node scripts/minify.mjs","typecheck":"tsc -p tsconfig.json --noEmit","build:deno":"esbuild src/adapters/supabase.ts --bundle --minify --format=esm --platform=browser --target=es2022 --outfile=dist/deno/agentgateway-supabase.bundle.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8759f550-a079-428a-8f1a-ee8be5063240"}},"repository":{"url":"git+https://github.com/conveo/conveo-sdk.git","type":"git"},"_npmVersion":"11.17.0","description":"SDK for Conveo apps behind the agent gateway: drop-in auth middleware (Next.js / Vercel / Supabase), server helpers, and a dev-token CLI.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jose":"^6.2.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.5.3","devDependencies":{"next":"^16.2.9","vitest":"^4.1.8","esbuild":"^0.28.1","typescript":"^5.9.3","@types/node":"^24.0.0","@vercel/functions":"^3.7.1"},"peerDependencies":{"next":">=14","@vercel/functions":">=2"},"peerDependenciesMeta":{"next":{"optional":true},"@vercel/functions":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/conveo-sdk_0.3.1_1781708051495_0.8921087815221529","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@conveo/conveo-sdk","version":"0.4.0","license":"UNLICENSED","_id":"@conveo/conveo-sdk@0.4.0","maintainers":[{"name":"boris_conveo","email":"boris@conveo.ai"}],"homepage":"https://github.com/conveo/conveo-sdk#readme","bugs":{"url":"https://github.com/conveo/conveo-sdk/issues"},"bin":{"agentgateway-dev-token":"dist/dev/token.js"},"dist":{"shasum":"c01922dc4b2f046f6817ece96b4b6d22e5906a9f","tarball":"https://registry.npmjs.org/@conveo/conveo-sdk/-/conveo-sdk-0.4.0.tgz","fileCount":25,"integrity":"sha512-Gl9az8D+IUeoYQSv9E1PGk9joEf8xsAK1DuJeAg5jW09Hjizc8FX04m7USGNxiyhRruM/8fZ0d5GiaP2/YXauQ==","signatures":[{"sig":"MEYCIQDpc89lvWsRz5zk8CFavETzezmDPsctt6ogpC2zPrT+2gIhAJCNDvMsCAacqTFeD1+qvC9aVE53kjmoO9M1+RvK1hel","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64566},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./next":{"types":"./dist/adapters/next.d.ts","default":"./dist/adapters/next.js"},"./server":{"types":"./dist/server.d.ts","default":"./dist/server.js"},"./vercel":{"types":"./dist/adapters/vercel.d.ts","default":"./dist/adapters/vercel.js"},"./supabase":{"types":"./dist/adapters/supabase.d.ts","default":"./dist/adapters/supabase.js"}},"gitHead":"398ae1da8d7b57db040bacdcbdfd361499f483b0","scripts":{"dev":"tsc -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest run","build":"tsc -p tsconfig.build.json && pnpm minify && pnpm build:deno","minify":"node scripts/minify.mjs","typecheck":"tsc -p tsconfig.json --noEmit","build:deno":"esbuild src/adapters/supabase.ts --bundle --minify --format=esm --platform=browser --target=es2022 --outfile=dist/deno/agentgateway-supabase.bundle.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8759f550-a079-428a-8f1a-ee8be5063240"}},"repository":{"url":"git+https://github.com/conveo/conveo-sdk.git","type":"git"},"_npmVersion":"11.17.0","description":"SDK for Conveo apps behind the agent gateway: drop-in auth middleware (Next.js / Vercel / Supabase), server helpers, and a dev-token CLI.","directories":{},"_nodeVersion":"22.23.0","dependencies":{"jose":"^6.2.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.5.3","devDependencies":{"next":"^16.2.9","vitest":"^4.1.8","esbuild":"^0.28.1","typescript":"^5.9.3","@types/node":"^24.0.0","@vercel/functions":"^3.7.1"},"peerDependencies":{"next":">=14","@vercel/functions":">=2"},"peerDependenciesMeta":{"next":{"optional":true},"@vercel/functions":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/conveo-sdk_0.4.0_1782482774992_0.30596689093640195","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@conveo/conveo-sdk","version":"0.4.1","description":"SDK for Conveo apps behind the agent gateway: drop-in auth middleware (Next.js / Vercel / Supabase), server helpers, and a dev-token CLI.","license":"UNLICENSED","type":"module","repository":{"type":"git","url":"git+https://github.com/conveo/conveo-sdk.git"},"publishConfig":{"registry":"https://registry.npmjs.org","access":"public"},"packageManager":"pnpm@11.5.3","engines":{"node":">=20"},"exports":{".":{"types":"./dist/core/index.d.ts","default":"./dist/core/index.js"},"./next":{"types":"./dist/adapters/next.d.ts","default":"./dist/adapters/next.js"},"./vercel":{"types":"./dist/adapters/vercel.d.ts","default":"./dist/adapters/vercel.js"},"./supabase":{"types":"./dist/adapters/supabase.d.ts","default":"./dist/adapters/supabase.js"},"./server":{"types":"./dist/server.d.ts","default":"./dist/server.js"},"./linear":{"types":"./dist/integrations/linear.d.ts","default":"./dist/integrations/linear.js"},"./hubspot":{"types":"./dist/integrations/hubspot.d.ts","default":"./dist/integrations/hubspot.js"},"./postgrest":{"types":"./dist/integrations/postgrest.d.ts","default":"./dist/integrations/postgrest.js"}},"bin":{"agentgateway-dev-token":"dist/dev/token.js"},"scripts":{"build":"tsc -p tsconfig.build.json && pnpm minify && pnpm build:deno","minify":"node scripts/minify.mjs","build:deno":"esbuild src/adapters/supabase.ts --bundle --minify --format=esm --platform=browser --target=es2022 --outfile=dist/deno/agentgateway-supabase.bundle.js","dev":"tsc -p tsconfig.build.json --watch --preserveWatchOutput","test":"vitest run","typecheck":"tsc -p tsconfig.json --noEmit"},"dependencies":{"jose":"^6.2.3"},"peerDependencies":{"@hubspot/api-client":">=10","@linear/sdk":">=30","@vercel/functions":">=2","next":">=14"},"peerDependenciesMeta":{"@hubspot/api-client":{"optional":true},"@linear/sdk":{"optional":true},"@vercel/functions":{"optional":true},"next":{"optional":true}},"devDependencies":{"@hubspot/api-client":"^14.0.0","@linear/sdk":"^87.0.0","@types/node":"^24.0.0","@vercel/functions":"^3.7.1","esbuild":"^0.28.1","next":"^16.2.9","typescript":"^5.9.3","vitest":"^4.1.8"},"gitHead":"6eccf2f69741a4d5c89e0728363980be2b5ef739","_id":"@conveo/conveo-sdk@0.4.1","bugs":{"url":"https://github.com/conveo/conveo-sdk/issues"},"homepage":"https://github.com/conveo/conveo-sdk#readme","_nodeVersion":"22.23.0","_npmVersion":"11.18.0","dist":{"integrity":"sha512-dG2VqgSQbRMwBE6ndv7TOZM/+hdySmC+feHllJ6SBnKO6N6c40+xOhsnPK8DT4A0MxkPWl3T3JSRgklgmJcpew==","shasum":"256664444625ce1102c7e798c6566922da7d2be3","tarball":"https://registry.npmjs.org/@conveo/conveo-sdk/-/conveo-sdk-0.4.1.tgz","fileCount":35,"unpackedSize":78611,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCA00aOACn1l4ObU2nyg5t53k4l74ZX/JrUxMO+PFbf8wIhAJKoR8Xh5bjWihAnf1CiOtFobfDnfwmXwptLpXNW71tC"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8759f550-a079-428a-8f1a-ee8be5063240"}},"directories":{},"maintainers":[{"name":"boris_conveo","email":"boris@conveo.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/conveo-sdk_0.4.1_1782910235693_0.050807672085912525"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-17T14:34:42.434Z","modified":"2026-07-01T12:50:36.024Z","0.3.0":"2026-06-17T14:34:45.423Z","0.3.1":"2026-06-17T14:54:11.675Z","0.4.0":"2026-06-26T14:06:15.122Z","0.4.1":"2026-07-01T12:50:35.842Z"},"bugs":{"url":"https://github.com/conveo/conveo-sdk/issues"},"license":"UNLICENSED","homepage":"https://github.com/conveo/conveo-sdk#readme","repository":{"type":"git","url":"git+https://github.com/conveo/conveo-sdk.git"},"description":"SDK for Conveo apps behind the agent gateway: drop-in auth middleware (Next.js / Vercel / Supabase), server helpers, and a dev-token CLI.","maintainers":[{"name":"boris_conveo","email":"boris@conveo.ai"}],"readme":"# @conveo/conveo-sdk\n\n**Easily add Conveo authentication to your app. @conveo.ai sign-in for free.**\n\nVibe-coding an internal tool? You don't need to build login, sessions,\nor user management. Conveo's **agent gateway** signs people in with their\nnormal Conveo account (Okta) *before* they ever reach your app. This SDK\nis the small piece your app needs to know **who** is calling.\n\n## Why you need this\n\nWithout it, every internal app reinvents auth, and usually gets it wrong\n(client-side-only checks, shared API keys, \"@conveo.ai only\" rules that aren't\nactually enforced). With it:\n\n- 🔒 **Your app is unreachable except through the gateway.** No login screen\n  to build, no passwords or tokens to store, nothing to leak.\n- 👤 **Your code just knows the user.** `user.email`, verified\n  cryptographically, on every request.\n- 🔁 **You can call Conveo data and APIs *as that user*.** The gateway\n  enforces per-user permissions and keeps an audit trail.\n\n## Quick start (Next.js on Vercel)\n\n**1. Install.** The package is on the public npm registry, so there's no\nregistry config or auth to set up — on Vercel, in CI, or locally:\n\n```bash\npnpm add @conveo/conveo-sdk\n```\n\n**2. Add one file:** `proxy.ts` at your project root (Next.js 16; call it\n`middleware.ts` on older Next):\n\n```ts\nimport { createGatewayProxy } from \"@conveo/conveo-sdk/next\";\n\nexport default createGatewayProxy();\n\nexport const config = {\n  matcher: [\"/((?!_next/static|_next/image|favicon.ico).*)\"],\n};\n```\n\nThat's the entire auth setup. Every page and API route is now protected,\nincluding ones you add next month and forget to think about.\n\n**3. Use the user**, anywhere in your server code:\n\n```ts\nimport { getGatewayUser, gatewayFetch } from \"@conveo/conveo-sdk/server\";\n\nconst user = await getGatewayUser();\nuser.email;                                   // \"you@conveo.ai\"\n\n// call Conveo data through the gateway, as this user:\nconst res = await gatewayFetch(\"/postgrest/Organization?select=id,name\", { user });\n```\n\n`gatewayFetch` can also call as the **app itself** instead of a user — for\ngateway-fronted vendor APIs whose key lives at the gateway (HubSpot, Linear, …).\nYou authenticate with the app's Vercel OIDC identity; the gateway checks a Grant\nand injects the vendor key on the upstream leg, so your app never holds it:\n\n```ts\n// `service` targets the vendor API's own host; `identity: \"app\"` uses the\n// app's VERCEL_OIDC_TOKEN as the bearer (the default when there's no `user`).\nconst res = await gatewayFetch(\"/crm/v3/objects/contacts?limit=3\", {\n  identity: \"app\",\n  service: \"hubspot\",\n});\n```\n\n`service` resolves to `AGENTGATEWAY_SERVICE_<NAME>_URL` if set, else\n`https://<name>.internal.conveo.ai` (override the suffix with\n`AGENTGATEWAY_SERVICE_DOMAIN`). Install `@vercel/functions` for automatic\nrefresh of the short-lived OIDC token; without it the SDK reads\n`VERCEL_OIDC_TOKEN` directly.\n\nThe `user` you get back looks like this:\n\n```ts\n{\n  email: \"you@conveo.ai\",     // who's calling (verified, safe to trust)\n  sub: \"eae61a46-3101-…\",     // stable user id, use this as your database key\n  emailVerified: true,\n  token: \"eyJhbGciOi…\",       // the user's token, gatewayFetch uses it for you\n  claims: { name: \"…\", exp: 1765486800, /* …all raw token claims */ },\n}\n```\n\nDay to day you'll only touch `email` (display, allowlists) and `sub` (storing\nper-user data, since emails can change and `sub` never does).\n\n**Local dev:** get yourself a real token (opens Okta in your browser, valid 8h):\n\n```bash\npnpm exec agentgateway-dev-token   # writes AGENTGATEWAY_DEV_TOKEN to .env.local\npnpm dev                           # localhost now behaves as you, for real\n```\n\nWant a full working example? See the\n[template app](https://github.com/conveo/agentgateway-template-app). Clone\nit and you're done.\n\n## Third-party SDKs through the gateway\n\n`gatewayFetch({ service })` is the low-level way to reach a gateway-fronted vendor\nAPI. For the common ones, these subpaths hand you the **official vendor SDK** already\npointed at the gateway and authenticated — no host, no token, no vendor key in your app:\n\n| Import | Returns | Vendor SDK |\n|---|---|---|\n| `@conveo/conveo-sdk/linear` | `getLinearClient()` → `LinearClient` | `@linear/sdk` |\n| `@conveo/conveo-sdk/hubspot` | `getHubspotClient()` → HubSpot `Client` | `@hubspot/api-client` |\n| `@conveo/conveo-sdk/postgrest` | `postgrest()` / `postgrestWithCount()` | none (typed helper) |\n\n**Prerequisites (one-time):**\n\n1. On the Vercel project: **Settings → Functions → OIDC Federation = ON** (Vercel then\n   injects a fresh `VERCEL_OIDC_TOKEN` into every server invocation). Install\n   `@vercel/functions` for automatic token refresh.\n2. The app must be **granted** each route — the gateway is fail-closed. Onboarding adds\n   an `Identity` + `Grant` for your Vercel project in `conveo/agentgateway`; until then,\n   calls return `401`.\n3. Install the vendor SDK you use (optional peer deps): `pnpm add @linear/sdk` /\n   `pnpm add @hubspot/api-client`. PostgREST needs none.\n\n**Linear / HubSpot** — build the client **per request** (the OIDC token rotates) and use\nthe native SDK:\n\n```ts\nimport { getLinearClient } from \"@conveo/conveo-sdk/linear\";\nimport { getHubspotClient } from \"@conveo/conveo-sdk/hubspot\";\n\nexport async function GET() {\n  const linear = await getLinearClient();\n  const issues = await linear.issues({ first: 10 });\n\n  const hs = await getHubspotClient();\n  const deals = await hs.crm.deals.basicApi.getPage(10);\n\n  return Response.json({ issues: issues.nodes, deals: deals.results });\n}\n```\n\n**PostgREST** — a typed helper returning a result union (never throws on a bad status):\n\n```ts\nimport { postgrest } from \"@conveo/conveo-sdk/postgrest\";\n\nconst res = await postgrest<Org[]>(\"Organization?select=id,name&limit=100\");\nif (!res.ok) return Response.json({ error: res.kind }, { status: res.status });\nreturn Response.json(res.data); // res.kind: ok | unauthenticated | unauthorized | unreachable | error\n```\n\nNotes:\n\n- **Server-side only** — these need the Vercel OIDC token. Never call from a client component.\n- **Call the factory per request**, inside your handler — never cache a client at module scope.\n- **App identity, not user identity** — the gateway injects a *shared* upstream credential\n  (e.g. Linear writes appear as the shared app actor, not the signed-in person).\n- **Hosts** follow the same `service` convention as `gatewayFetch`: `linear`/`hubspot`\n  resolve to `https://<name>.internal.conveo.ai` (override with\n  `AGENTGATEWAY_SERVICE_<NAME>_URL` / `AGENTGATEWAY_SERVICE_DOMAIN`, or a per-call\n  `baseUrl`). PostgREST is a path on the API base (`AGENTGATEWAY_API_URL`).\n- **Errors:** `401` = OIDC off, wrong project slug, or route not granted; `403` = the\n  upstream credential's scopes don't cover the call (a gateway-side change).\n\n## How it works\n\n![How it works](docs/how-it-works.svg)\n\nIn words: users visit your app at `yourapp.internal.conveo.ai`, which is the\n**gateway**, not Vercel. The gateway checks who they are (Okta), then forwards\nthe request to your Vercel deployment with two things attached: its own\n*service token* (the key past Vercel's deployment protection — your app never\nsees it) and the user's *identity token*. Your `proxy.ts` — this SDK —\ndouble-checks that identity token against Keycloak's public keys and hands\nyour code the user. Anyone who tries to reach your `*.vercel.app` URL directly\nhits a wall, and anyone who somehow got through still can't fake an identity:\nthat would require Keycloak's signing key.\n\nYou never see a password, never store a token in the browser, and there are\nno shared secrets anywhere in your app.\n\n---\n\n## The details\n\nEverything below is reference material — you don't need it to get started.\n\n### Package layout\n\nThe SDK is a pure, environment-free core with thin adapters per runtime:\n\n| Import | Use from |\n|---|---|\n| `@conveo/conveo-sdk` | core: `createVerifier`, `checkPolicy`, types |\n| `…/next` | `proxy.ts` / `middleware.ts` in a Next.js app |\n| `…/vercel` | root `middleware.ts` of any non-Next Vercel app (Vite SPA etc.) |\n| `…/supabase` | `requireGatewayUser(req)` in Deno edge functions |\n| `…/server` | `getGatewayUser()`, `gatewayFetch()` in Next server code |\n| `…/linear` | `getLinearClient()` — Linear via the gateway ([integrations](#third-party-sdks-through-the-gateway)) |\n| `…/hubspot` | `getHubspotClient()` — HubSpot via the gateway |\n| `…/postgrest` | `postgrest()` — Conveo Postgres replica via the gateway |\n\n### What the middleware verifies\n\nSignature against Keycloak's JWKS (cached, auto-rotating — public keys, no\nsecrets), issuer, expiry (30s clock tolerance), `email_verified`, and your\noptional domain/allowlist policy. `aud` is verified only when configured —\nconveo-realm user tokens carry no `aud` claim today.\n\n### Configuration (env-first; code options win)\n\n| Env var | Default | Purpose |\n|---|---|---|\n| `AGENTGATEWAY_ISSUER` | `https://keycloak.ops.conveo.ai/realms/conveo` | Token issuer |\n| `AGENTGATEWAY_AUDIENCE` | not enforced | Required `aud` when set |\n| `AGENTGATEWAY_JWKS_URL` | derived from issuer | Override for non-Keycloak issuers |\n| `AGENTGATEWAY_USER_HEADER` | `authorization` (Bearer) | Where the gateway puts the user token |\n| `AGENTGATEWAY_REQUIRE_EMAIL_DOMAIN` | — | e.g. `conveo.ai` (exact domain match) |\n| `AGENTGATEWAY_ALLOWED_EMAILS` | — | CSV allowlist |\n| `AGENTGATEWAY_SIGNIN_URL` | — | Browser 302 target; unset → always 401 |\n| `AGENTGATEWAY_AUTH_MODE` | `required` | `optional` verifies but never rejects |\n| `AGENTGATEWAY_API_URL` / `_MCP_URL` | gateway prod hosts | `gatewayFetch` bases |\n| `AGENTGATEWAY_SERVICE_<NAME>_URL` | `https://<name>.<domain>` | Override a `gatewayFetch({ service })` host (e.g. `AGENTGATEWAY_SERVICE_HUBSPOT_URL`) |\n| `AGENTGATEWAY_SERVICE_DOMAIN` | `internal.conveo.ai` | Suffix for unresolved `service` hosts |\n| `AGENTGATEWAY_DEV_TOKEN` / `_DEV_MOCK_USER` | — | Local dev only; honored only when `NODE_ENV` or `VERCEL_ENV` is `development` |\n\nCode options: `createGatewayProxy({ publicPaths: [\"/api/health\"], ... })` —\npublic paths skip the user check (they're still behind Vercel's edge wall).\n\n### Supabase Edge Functions (Deno)\n\nSupabase functions are reachable directly at `*.supabase.co` — they bypass\nVercel's protection entirely, so they must verify tokens themselves:\n\n```ts\nimport { requireGatewayUser } from \"../_shared/agentgateway-supabase.bundle.js\";\n\nDeno.serve(async (req) => {\n  try {\n    const user = await requireGatewayUser(req);\n    return Response.json({ hello: user.email });\n  } catch (error) {\n    if (error instanceof Response) return error; // 401/403 from the adapter\n    throw error;\n  }\n});\n```\n\nThat relative import is the **vendored bundle**: a self-contained\n`dist/deno/agentgateway-supabase.bundle.js` (jose inlined, minified). Copy it\nfrom `node_modules` into `supabase/functions/_shared/` with a `postinstall`\nscript — the copy always matches your lockfile-pinned version, so deploys are\nreproducible and need no network fetch. (Now that the package is on the public\nregistry you can also `import … from \"npm:@conveo/conveo-sdk/supabase\"`\ndirectly; the vendored bundle just keeps deploys pinned and offline-friendly.)\n\n### Behavior guarantees\n\n- `x-gateway-user-*` headers are stripped from every inbound request before\n  anything else — app code can trust them.\n- Fail closed: JWKS unreachable / malformed token / policy failure → 401/403,\n  never pass-through. Rejections: 302 to sign-in for browser navigations (when\n  configured), otherwise JSON `401` with `WWW-Authenticate` / `403`.\n- `getGatewayUser()` re-verifies the forwarded token rather than trusting\n  headers, so routes missed by the matcher can't be fed forged identity.\n\n### Gateway contract\n\nThe gateway-side contract (Trusted Sources gate token, `Authorization`\npassthrough of the user JWT) is defined in\n[`conveo/agentgateway`](https://github.com/conveo/agentgateway) —\n`chart/VERCEL-TRUSTED-SOURCES.md`. This SDK verifies what\n`backend.auth.passthrough` forwards.\n\n### Releasing\n\nCI builds + tests every PR. Releases are automatic: every merge to `main`\nruns the release workflow, which computes the next version from the latest git\ntag (a patch bump, or whatever `package.json` requests if it's higher),\npublishes to the public npm registry, and pushes the version tag. Nothing is\ncommitted back to `main`.\n\nPublishing uses **npm Trusted Publishing** (OIDC) — no `NPM_TOKEN` secret. The\npackage's trusted-publisher settings on npmjs.com name this repo and\n`release.yml`; npm build provenance is attached automatically. The published\nJS is minified (`scripts/minify.mjs`); the `.d.ts` types ship readable.\n","readmeFilename":"README.md"}