惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
N
News and Events Feed by Topic
D
DataBreaches.Net
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Engineering at Meta
Engineering at Meta
T
Tailwind CSS Blog
博客园_首页
Microsoft Azure Blog
Microsoft Azure Blog
Y
Y Combinator Blog
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
月光博客
月光博客
A
About on SuperTechFans
I
InfoQ
S
Securelist
Last Week in AI
Last Week in AI
S
Schneier on Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Hacker News: Ask HN
Hacker News: Ask HN
Schneier on Security
Schneier on Security
Know Your Adversary
Know Your Adversary
腾讯CDC
大猫的无限游戏
大猫的无限游戏
S
Security @ Cisco Blogs
博客园 - 三生石上(FineUI控件)
Simon Willison's Weblog
Simon Willison's Weblog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog
美团技术团队
aimingoo的专栏
aimingoo的专栏
G
Google Developers Blog
罗磊的独立博客
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Cloudflare Blog
S
Secure Thoughts
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Latest news
Latest news
Recent Announcements
Recent Announcements
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
L
LINUX DO - 热门话题
Security Latest
Security Latest
TaoSecurity Blog
TaoSecurity Blog
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队

Supabase Blog

AI Agents Know About Supabase. They Don't Always Use It Right. Custom OIDC Providers for Supabase Auth 100,000 GitHub stars Supabase docs over SSH Navigating Regional Network Blocks Supabase Joins the Stripe Projects Developer Preview Log Drains: Now available on Pro Supabase Storage: major performance, security, and reliability updates Supabase incident on February 12, 2026 Hydra joins Supabase X / Twitter OAuth 2.0 is now available for Supabase Auth BKND joins Supabase Supabase is now an official Claude connector Supabase PrivateLink is now available Introducing: Postgres Best Practices When to use Read Replicas vs. bigger compute Introducing TRAE SOLO integration with Supabase Supabase Security Retro: 2025 Sync Stripe Data to Your Supabase Database in One Click Building ChatGPT Apps with Supabase Edge Functions and mcp-use Own Your Observability: Supabase Metrics API Introducing iceberg-js: A JavaScript Client for Apache Iceberg Introducing Supabase for Platforms Adding Async Streaming to Postgres Foreign Data Wrappers Build "Sign in with Your App" using Supabase Auth Introducing Seven New Email Templates for Supabase Auth The new Supabase power for Kiro Introducing Supabase ETL Introducing Analytics Buckets Introducing Vector Buckets Snap, Inc. Launches Snap Cloud, Powered by Supabase Triplit joins Supabase Supabase Series E 1000 Y Combinator Founders Choose Supabase gm 👋 web3, welcome aboard to Sign in with Web3 (Solana, Ethereum) Announcing the Supabase Remote MCP Server Enterprise speed, enterprise standards with Bolt Cloud + Supabase PostgREST 13 Lovable Cloud + Supabase: The Default Platform for AI Builders Processing large jobs with Edge Functions, Cron, and Queues Defense in Depth for MCP Servers OrioleDB Patent: now freely available to the Postgres community Supabase Launch Week 15 Hackathon Winner Announcement The Vibe Coder's Guide to Supabase Environments Testing for Vibe Coders: From Zero to Production Confidence The Vibe Coding Master Checklist Vibe Coding: Best Practices for Prompting Supabase Auth: Build vs. Buy Top 10 Launches of Launch Week 15 Supabase Launch Week 15 Hackathon Storage: 10x Larger Uploads, 3x Cheaper Cached Egress, and 2x Egress Quota Persistent Storage and 97% Faster Cold Starts for Edge Functions Algolia Connector for Supabase New Observability Features in Supabase Improved Security Controls and A New Home for Security Introducing Branching 2.0 Stripe-To-Postgres Sync Engine as standalone Library Supabase Analytics Buckets with Iceberg Support Create a Supabase backend using Figma Make Introducing JWT Signing Keys Supabase UI: Platform Kit Build a Personalized AI Assistant with Postgres Announcing Multigres: Vitess for Postgres Building on open table formats Open Data Standards: Postgres, OTel, and Iceberg Simplifying back-end complexity with Supabase Data APIs PostgreSQL Event Triggers without superuser access Top 10 Launches of Launch Week 14 Supabase MCP Server Data API Routes to Nearest Read Replica Declarative Schemas for Simpler Database Management Realtime: Broadcast from Database Keeping Tabs on What's New in Supabase Studio Edge Functions: Deploy from the Dashboard + Deno 2.1 Automatic Embeddings in Postgres Introducing the Supabase UI Library Supabase Auth: Bring Your Own Clerk Postgres Language Server: Initial Release Migrating from Fauna to Supabase Migrating from the MongoDB Data API to Supabase Dedicated Poolers Postgres as a Graph Database: (Ab)using pgRouting AI Hackathon at Y Combinator Calendars in Postgres using Foreign Data Wrappers Supabase Launch Week 13 Hackathon Winners How to Hack the Base! Running Durable Workflows in Postgres using DBOS database.build v2: Bring-your-own-LLM Restore to a New Project Hack the Base! with Supabase Top 10 Launches of Launch Week 13 Supabase Queues High Performance Disk Supabase Cron Supabase CLI v2: Config as Code Supabase Edge Functions: Introducing Background Tasks, Ephemeral Storage, and WebSockets Supabase AI Assistant v2 OrioleDB Public Alpha Executing Dynamic JavaScript Code on Supabase with Edge Functions ClickHouse Partnership, improved Postgres Replication, and Disk Management
Introducing @supabase/server
Tomás Pozo, Kalleby Santos, Katerina Skroumpelou, Matt Johnston · 2026-05-06 · via Supabase Blog

