Using with Supabase Auth
How to authenticate AI agents with Supabase Auth — map verified agent tokens to Supabase users and enable agent signups.
AgentOnboard works alongside Supabase Auth. Supabase handles sessions and Row Level Security (RLS) for human web users; AgentOnboard authenticates AI agents calling your API.
1. Verifying existing Supabase users
Use your Supabase client inside resolveAccount to look up the user by email:
import { createClient } from "@supabase/supabase-js";
import { requireAgentAccount } from "@agentonboard/sdk/next";
// Service role client for server-side lookups
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
export async function POST(request: Request) {
const session = await requireAgentAccount(request, {
audience: "notes.com",
resolveAccount: async ({ email }) => {
// Look up the user in your profiles or users table
const { data } = await supabase
.from("profiles")
.select("id")
.eq("email", email.toLowerCase())
.maybeSingle();
return data?.id ?? null;
},
});
// Returns 401 or 403 automatically
if (!session.ok) return session.response;
// session.user is your Supabase user ID (UUID)
return Response.json({ success: true, supabase_user_id: session.user });
}2. Enabling agent signup with Supabase
To let an agent automatically provision an account in Supabase when visiting your signup route, use the Supabase Admin Auth API:
import { createClient } from "@supabase/supabase-js";
import { createAgentAccount } from "@agentonboard/sdk";
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
export async function POST(request: Request) {
const outcome = await createAgentAccount({
token: request.headers.get("Authorization") ?? "",
audience: "notes.com",
resolveAccount: async ({ email }) => {
const { data } = await supabase
.from("profiles")
.select("id")
.eq("email", email.toLowerCase())
.maybeSingle();
return data?.id ?? null;
},
createAccount: async ({ email }) => {
// Provision user via admin API with email_confirm: true
const { data, error } = await supabase.auth.admin.createUser({
email: email.toLowerCase(),
email_confirm: true,
});
if (error) throw error;
return data.user.id;
},
});
if (!outcome.ok) {
return Response.json(
{ code: outcome.code, error: outcome.error },
{ status: outcome.code === "RESOLVER_ERROR" ? 500 : 401 }
);
}
return Response.json(
{ user_id: outcome.user, created: outcome.created },
{ status: 201 }
);
}email_confirm: true
Because AgentOnboard asserts that the human verified ownership of the inbox, you can safely set email_confirm: true without sending a duplicate confirmation email.