OAuth and RBAC | Kyzen | Primitives Docs

OAuth and RBAC

Configure provider login, define roles, and check permissions

OAuth providers

The package currently includes built-in provider wiring for:

  • GitHub
  • Google

Configure providers via the oauth option on kyzenAuthMiddleware({...}):

// src/middleware.ts
kyzenAuthMiddleware({
  oauth: {
    providers: {
      github: {
        clientIdEnv: 'GITHUB_CLIENT_ID',
        clientSecretEnv: 'GITHUB_CLIENT_SECRET',
      },
      google: {
        clientIdEnv: 'GOOGLE_CLIENT_ID',
        clientSecretEnv: 'GOOGLE_CLIENT_SECRET',
      },
    },
    loginRedirect: '/admin',
  },
});

Provider client IDs and secrets are looked up from env at request time using the env var names you specify — keep the literal values in Cloudflare secrets, not in code.

Runtime helpers:

  • getOAuthData()
  • startOAuth(formData)
  • handleOAuthCallback()
  • getOAuthProviders()

The callback flow:

  • verifies state
  • exchanges the code for tokens
  • fetches the profile
  • creates or links the user
  • stores encrypted OAuth tokens
  • creates a normal auth session

Roles

Define role mappings with defineRoles():

const Roles = defineRoles({
  admin: ['*'],
  editor: ['posts.*', 'users.read'],
  user: ['posts.read'],
}, {
  defaultRole: 'user',
});

Available helpers:

  • hasRole(user, role)
  • hasPermission(user, permission)
  • getPermissionsForRole(role)
  • getRoleDefinitions()
  • getAllRoles()
  • getDefaultRole()

Wildcard behavior:

  • * matches everything
  • posts.* matches posts.read, posts.create, and the base posts namespace

Assigning roles

assignRole(formData) reads:

  • userId
  • role

and requires the current user to have users.update.

Activity helpers

The auth package also includes built-in activity logging:

  • defineActivities()
  • logActivity()
  • getActivity()
  • getActivityDefinitions()

Use this layer for audit-friendly auth and admin events.