No results found.

Getting Started

Register an app, wire the SDK, ship.

Getting Started

End-to-end walkthrough — from “I have a SvelteKit/Next.js/Laravel app” to “users are logging in via WolfieAuth”. Total wall-clock time: 5–10 minutes if you copy-paste, longer if you stop to read.

1. Register your app at the WolfieAuth admin

Go to auth.wolfieguard.com/admin/clients/new and fill in:

FieldWhat to put
NameHuman-readable, e.g. “Acme CRM”
App slugLowercase short name, e.g. crm — gets auto-prefixed to <yourOrgSlug>-crm so two orgs can both have a “crm” without collision
Redirect URIsWhere WolfieAuth sends users back after login. SvelteKit/React: https://your-app.com/auth/callback. Next.js Auth.js: https://your-app.com/api/auth/callback/wolfieauth. WordPress: https://your-site.com/wp-admin/admin-ajax.php?action=wolfieauth_callback. Perfex: https://your-perfex.com/wolfieauth_client/callback
TrustedEnable for your own apps so the consent screen is skipped on every login. Leave OFF for third-party apps
Owner orgDefaults to your active org — the org whose Stripe Connect account receives plan revenue

You’ll get back a clientId and a clientSecret (shown ONCE — store immediately). Add them to your app’s env:

WOLFIEAUTH_ISSUER=https://auth.wolfieguard.com
WOLFIEAUTH_CLIENT_ID=youorgslug-crm
WOLFIEAUTH_CLIENT_SECRET=<from-admin-panel>

2. Pick a SaaS RBAC template

Most apps fit one of five canonical shapes. Apply one in /admin/clients/<id>#users → Roles → 📋 Use template:

TemplateRolesBest for
SoloOwnerPersonal tools, founder-only
B2B TeamAdmin / Editor / ViewerCRM, project mgmt
B2B HierarchicalAdmin / Billing-Admin / Editor / Auditor / ViewerAccounting, ERP
MarketplaceVendor-Admin / Vendor-Staff / CustomerMulti-vendor stores
Internal ToolSuper-Admin / Tenant-Admin / Member / AuditorPlatform-owner + sub-tenants

Each role’s permissions[] uses canonical strings like members.invite / billing.read / plans.write. Your downstream app reads them from claims.wolfieauth_permissions[]. Mix and match — apply the template, then add a custom role for your specific niche need.

3. Drop in the SDK

Pick the matching SDK from the SDKs page. For a SvelteKit example:

$ npm install @wolfieauth/sdk-sveltekit
// src/hooks.server.ts
import { sequence } from '@sveltejs/kit/hooks';
import { createWolfieAuthHandle, pendingApprovalGate } from '@wolfieauth/sdk-sveltekit/server';

const auth = createWolfieAuthHandle({
  template: {
    id: 'guest-request',
    issuer:   process.env.WOLFIEAUTH_ISSUER!,
    clientId: process.env.WOLFIEAUTH_CLIENT_ID!,
    branding: { appName: 'Acme CRM' },
  },
  sessionSecret: process.env.SESSION_SECRET!,
});

export const handle = sequence(auth, pendingApprovalGate);
<!-- src/routes/auth/login/+page.svelte -->
<script>
  import { LoginPage } from '@wolfieauth/sdk-sveltekit/components';
  export let data;
</script>
<LoginPage config={data.loginConfig} />

That’s it for SvelteKit. Same shape for Next.js, Express, Django, Laravel — see the SDKs page for each.

4. Mirror the user into your app DB

Every app needs local Organization + OrgMembership rows so its own queries can FK to org-id. Mirror happens on first OIDC callback per (user × org) in the SDK middleware:

const mirror: Handle = async ({ event, resolve }) => {
  const c = event.locals.session?.claims;
  if (!c) return resolve(event);

  const org = await prisma.organization.upsert({
    where:  { wolfieauthOrgId: c.wolfieauth_org_id },
    create: {
      name:            c.wolfieauth_org_name,
      type:            c.wolfieauth_org_tier === 'PLATFORM' ? 'SUPER' : 'CLIENT',
      wolfieauthOrgId: c.wolfieauth_org_id,
      wolfieauthSlug:  c.wolfieauth_org_slug,
    },
    update: { name: c.wolfieauth_org_name },
  });

  await prisma.orgMembership.upsert({
    where:  { userId_organizationId: { userId: c.sub, organizationId: org.id } },
    create: { userId: c.sub, organizationId: org.id, role: mapRole(c.wolfieauth_role_slug) },
    update: { role: mapRole(c.wolfieauth_role_slug) },
  });

  event.locals.org = org;
  return resolve(event);
};

Critical invariant: No local User table. WolfieAuth IS your user table. Store userId = sub everywhere; refresh user details (name, email, avatar) from /userinfo when you need them, cache in-process for ~5 minutes. This eliminates an entire class of stale-record bugs.

5. Your app reads claims to gate features

import { hasActiveFeature, isApproved } from '@wolfieauth/sdk-core/oidc/claims';

if (!isApproved(claims)) return redirect('/auth/pending');

if (hasActiveFeature(claims, 'youorgslug-crm', 'ksef_enabled')) {
  // user has the KSeF feature on their active org's subscription
}

The wolfieauth_features[] claim is a flat ["<appClientId>:<feature>", …] array — hasFeature() looks across every active subscription on every org the user belongs to (union mode), hasActiveFeature() filters to the user’s currently-selected org (workspace mode). Pick whichever model fits your app.

What’s next

Last updated: