An app in app mode (gipity project auth app, or both to also offer Sign in with Gipity) has its own users: people sign in to this app only, with no Gipity account and no consent screen, and the app owns them. Use it for anything you put in front of the public; use Sign in with Gipity for your own tools and for AI apps where users pay for their AI use (see app-auth).

Using it

Turn it on in gipity.yaml (a top-level block, applied by every deploy):

auth:
  mode: app        # or both, to offer Sign in with Gipity too

(gipity project auth app sets it at once and writes that block.) Then the same client code works, with no new endpoints to call; Gipity.auth.signInAsGuest() signs a browser in as its guest with no prompt (for "no sign-in" apps):

const user = await Gipity.auth.signIn();   // opens the app's own sign-in page in a popup
// user: { guid, displayName, avatarUrl, email, provider }   (provider: 'google' | 'discord' | 'apple' | 'email')
await Gipity.auth.user();                  // the signed-in user, or null
await Gipity.auth.signOut();               // this browser
await Gipity.auth.signOutEverywhere();     // every device

The sign-in page is branded as your app (name, logo and accent color from gipity brand / the auth_branding: deploy phase) and offers each provider that is set up plus an email code. A signed-in browser holds an httpOnly session cookie for your app only (30 days, renewed on use, revocable): page JavaScript never sees a token, and another app's code can't use it.

In functions an app user is an ordinary signed-in user (ctx.auth.userGuid, displayName), plus ctx.auth.identity = { provider, id, email }. email is their verified address (null for Steam and guest players), so the app can email its own users with the email() service. Gipity-account callers have identity: null and no email.

One person is one user per app. A provider seen before signs in to its user; a new provider whose verified email matches an existing user links to that user (sign in with Google today, an email code tomorrow: same userGuid). An unverified email never links. The same person in two different apps is two separate users.

Providers and credentials. gipity project auth shows each provider's state.

Lifecycle hooks. Declare functions with hooks: in gipity.yaml (use auth: member so only the platform and you can run them):

Managing users (owner): gipity project users lists and searches them, gipity project users export --format csv -o users.csv exports all, gipity project users delete <guid> erases one (running user_deleted hooks), and gipity project users signout <guid> ends all of their sessions.

Native clients (games, mobile, desktop) don't use the page or the cookie: they sign in over HTTPS and send the returned token as Authorization: Bearer. Steam and guest devices: see steam-game. Email codes: POST /api/<PROJECT_GUID>/auth/email/start { email }, then POST /api/<PROJECT_GUID>/auth/email/verify { email, code }, which returns { data: { token, expiresIn, user } }.

Endpoint What
GET /api/<PROJECT_GUID>/auth/player The signed-in app user (guid, displayName, email, provider, providerUserId)
PATCH /api/<PROJECT_GUID>/auth/player Set or clear their display name ({ displayName }); gipity project auth --unique-names on makes names unique
DELETE /api/<PROJECT_GUID>/auth/player Erase their account (runs user_deleted hooks)
POST /api/<PROJECT_GUID>/auth/signout[?everywhere=1] End the browser session (send X-Gipity-Logout: 1); the SDK's signOut() does this

Limits. App users have no Gipity credits, so user_pays services can't bill them; those calls are billed to you (owner pays). There are no passwords, MFA or organizations; if an app needs those, it needs a dedicated identity provider.