Introducing @supabase/server

Today we're releasing @supabase/server in public beta.

This is a new package that handles auth verification, client setup, request context, and common server-side boilerplate for you. It works across Edge Functions, Vercel Functions, Cloudflare Workers, Hono and Bun.

We anonymously analyzed 25,000 deployed Edge Functions and saw the same pattern everywhere: developers were rebuilding the same setup code over and over just to get to their actual business logic.

Most functions needed to:

  • Create a Supabase client with SUPABASE_ANON_KEY
  • Create another admin client with SUPABASE_SERVICE_ROLE_KEY that can bypass Row Level Security
  • Verify the JWT
  • Parse claims
  • Handle CORS
  • Wire up auth context
  • Copy/paste the same _shared/*.ts files between functions

With @supabase/server you just declare who can call your endpoint and get a fully initialized context back:

  • User-scoped Supabase client
  • Admin client with service role access
  • Verified user identity
  • JWT claims
  • Built-in request/auth helpers


_17

import { withSupabase } from 'npm:@supabase/server'

_17

_17

// Typical Deno.serve usage

_17

Deno.serve(

_17

withSupabase({ auth: 'user' }, async (req, ctx) => {

_17

const { data } = await ctx.supabase.from('todos').select()

_17

return Response.json(data)

_17

})

_17

)

_17

_17

// New fetch style handler usage

_17

export default {

_17

fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {

_17

const { data } = await ctx.supabase.from('todos').select()

_17

return Response.json(data)

_17

}),

_17

}


Note that export default { fetch } is equivalent to Deno.serve(...). Both define a request handler. We use export default throughout this post because it works across Edge Functions, Workers, and Bun. If you prefer Deno.serve, you can keep using it — it's still supported on Edge Functions.

At the core of @supabase/server is the SupabaseContext: a request context that includes everything most Edge Functions need, already configured for you.

That includes:

  • A user-scoped Supabase client
  • An admin client with service role access
  • Verified user identity
  • JWT claims
  • Auth metadata

@supabase/server gives you multiple ways to get a SupabaseContext. The most common is withSupabase, a wrapper that handles auth, client creation, and CORS before your handler runs:


_10

import { withSupabase } from 'npm:@supabase/server'

_10

_10

export default {

_10

fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {

_10

const { data } = await ctx.supabase.from('todos').select()

_10

return Response.json(data)

_10

}),

_10

}


If you need more control over error handling and responses, you can also call createSupabaseContext directly:


_11

import { createSupabaseContext } from 'npm:@supabase/server'

_11

_11

export default {

_11

fetch: async (req) => {

_11

const { data: ctx, error } = await createSupabaseContext(req, { auth: 'user' })

_11

if (error) return Response.json({ error: error.message }, { status: error.status })

_11

_11

const { data } = await ctx.supabase.from('todos').select()

_11

return Response.json(data)

_11

},

_11

}


Both approaches give you the same SupabaseContext. No shared utility files. No environment variable management. No manual JWT verification.

What's in the context#

Every withSupabase handler receives a ctx object with two pre-configured clients:

ctx.supabase — a user-scoped client that automatically respects RLS policies ctx.supabaseAdmin — an admin client using the service role for privileged operations

No manual client setup, JWT verification, or environment variable wiring required.

The full context looks like this:


_10

interface SupabaseContext {

_10

supabase: SupabaseClient

_10

supabaseAdmin: SupabaseClient

_10

userClaims: UserIdentity | null

_10

jwtClaims: JWTClaims | null

_10

authMode: AuthMode

_10

}


With @supabase/server, authentication happens before your handler runs.

You declare who is allowed to call the endpoint, and the package handles verification automatically.

For example, this endpoint allows unauthenticated requests:


_10

export default {

_10

fetch: withSupabase({ auth: 'none' }, async (_req, _ctx) => {

_10

return Response.json({ status: 'ok' })

_10

}),

_10

}


This endpoint requires a valid user JWT:


_10

export default {

_10

fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {

_10

const { data } = await ctx.supabase.from('todos').select()

_10

return Response.json(data)

_10

}),

_10

}


If the request does not include a valid user token, the request is rejected before your handler executes.

Here's all of the auth modes included in the package:


_14

// authenticated users only (default)

_14

withSupabase({ auth: 'user' }, handler)

_14

_14

// no auth required, good for webhooks and health checks

_14

withSupabase({ auth: 'none' }, handler)

_14

_14

// server-to-server with secret key

_14

withSupabase({ auth: 'secret' }, handler)

_14

_14

// with publishable key

_14

withSupabase({ auth: 'publishable' }, handler)

_14

_14

// accept either a user JWT or a secret key

_14

withSupabase({ auth: ['user', 'secret'] }, handler)


Your function's security model is visible in one line.

Last year we improved project security with asymmetric JWT Signing Keys and new API keys. Better security for every project, but migrating existing functions was hard.

You had to install jose, configure a JWKS endpoint, build your own auth middleware, expose new secrets, and update every function individually.

We fixed it. @supabase/server handles new key validation and JWT verification internally. You adopt the package and the new security model comes with it. No jose. No JWKS configuration. No manual secret setup.


_10

export default {

_10

// auth: 'user' will handle incoming user JWT validation for you

_10

fetch: withSupabase({ auth: 'user' }, async (req, { supabase }) => {

_10

const { data } = await supabase.from('subscriptions').select('*')

_10

return Response.json(data)

_10

}),

_10

}


Now you get support for the new auth keys without manual JWT verification. Delete your shared utility files and focus on business logic.

withSupabase returns a standard (Request) => Promise<Response> handler. It works with any runtime that supports the Web API pattern.

Edge Functions, Vercel Functions, and Cloudflare Workers:


_10

import { withSupabase } from '@supabase/server'

_10

_10

export default {

_10

fetch: withSupabase({ auth: 'user' }, handler),

_10

}


On Edge Functions, declare the dependency in deno.json to import @supabase/server from npm:@supabase/server.

Hono (with the included adapter):


_12

import { withSupabase } from '@supabase/server/adapters/hono'

_12

import { Hono } from 'hono'

_12

_12

const app = new Hono()

_12

_12

app.get('/todos', withSupabase({ auth: 'user' }), async (c) => {

_12

const { supabase } = c.var.supabaseContext

_12

const { data } = await supabase.from('todos').select()

_12

return c.json(data)

_12

})

_12

_12

export default { fetch: app.fetch }


Most developers don't need anything beyond withSupabase or createSupabaseContext. But you can use the underlying primitives directly.


_10

import {

_10

createAdminClient,

_10

createContextClient,

_10

resolveEnv,

_10

verifyAuth,

_10

} from '@supabase/server/core'


These are useful when you need more control: multiple routes with different auth, custom response headers, or domain-specific wrappers like MCP servers.

Here's an Edge Function with per-route auth:


_22

import { createContextClient, verifyAuth } from '@supabase/server/core'

_22

_22

export default {

_22

fetch: async (req) => {

_22

const url = new URL(req.url)

_22

_22

if (url.pathname === '/health') {

_22

return Response.json({ status: 'ok' })

_22

}

_22

_22

if (url.pathname === '/todos') {

_22

const { data: auth, error } = await verifyAuth(req, { auth: 'user' })

_22

if (error) return Response.json({ error: error.message }, { status: error.status })

_22

_22

const supabase = createContextClient(auth.token)

_22

const { data } = await supabase.from('todos').select()

_22

return Response.json(data)

_22

}

_22

_22

return new Response('Not found', { status: 404 })

_22

},

_22

}


These are the same primitives that power withSupabase. Teams building MCP servers, custom middleware, or framework adapters can compose them into their own patterns.

We designed @supabase/server with agentic development in mind. Every function follows the same structure: declare access, receive context, write logic.

During internal testing, Claude Code migrated an entire project's Edge Functions to @supabase/server in a single prompt. That included adopting new API keys, removing shared utility files, and switching every function to withSupabase. All functions worked on the first run.

When every function looks the same, agents produce correct code from a single example.

Does this replace @supabase/ssr?

No. @supabase/ssr handles cookie-based session management for frameworks like Next.js and SvelteKit. @supabase/server handles stateless, header-based auth for Edge Functions, Workers, and other backend runtimes. The two packages coexist and are not replacements for each other. Deeper integration with @supabase/ssr is on the roadmap.

If you would like to adopt the DX that this package provides, check our SSR frameworks documentation for implementation references.

Which runtimes does this support?

Any runtime or platform that supports the standard Request/Response Web API. withSupabase returns a standard (Request) => Promise<Response> handler, so it works on Supabase Edge Functions, Vercel Functions, Cloudflare Workers, Bun, Deno and more.

Is Hono the only supported framework?

No. Hono was the first framework adapter we shipped, and we have already merged a community PR for the H3 adapter. We expect to accept more community-contributed adapters.

See more in our adapters documentation.

Where is the documentation?

The package ships with full documentation in the GitHub repo. We're also working on adding guides to the Supabase docs.

What about environment variables?

On the Supabase platform and Local Development (CLI), your Edge Functions will receive the required environment variables to work out of the box (SUPABASE_PUBLISHABLE_KEYS, SUPABASE_SECRET_KEYS, SUPABASE_JWKS).

In local development or self-hosted environments, use the same plural form: SUPABASE_PUBLISHABLE_KEYS instead of SUPABASE_ANON_KEY, SUPABASE_SECRET_KEYS instead of SUPABASE_SERVICE_ROLE_KEY.

Check out the environment variables documentation for more details.

How can I leave feedback?

Open an issue on the GitHub repo or join the conversation in Discord.

Install the package and the AI skill:


_10

npm install @supabase/server@latest

_10

npx skills add supabase/server


The skill gives Claude Code, Codex, Cursor and any agentic coding tool full context about the API surface, patterns, and migration paths. From there, you can prompt your way through most tasks.


_10

Analyze all Edge Functions, and plan a full migration to use

_10

the new API keys with @supabase/server


Scaffold a new REST API with Hono:


_10

Create a Hono API with @supabase/server that has CRUD

_10

endpoints for a todos table, using per-route auth


Add a protected Edge Function with admin operations:


_10

Create an Edge Function that accepts user or secret key auth,

_10

reads from a user's profile with RLS, and writes audit logs

_10

with the admin client


Or write it by hand:


_10

import { withSupabase } from 'npm:@supabase/server'

_10

_10

export default {

_10

fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {

_10

const { data } = await ctx.supabase.from('todos').select()

_10

return Response.json(data)

_10

}),

_10

}


@supabase/server is in public beta. We're looking for feedback on the API surface, the adapter patterns, and edge cases we haven't hit yet.

Check out the GitHub repo and the docs and let us know what you build.