Skip to Content
SDK ReferenceAuth Management

Auth Management (Server-Side)

Administer the end users of your project’s auth apps from your backend, using the Server SDK.

This page covers server-side user administration. For client-side user authentication (login, register, profile), see the Client SDK. Creating an auth app, changing its settings and rotating its signing keys are not in the SDK — they live in the Dashboard and the ghayma auth commands.

import { Ghayma } from "@ghayma/sdk"; const ghayma = new Ghayma({ apiKey: process.env.GHAYMA_API_KEY });

These calls need the auth capability, which the Application purpose grants. A key restricted to specific auth apps answers 404 for every other app in the project.

Verifying User Tokens

This SDK does not verify user tokens. @ghayma/sdk acts on your auth apps with a project API key, not on your end-users’ sessions.

Access tokens are RS256-signed JWTs, so your backend verifies them locally against the app’s published signing key (JWKS) with any standard JWT library — no API call per request:

import { verifyAccessToken } from "@/lib/auth"; const claims = await verifyAccessToken(token); // throws if invalid or expired console.log(claims.sub); // user id console.log(claims.email); console.log(claims.app_metadata); // roles / plan / tenant, if you set them

The lib/auth.ts helper, plus ready-made Express and Next.js middleware, is in Auth Integration → JWT Verification.

List Users

Page through the users registered in your auth app.

const { users, total, page, per_page } = await ghayma.auth.listUsers("my-app", { page: 1, per_page: 50, }); for (const user of users) { console.log(user.id, user.email, user.name, user.provider); }

Options:

NameTypeDefaultDescription
pagenumber?1Page number
per_pagenumber?20Results per page, 1–100

The first argument is the auth app — its slug (my-app) or its UUID.

App Metadata (Roles)

Set developer-owned data on a user — roles, plan, tenant id. Unlike the user-editable metadata, app_metadata can only be written from here (or the Dashboard), and it is embedded in the user’s JWT as the app_metadata claim, so your backend can authorize from the verified token with no extra lookups.

// Replace semantics — send the full object; {} clears it. Max 8KB. await ghayma.auth.updateUserAppMetadata("my-app", "user-id", { roles: ["admin"], plan: "pro", });

Then on your server, after verifying the JWT:

const roles = (claims.app_metadata?.roles as string[]) ?? []; if (!roles.includes("admin")) throw new Error("forbidden");

Notes:

  • Requires the admin or owner role on the project — read/write collaborators get 403.
  • Changes reach the user’s tokens at their next refresh (up to the JWT expiry, 15 min by default). If a role change can’t wait, disabling the user ends their sessions; once re-enabled they sign in again with the new roles. A backend that verifies tokens itself still accepts an older token until it expires — see Ending every session.
  • Every change is audit-logged.

Mint a password-reset link for a user — for apps that send reset emails through their own transport and templates instead of Ghayma’s. This is the full-control alternative to the custom reset page (where Ghayma still sends the email).

const { link, expires_at } = await ghayma.auth.generatePasswordResetLink( "my-app", "[email protected]" ); // Put `link` in your own email template and send it.

The link points at your configured reset page (reset_url) when set, or the hosted form otherwise, and behaves exactly like an emailed link: single-use, expires in 1 hour, and minting invalidates any previously issued reset link for that user.

Handle the link like a password:

  • Send it to the user’s verified email address — never over chat, SMS, or URLs you don’t control, and never log it.
  • Requires the admin or owner role on the project (403 otherwise), and is strictly rate-limited per app (429).
  • Every mint is recorded in the audit log (without the link itself).

Reset a User’s 2FA

The support hammer for a locked-out user (lost phone and recovery codes): clears their entire 2FA enrolment so they can sign in again — with a password, Google or GitHub — and re-enrol. It is also the way out for a user asked for a code they never set up after a Google or GitHub sign-in took over their account. Requires the admin or owner role; audited.

await ghayma.auth.resetUser2FA("my-app", "user-id");

Disable / Enable User

// Disable (block login) await ghayma.auth.disableUser("my-app", "user-id"); // Re-enable await ghayma.auth.enableUser("my-app", "user-id");

Disabling ends every session of the user at once, and a disabled user cannot sign in. Re-enabling lets them sign in again; nothing from before the disable comes back.

Delete User

await ghayma.auth.deleteUser("my-app", "user-id");

This permanently deletes the user account. The user will need to re-register.

Auth App Details

Read-only. Everything that changes an app — create, configure, rotate keys, delete — is in the Dashboard and the ghayma auth commands.

List Auth Apps

const apps = await ghayma.auth.listApps();

With a project API key this lists the apps of the key’s own project — and only those. A restricted key still sees the whole list; it just answers 404 when you act on an app outside its restriction. With an account token the call lists your account’s auth apps instead.

Get Auth App

const app = await ghayma.auth.getApp("my-app");

Get Statistics

const stats = await ghayma.auth.getStats("my-app"); console.log(stats.total_users); // 1542 console.log(stats.logins_today); // 87