Quick Start
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)
| Variable | Description | Default |
|---|---|---|
NUXT_OPENAPE_IDP_RP_ID | Relying Party ID (domain) | '' (falls back to request host) |
NUXT_OPENAPE_IDP_RP_ORIGIN | Relying Party origin URL | '' (falls back to request origin) |
NUXT_OPENAPE_IDP_RP_NAME | Display name | '' |
NUXT_OPENAPE_IDP_ISSUER | JWT iss claim | '' (falls back to request origin) |
NUXT_OPENAPE_IDP_RP_HOST_ALLOW_LIST | Comma-separated multi-tenant hostnames | '' |
NUXT_OPENAPE_IDP_SESSION_SECRET | Session cookie secret (32+ chars) | change-me… (warn in prod) |
NUXT_OPENAPE_IDP_ADMIN_EMAILS | Comma-separated admin emails | '' |
NUXT_OPENAPE_IDP_MANAGEMENT_TOKEN | Bearer for management API | '' |
NUXT_OPENAPE_IDP_ALLOWED_FRAME_ANCESTORS | Space-separated origins allowed to embed the IdP in an iframe | '' (frame-ancestors 'none') |
The full option surface is documented in nuxt-auth-idp.
SP
| Variable | Description | Default |
|---|---|---|
NUXT_OPENAPE_SP_CLIENT_ID | Service Provider ID | '' (dev: localhost:{port}) |
NUXT_OPENAPE_SP_SP_NAME | Display name | OpenApe Service Provider |
NUXT_OPENAPE_SP_SESSION_SECRET | Session encryption secret (32+ chars) | auto-generated in dev |
NUXT_OPENAPE_SP_OPENAPE_URL | Direct IdP URL (bypasses DDISA discovery) | '' |
NUXT_OPENAPE_SP_FALLBACK_IDP_URL | Fallback when DNS has no DDISA record | https://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.