Getting Started

Quick Start

Get OpenApe running in minutes.

Quick Start

Add a DNS Record

Point your domain to your IdP by adding a TXT record:

_ddisa.example.com TXT "v=ddisa1; idp=https://id.example.com; mode=strict"

Deploy the IdP

The fastest way is a Nuxt app with the @openape/nuxt-auth-idp module:

npx nuxi init my-idp
cd my-idp
pnpm add @openape/nuxt-auth-idp

Configure nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['@openape/nuxt-auth-idp'],
  openapeIdp: {
    rpName: 'My Identity Provider',
    rpID: 'id.example.com',
    rpOrigin: 'https://id.example.com',
    issuer: 'https://id.example.com',
    // sessionSecret: set NUXT_OPENAPE_IDP_SESSION_SECRET in production
  },
})

All routes are auto-registered: /login, /register, /authorize, /token, /.well-known/jwks.json, and the full admin API.

For persistent storage, register a store backend from a Nitro plugin. See the openape-free-idp reference app for a wired-up Drizzle + libsql/Turso example, or read the Free-IdP Hosting Guide.

Deploy the SP

For a service that accepts OpenApe login:

pnpm add @openape/nuxt-auth-sp
export default defineNuxtConfig({
  modules: ['@openape/nuxt-auth-sp'],
})

That's it for development — the module auto-generates secrets and derives clientId from your dev server. Add a login page:

<template>
  <OpenApeAuth />
</template>

For production, set clientId and sessionSecret:

export default defineNuxtConfig({
  modules: ['@openape/nuxt-auth-sp'],
  openapeSp: {
    clientId: 'myapp.example.com',
  },
})
NUXT_OPENAPE_SP_SESSION_SECRET=$(openssl rand -hex 32)

The SP is fully stateless — OAuth flow state lives in signed cookies. Zero server storage needed.

See the nuxt-auth-sp docs for full configuration reference.

Environment Variables

Both modules follow Nuxt's runtimeConfig convention: openapeIdp.* options map to NUXT_OPENAPE_IDP_*, openapeSp.* options map to NUXT_OPENAPE_SP_*. Camel-case keys are upper-snake-case-ified.

IdP (common vars)

VariableDescriptionDefault
NUXT_OPENAPE_IDP_RP_IDRelying Party ID (domain)'' (falls back to request host)
NUXT_OPENAPE_IDP_RP_ORIGINRelying Party origin URL'' (falls back to request origin)
NUXT_OPENAPE_IDP_RP_NAMEDisplay name''
NUXT_OPENAPE_IDP_ISSUERJWT iss claim'' (falls back to request origin)
NUXT_OPENAPE_IDP_RP_HOST_ALLOW_LISTComma-separated multi-tenant hostnames''
NUXT_OPENAPE_IDP_SESSION_SECRETSession cookie secret (32+ chars)change-me… (warn in prod)
NUXT_OPENAPE_IDP_ADMIN_EMAILSComma-separated admin emails''
NUXT_OPENAPE_IDP_MANAGEMENT_TOKENBearer for management API''
NUXT_OPENAPE_IDP_ALLOWED_FRAME_ANCESTORSSpace-separated origins allowed to embed the IdP in an iframe'' (frame-ancestors 'none')

The full option surface is documented in nuxt-auth-idp.

SP

VariableDescriptionDefault
NUXT_OPENAPE_SP_CLIENT_IDService Provider ID'' (dev: localhost:{port})
NUXT_OPENAPE_SP_SP_NAMEDisplay nameOpenApe Service Provider
NUXT_OPENAPE_SP_SESSION_SECRETSession encryption secret (32+ chars)auto-generated in dev
NUXT_OPENAPE_SP_OPENAPE_URLDirect IdP URL (bypasses DDISA discovery)''
NUXT_OPENAPE_SP_FALLBACK_IDP_URLFallback when DNS has no DDISA recordhttps://id.openape.at

Create Your First User

Use the management API to create a registration URL:

curl -X POST https://id.example.com/api/admin/registration-urls \
  -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","name":"Alice"}'

Open the returned URL in a browser to register a Passkey. Done.