Skip to main content

Authentication & Authorization

The GraphQL API integrates with next-auth for authentication and implements role-based access control with OAuth scope preparation.

How Authentication Works

  1. Session-based authentication - The GraphQL context extracts the user session from next-auth cookies
  2. Automatic context creation - Each request creates a fresh context with user info and authorization helpers
  3. Resolver-level authorization - Each resolver checks authentication and authorization requirements

Context

Every resolver receives a context object with:

  • req - The original Next.js request
  • isAuthenticated - Whether the request is authenticated
  • user - The authenticated user info (id, email, name, image)
  • session - The raw next-auth session
  • hasScope(scope) - Check if user has a specific OAuth scope
  • canAccessResource(ownerId) - Check if user can access a resource

See apps/web/src/lib/graphql/context.ts for the full implementation.

OAuth Scopes

ScopeDescription
profile:readRead user profile data
profile:writeCreate and update user profiles
organization:readRead organization data
organization:writeCreate and update organizations
organization:members:readRead organization membership
organization:members:writeAdd/remove organization members
adminFull administrative access

Currently, authenticated users receive default scopes. In a future OAuth implementation, scopes will be derived from OAuth tokens.

Scopes are defined in packages/shared-graphql/src/types.ts.

Schema Directive

The @auth directive declaratively specifies authorization requirements on types and fields:

  • @auth(requires: USER) - Requires authentication
  • @auth(requires: ADMIN) - Requires admin role

Error Handling

Authentication errors throw GraphQL errors with code UNAUTHENTICATED. Authorization errors return response wrappers with error code FORBIDDEN.

Authorization in Resolvers

Use the helper functions from apps/web/src/lib/graphql/common/utils.ts:

  • requireAuth(context) - Throws if not authenticated
  • requireScope(context, scope) - Requires authentication and checks scope

Future OAuth Integration

The authentication system is designed to be extended with OAuth:

  1. Token-based scopes - OAuth tokens will carry granted scopes
  2. Scope validation - context.hasScope() will check token scopes
  3. Directive integration - The @auth directive will validate scopes
  4. Client credentials - Support for machine-to-machine authentication