본문으로 건너뛰기
cccskills
무료GitHub에 공개

convex-setup-auth

Set up Convex authentication with proper user management, identity mapping, and access control patterns. Use when implementing auth flows, setting up OAuth providers, or adding role-based access control.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Convex Authentication Setup

Implement secure authentication in Convex with user management and access control.

When to Use

  • Setting up authentication for the first time
  • Implementing user management (users table, identity mapping)
  • Creating authentication helper functions
  • Setting up auth providers (Convex Auth, Clerk, WorkOS AuthKit, Auth0, custom JWT)

First Step: Choose the Auth Provider

Do not assume a provider. Before writing setup code:

  1. Ask the user which auth solution they want, unless the repository already makes it obvious
  2. If the repo already uses a provider, continue with that provider unless the user wants to switch
  3. If the user has not chosen and the repo does not make it obvious, ask before proceeding

Common options:

  • Convex Auth: good default when the user wants auth handled directly in Convex
  • Clerk: use when the app already uses Clerk
  • WorkOS AuthKit: use when the app already uses WorkOS
  • Auth0: use when the app already uses Auth0
  • Custom JWT provider: use when integrating an existing auth system

Look for signals in the repo before asking:

  • Dependencies such as @clerk/*, @workos-inc/*, @auth0/*
  • Existing files such as convex/auth.config.ts, auth middleware, provider wrappers
  • Environment variables that clearly point at a provider

Schema Setup

// convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  users: defineTable({
    tokenIdentifier: v.string(),
    name: v.string(),
    email: v.string(),
    pictureUrl: v.optional(v.string()),
    role: v.union(v.literal("user"), v.literal("admin")),
    createdAt: v.number(),
    updatedAt: v.optional(v.number()),
  })
    .index("by_token", ["tokenIdentifier"])
    .index("by_email", ["email"]),
});

Core Helper Functions

Get Current User

// convex/lib/auth.ts
import { QueryCtx, MutationCtx } from "./_generated/server";
import { Doc } from "./_generated/dataModel";

export async function getCurrentUser(
  ctx: QueryCtx | MutationCtx
): Promise<Doc<"users">> {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) throw new Error("Not authenticated");

  const user = await ctx.db
    .query("users")
    .withIndex("by_token", q =>
      q.eq("tokenIdentifier", identity.tokenIdentifier)
    )
    .unique();

  if (!user) throw new Error("User not found");
  return user;
}

export async function getCurrentUserOrNull(
  ctx: QueryCtx | MutationCtx
): Promise<Doc<"users"> | null> {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) return null;

  return await ctx.db
    .query("users")
    .withIndex("by_token", q =>
      q.eq("tokenIdentifier", identity.tokenIdentifier)
    )
    .unique();
}

export async function requireAdmin(
  ctx: QueryCtx | MutationCtx
): Promise<Doc<"users">> {
  const user = await getCurrentUser(ctx);
  if (user.role !== "admin") throw new Error("Admin access required");
  return user;
}

User Creation/Upsert

// convex/users.ts
import { mutation } from "./_generated/server";
import { v } from "convex/values";

export const storeUser = mutation({
  args: {},
  handler: async (ctx) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) throw new Error("Not authenticated");

    const existingUser = await ctx.db
      .query("users")
      .withIndex("by_token", q =>
        q.eq("tokenIdentifier", identity.tokenIdentifier)
      )
      .unique();

    if (existingUser) {
      await ctx.db.patch(existingUser._id, { updatedAt: Date.now() });
      return existingUser._id;
    }

    return await ctx.db.insert("users", {
      tokenIdentifier: identity.tokenIdentifier,
      name: identity.name ?? "Anonymous",
      email: identity.email ?? "",
      pictureUrl: identity.pictureUrl,
      role: "user",
      createdAt: Date.now(),
    });
  },
});

Access Control Patterns

Resource Ownership

export const deleteTask = mutation({
  args: { taskId: v.id("tasks") },
  handler: async (ctx, args) => {
    const user = await getCurrentUser(ctx);
    const task = await ctx.db.get(args.taskId);
    if (!task) throw new Error("Task not found");
    if (task.userId !== user._id) throw new Error("You can only delete your own tasks");
    await ctx.db.delete(args.taskId);
  },
});

Team-Based Access

async function requireTeamAccess(
  ctx: MutationCtx,
  teamId: Id<"teams">
): Promise<{ user: Doc<"users">, membership: Doc<"teamMembers"> }> {
  const user = await getCurrentUser(ctx);
  const membership = await ctx.db
    .query("teamMembers")
    .withIndex("by_team_and_user", q =>
      q.eq("teamId", teamId).eq("userId", user._id)
    )
    .unique();

  if (!membership) throw new Error("You don't have access to this team");
  return { user, membership };
}

Checklist

  • Chosen the correct auth provider before writing setup code
  • Users table with tokenIdentifier index
  • getCurrentUser helper function
  • storeUser mutation for first sign-in
  • Authentication check in all protected functions
  • Authorization check for resource access
  • Clear error messages ("Not authenticated", "Unauthorized")
  • Client auth provider configured

Source: https://github.com/get-convex/agent-skills

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

adapt

무료

Adapt designs to work across different screen sizes, devices, contexts, or platforms. Implements breakpoints, fluid layouts, and touch targets. Use when the user mentions responsive design, mobile layouts, breakpoints, viewport adaptation, or cross-device compatibility.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

waynesutton/waynesutton-ai22026년 9월 8일 업데이트

Agent Ready project design context for navigation, docs links, and interface tone. Use when building or reviewing UI in this repo so patterns match the documented product feel.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

waynesutton/waynesutton-ai22026년 9월 8일 업데이트

animate

무료

Review a feature and enhance it with purposeful animations, micro-interactions, and motion effects that improve usability and delight. Use when the user mentions adding animation, transitions, micro-interactions, motion design, hover effects, or making the UI feel more alive.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

waynesutton/waynesutton-ai22026년 9월 8일 업데이트

arrange

무료

Improve layout, spacing, and visual rhythm. Fixes monotonous grids, inconsistent spacing, and weak visual hierarchy. Use when the user mentions layout feeling off, spacing issues, visual hierarchy, crowded UI, alignment problems, or wanting better composition.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

waynesutton/waynesutton-ai22026년 9월 8일 업데이트

audit

무료

Run technical quality checks across accessibility, performance, theming, responsive design, and anti-patterns. Generates a scored report with P0-P3 severity ratings and actionable plan. Use when the user wants an accessibility check, performance audit, or technical quality review.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

waynesutton/waynesutton-ai22026년 9월 8일 업데이트

Layout structure for web interfaces, from grouping and alignment to reading order, progressive disclosure, and adaptive breakpoints. Use when structuring a page or component, spacing or aligning controls, deciding what collapses at small sizes, handling RTL layout direction, or reviewing frontend code for layout. Triggers on layout, spacing, alignment, grouping, negative space, whitespace, visual hierarchy, reading order, progressive disclosure, breakpoints, responsive layout, container queries, safe area, full-bleed, edge-to-edge, layout margins, RTL layout, logical properties.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

waynesutton/waynesutton-ai22026년 9월 8일 업데이트

waynesutton의 스킬 모두 보기

이 스킬의 문제 신고