Skip to main content

robel-auth

Integrate and maintain Robelest Convex Auth in apps by always checking upstream before implementation. Use when adding auth setup, updating auth wiring, migrating between upstream patterns, or troubleshooting @robelest/convex-auth behavior across projects.

Zur Installation springen

Quellinformationen

Repository
get-convex/components-submissions-directory
Letzte Quellaktivität
12. Juni 2026 um 00:15
Erkannte Sprache von SKILL.md
Englisch
Sterne
9
Forks
4

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
robel-auth
description
Integrate and maintain Robelest Convex Auth in apps by always checking upstream before implementation. Use when adding auth setup, updating auth wiring, migrating between upstream patterns, or troubleshooting @robelest/convex-auth behavior across projects.
# Robel auth skill Use this skill when a user asks to implement, update, or debug auth based on `robelest/convex-auth`. This skill is designed to be copied into other repos. ## Non negotiable upstream check before any auth change Run this every time before proposing code or commands. Preferred command: ```bash bash .agents/skills/robel-auth/scripts/check-upstream.sh ``` Manual checklist if script is unavailable: 1. Read official docs: `https://auth.estifanos.com/getting-started/installation/` 2. Read latest `main` README: `https://raw.githubusercontent.com/robelest/convex-auth/main/README.md` 3. Read latest `release` README: `https://raw.githubusercontent.com/robelest/convex-auth/release/README.md` 4. Check branch level differences: `https://github.com/robelest/convex-auth/compare/release...main` 5. Read current self hosting docs if portal or static hosting is involved: - `https://raw.githubusercontent.com/get-convex/self-hosting/main/INTEGRATION.md` - `https://github.com/get-convex/self-hosting` If `main` and `release` conflict, prefer the branch requested by the user. If unspecified, use `release` for stability and explain that choice. ## Important assumptions for this skill - Treat the official docs site (`auth.estifanos.com`) and GitHub as sources of truth every time. - Do not assume npm package availability. - Validate package availability at execution time. - If npm is unavailable, use a GitHub source install pinned to a branch or commit. - Keep all Convex code type safe and validator complete. ## Published package reality check (critical) The docs site (`auth.estifanos.com`) and `main` branch often describe APIs ahead of the latest preview release on npm. Before writing imports, always inspect what the installed version actually exports: ```bash ls node_modules/@robelest/convex-auth/dist/providers/ cat node_modules/@robelest/convex-auth/dist/providers/index.js cat node_modules/@robelest/convex-auth/dist/component/index.d.ts ``` As of `0.0.4-preview.25` the installed package ships: - PascalCase class/factory exports: `Password`, `OAuth`, `Passkey`, `Credentials`, `Anonymous`, `Device`, `Email`, `Phone`, `SSO`, `Totp` (not lowercase `password`, `oauth`, etc. that the docs show). - `Password`, `Credentials`, etc. are classes. Use `new Password()`, not `Password()`. - `OAuth` is a factory function: `OAuth(provider, config)`. - No first-party provider files exist yet (no `github.js`, `google.js`, etc.). For GitHub, Google, Apple, Microsoft, you still wrap an `arctic` provider in `OAuth()` and supply a `profile` callback. - `createAuth` is available from `@robelest/convex-auth/component` and is the correct entry point. - The client factory now **requires** `api` in SPA mode: `client({ convex, api: api.auth })`. Omitting `api` throws `"The \`api\` option is required when \`proxyPath\` is not set. Pass { api: api.auth }."` at first `signIn`/`signOut`/`verifyCode` call. Only `proxyPath` mode can skip it. If the docs show a lowercase factory like `github({ ... })` but the installed package only exports PascalCase classes and `OAuth`, follow the installed package and note the drift to the user. Do not blindly copy doc examples. ## Clarifying questions to ask first Ask these before editing: 1. Which branch is source of truth for this task, `release` or `main`. 2. Is this a new integration or an update to an existing auth setup. 3. Which framework is used: Vite, Next.js, SvelteKit, TanStack Start, Expo web, or other. 4. Is self hosted portal/static delivery needed now. 5. Are they okay pinning dependency to a specific Git commit for reproducibility. ## Install and dependency strategy Never assume one install path. 1. Try package registry lookup: - `npm view @robelest/convex-auth version` 2. If package is unavailable or blocked, install from GitHub: - `npm install github:robelest/convex-auth#release` 3. For deterministic builds, pin a commit SHA: - `npm install github:robelest/convex-auth#<commit-sha>` If the project uses pnpm or bun, translate the same GitHub dependency pinning pattern. ## Quick setup (CLI wizard) The recommended setup flow: 1. Install `@robelest/convex-auth` 2. Start a Convex deployment with `convex dev` 3. Run the auth setup wizard The wizard handles key generation, `convex.config.ts`, `auth.ts`, and `http.ts` automatically. ## Core wiring (3 files) ### 1. Register the component ```typescript // convex/convex.config.ts import { defineApp } from "convex/server"; import auth from "@robelest/convex-auth/convex.config"; const app = defineApp(); app.use(auth); export default app; ``` ### 2. Configure auth ```typescript // convex/auth.ts import { createAuth } from "@robelest/convex-auth/component"; import { components } from "./_generated/api"; import { github } from "@robelest/convex-auth/providers/github"; const auth = createAuth(components.auth, { providers: [ github({ clientId: process.env.AUTH_GITHUB_ID!, clientSecret: process.env.AUTH_GITHUB_SECRET!, }), ], }); export { auth }; export const { signIn, signOut, store } = auth; ``` ### 3. Wire up HTTP routes ```typescript // convex/http.ts import { httpRouter } from "convex/server"; import { auth } from "./auth"; const http = httpRouter(); auth.http.add(http); export default http; ``` `auth.http.add` registers OAuth callbacks and JWKS endpoints in one call. ## API layers Client auth flow: `signIn`, `signOut`, and `store` are the only required client-callable auth functions. Frontends use them through `client({ convex, api: api.auth })`. Server helpers: `auth.user.*`, `auth.session.*`, `auth.account.*`, `auth.group.*`, `auth.member.*`, `auth.invite.*`, `auth.key.*`, `auth.http.*`, `auth.group.sso.*`, and `auth.group.sso.scim.*` are server-side helpers for Convex code. They are not automatically public RPC. Optional group SSO RPC: If your app wants client-callable group SSO admin APIs, expose app-owned wrappers such as `convex/auth/group.ts`. ## Available providers All providers import from `@robelest/convex-auth/providers`: ```typescript import { anonymous, apple, custom, email, github, google, microsoft, passkey, password, phone, sso, totp, } from "@robelest/convex-auth/providers"; ``` ### OAuth providers | Provider | Factory | Required env vars | |----------|---------|-------------------| | GitHub | `github({ clientId, clientSecret })` | `AUTH_GITHUB_ID`, `AUTH_GITHUB_SECRET` | | Google | `google({ clientId, clientSecret })` | `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET` | | Apple | `apple({ clientId, teamId, keyId, privateKey })` | `AUTH_APPLE_ID`, `AUTH_APPLE_TEAM_ID`, `AUTH_APPLE_KEY_ID`, `AUTH_APPLE_PRIVATE_KEY` | | Microsoft | `microsoft({ tenant, clientId, clientSecret? })` | `AUTH_MICROSOFT_TENANT_ID`, `AUTH_MICROSOFT_ID` | All OAuth wrappers derive callback URL from `CONVEX_SITE_URL` automatically. ### Custom OAuth Use `custom()` for providers without a first-party wrapper: ```typescript custom({ id: "discord", clientId: process.env.AUTH_DISCORD_ID!, clientSecret: process.env.AUTH_DISCORD_SECRET!, scopes: ["identify", "email"], authorization: { url: "https://discord.com/oauth2/authorize", pkce: "optional" }, token: { url: "https://discord.com/api/oauth2/token", authMethod: "body" }, profile: async ({ accessToken }) => { const res = await fetch("https://discord.com/api/users/@me", { headers: { Authorization: `Bearer ${accessToken}` }, }); const user = await res.json(); return { id: String(user.id), email: user.email, name: user.username }; }, }) ``` ### Non-OAuth providers | Provider | Factory | Notes | |----------|---------|-------| | Password | `password()` | Built-in password auth | | Magic links | `email({ from, send })` | Requires email transport (e.g. Resend) | | Passkeys | `passkey()` | WebAuthn based | | TOTP | `totp({ issuer })` | Authenticator app codes | | Anonymous | `anonymous()` | Guest sessions | | Phone/SMS | `phone({ send })` | Requires SMS transport (e.g. Twilio) | | Group SSO | `sso()` | Enables OIDC, SAML 2.0, SCIM 2.0 | ## Configuration options ```typescript const auth = createAuth(components.auth, { providers: [/* ... */], session: { totalDurationMs: 30 * 24 * 60 * 60 * 1000, // 30 days inactiveDurationMs: 7 * 24 * 60 * 60 * 1000, // 7 days }, jwt: { durationMs: 60 * 1000, // 1 minute }, signIn: { max_failed_attempts_per_hour: 10, }, callbacks: { afterUserCreatedOrUpdated: async (ctx, { userId, existingUser }) => { /* ... */ }, }, authorization: { roles, // from defineRoles() }, }); ``` | Option | Type | Default | Description | |--------|------|---------|-------------| | `providers` | `AuthProviderConfig[]` | required | Auth methods to enable | | `session.totalDurationMs` | `number` | 30 days | Maximum session lifetime | | `session.inactiveDurationMs` | `number` | varies | Inactive session timeout | | `jwt.durationMs` | `number` | 60s | JWT token lifetime | | `signIn.max_failed_attempts_per_hour` | `number` | 10 | Rate limit for failed sign-in attempts | | `callbacks.afterUserCreatedOrUpdated` | `function` | none | Post sign-in hook | | `authorization.roles` | `Record` | `{}` | App-defined role definitions and grants | ## Multi-access patterns Every auth path resolves to the same `userId`. Three access patterns: | Pattern | Context | How userId is available | |---------|---------|------------------------| | App code (query/mutation/action) | `auth.ctx()` | `ctx.auth.userId` and `ctx.auth.user` | | Raw HTTP (session or API key) | `auth.http.context(ctx, request)` | `authContext.userId` | | API key HTTP | `auth.http.action(...)` | `ctx.key.userId` | ### Auth-aware custom functions ```typescript // convex/functions.ts import { customMutation, customQuery } from "convex-helpers/server/customFunctions"; import { mutation, query } from "./_generated/server"; import { auth } from "./auth"; export const authQuery = customQuery(query, auth.ctx()); export const authMutation = customMutation(mutation, auth.ctx()); ``` Use `auth.ctx({ optional: true })` when the same handler should work for both guests and signed-in users. ### Raw HTTP mixed auth ```typescript http.route({ path: "/api/data", method: "GET", handler: httpAction(async (ctx, request) => { const authContext = await auth.http.context(ctx, request, { optional: true }); if (authContext.userId === null) { return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 }); } const data = await ctx.runQuery(internal.data.forUser, { userId: authContext.userId }); return Response.json(data); }), }); ``` ## Authorization patterns ### Define roles with grants ```typescript import { defineRoles } from "@robelest/convex-auth/authorization"; export const roles = defineRoles({ orgAdmin: { label: "Organization Admin",
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen