> ## Documentation Index
> Fetch the complete documentation index at: https://vlyai-1c28d863.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Built-in auth

> Every vly app ships with authentication out of the box — email + password, magic links, social providers, roles, and permissions. Production-grade defaults, no third-party signup required.

Authentication in vly is **built in**. Every project starts with a working sign-up / sign-in flow, a session model, and the ability to scope data per user. You don't wire up Auth0 or Clerk; you don't think about JWTs; you just describe who can do what.

If you do want to use Clerk, Auth0, WorkOS, Firebase Auth, or Supabase Auth, vly supports them as integrations — but it's not required.

## What ships by default

<CardGroup cols={2}>
  <Card title="Email + password" icon="mail">
    Standard signup flow with email verification. Handles password resets, account recovery, and rate limiting on attempts.
  </Card>

  <Card title="Magic links" icon="wand">
    Passwordless email-based sign-in. See [Passwordless](/features/auth/passwordless).
  </Card>

  <Card title="Google OAuth" icon="chrome">
    Sign in with Google. Toggle on in workspace settings; works immediately.
  </Card>

  <Card title="GitHub OAuth" icon="github">
    Same. Toggle on, sign in.
  </Card>

  <Card title="Roles & permissions" icon="shield-check" href="/features/auth/roles-and-permissions">
    Role-based access with resource-level scoping. Owner / admin / member by default; customizable.
  </Card>

  <Card title="Session management" icon="key-round">
    Long-lived sessions with refresh, revocation, and device tracking.
  </Card>
</CardGroup>

## Adding auth to a prompt

You don't have to ask explicitly — every vly project ships with auth. To customize:

<Tabs>
  <Tab title="Enable Google sign-in">
    ```text theme={null}
    Add Google OAuth as a sign-in option, in addition to email + password.
    ```

    vly will prompt for `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET`. Get these from [Google Cloud Console → Credentials](https://console.cloud.google.com/apis/credentials).
  </Tab>

  <Tab title="Add roles">
    ```text theme={null}
    Add a `role` field to users (admin / member, default member).
    Admins can invite new users and delete any data. Members can only
    delete data they created.
    ```
  </Tab>

  <Tab title="Magic links only">
    ```text theme={null}
    Switch to magic-link-only authentication. Remove the password field
    from sign-up. On sign-in, just collect an email and send a link.
    ```
  </Tab>

  <Tab title="Multi-factor">
    ```text theme={null}
    Require 2FA via authenticator apps for users with the 'admin' role.
    Members can opt in but it's not required.
    ```
  </Tab>
</Tabs>

## How auth works under the hood

vly's auth system is built on Convex's auth primitives:

```mermaid theme={null}
sequenceDiagram
    participant Browser
    participant ConvexAuth
    participant DB
    participant App

    Browser->>ConvexAuth: sign in (email + password)
    ConvexAuth->>DB: verify credentials
    DB-->>ConvexAuth: user record
    ConvexAuth-->>Browser: session token (cookie)
    Browser->>App: open page (cookie sent)
    App->>ConvexAuth: getCurrentUser()
    ConvexAuth-->>App: user object
    App->>App: render with user context
```

A few important properties:

* **The `users` table is yours to extend.** Add custom fields (display name, avatar URL, role, plan tier) — vly's auth code reads from the same table.
* **Sessions are server-side.** No client-side JWT secrets to leak. Revoke instantly from the workspace.
* **Auth-aware queries are automatic.** Convex's `ctx.auth.getUserIdentity()` is available in every query and mutation, so scoping data to the current user is one line.

## Scoping data to the current user

The standard pattern in a Convex query:

```typescript convex/myStuff.ts theme={null}
import { query } from "./_generated/server";

export const list = query({
  args: {},
  handler: async (ctx) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) throw new Error("Not signed in");

    return await ctx.db
      .query("tasks")
      .withIndex("by_owner", (q) => q.eq("ownerId", identity.subject))
      .collect();
  },
});
```

vly generates this pattern automatically when you describe a feature with per-user data. You don't have to remember to add the auth check — it's part of the default code path.

## Roles and permissions

Most apps need more than "logged in or not." vly supports role-based scoping out of the box:

```typescript convex/teams.ts theme={null}
import { query } from "./_generated/server";
import { v } from "convex/values";

export const inviteMember = mutation({
  args: { teamId: v.id("teams"), email: v.string() },
  handler: async (ctx, { teamId, email }) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) throw new Error("Not signed in");

    // Check the caller is an admin of the team
    const membership = await ctx.db
      .query("teamMembers")
      .withIndex("by_team_and_user", (q) =>
        q.eq("teamId", teamId).eq("userId", identity.subject),
      )
      .first();

    if (!membership || membership.role !== "admin") {
      throw new Error("Only team admins can invite members");
    }

    // ... invite logic
  },
});
```

vly generates the role check automatically when you describe role-aware behavior in a prompt. See [Roles & permissions](/features/auth/roles-and-permissions) for the patterns.

## Common auth flows

<AccordionGroup>
  <Accordion title="Email verification" icon="mail-check">
    On sign-up, vly sends a verification email. The user clicks the link; their account becomes verified. Until verified, you can choose to allow limited access (default) or block sign-in entirely. Configure in **Workspace settings → Auth → Email verification**.
  </Accordion>

  <Accordion title="Password reset" icon="key">
    Built-in. The "Forgot password?" link sends a reset email. The link expires in 1 hour. Configure expiry in **Workspace settings → Auth**.
  </Accordion>

  <Accordion title="Account deletion" icon="trash">
    Users can delete their own accounts from the settings page (auto-generated for every project). Deletion cascades to user-owned data per the schema's `cascade` rules. See [Account deletion](/security/account-deletion).
  </Accordion>

  <Accordion title="Multi-factor (2FA)" icon="shield-plus">
    Authenticator-app-based 2FA is one prompt away. SMS-based 2FA is supported via the [Twilio integration](/integrations/twilio).
  </Accordion>

  <Accordion title="Single Sign-On (SSO / SAML)" icon="key-round">
    Available on Enterprise tier. Supports SAML 2.0 and OIDC. SCIM 2.0 for user provisioning. See [SSO](/features/workspace/sso).
  </Accordion>
</AccordionGroup>

## Switching to a third-party provider

If you'd prefer Clerk, Auth0, WorkOS, Firebase Auth, or Supabase Auth, all are first-class integrations:

<CardGroup cols={3}>
  <Card title="Clerk" icon="user-circle" href="/integrations/clerk">
    Pre-built UI components, social providers, and a polished management dashboard.
  </Card>

  <Card title="Auth0" icon="key" href="/integrations/auth0">
    Enterprise SSO, fine-grained access control, multi-tenant.
  </Card>

  <Card title="WorkOS" icon="building" href="/integrations/workos">
    SAML SSO + SCIM provisioning for B2B SaaS.
  </Card>
</CardGroup>

When you switch, vly migrates the user records and updates the auth-check pattern in every Convex function automatically.

## Tips

<Tip>
  **The auto-generated settings page is editable.** Every vly project ships with a `/settings/account` page that lets users update profile, password, and security settings. Edit it like any other page.
</Tip>

<Tip>
  **For multi-tenant apps, model `users` and `memberships` separately.** A user can belong to multiple workspaces; a membership is the join row that also carries the role. See [Multi-tenancy patterns](/architecture/multi-tenancy).
</Tip>

<Tip>
  **Test sign-up flows in incognito.** Real auth flows behave differently when there are no existing cookies — incognito catches more issues than refreshing your dev session.
</Tip>

## Related

<CardGroup cols={3}>
  <Card title="Passwordless" icon="wand" href="/features/auth/passwordless">
    Magic links, deep dive.
  </Card>

  <Card title="Roles & permissions" icon="shield-check" href="/features/auth/roles-and-permissions">
    The full RBAC model.
  </Card>

  <Card title="Auth flows" icon="git-branch" href="/architecture/auth-flows">
    Patterns for common auth scenarios.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.