Ecosystem

OpenApe Auth

DNS-based identity for humans and agents.

OpenApe Auth

@openape/core

The foundation package. Framework-agnostic, zero dependencies.

  • DNS Discovery β€” resolve _ddisa.{domain} TXT records to find the IdP
  • PKCE β€” code challenge/verifier generation for secure OAuth flows
  • JWT β€” sign, verify, and validate DDISA assertion tokens
  • Types β€” DDISAAssertionClaims, ActorType, AuthFlowState, etc.

@openape/auth

Complete OIDC login protocol logic β€” both sides in one package.

IdP Side

  • handleAuthorize() β€” validate authorization requests
  • handleTokenExchange() β€” exchange codes for signed assertions
  • issueAssertion() β€” create minimal AuthN-JWTs with act claim
  • WebAuthn β€” createRegistrationOptions(), verifyRegistration(), createAuthenticationOptions(), verifyAuthentication()

SP Side

  • discoverIdP() β€” DNS-based IdP discovery via DoH
  • createAuthorizationURL() β€” build OAuth redirect with PKCE
  • handleCallback() β€” exchange code, validate assertion

@openape/nuxt-auth-idp

Drop-in Nuxt module. Add it, configure it, you're an IdP.

Auto-registered routes:

  • /login, /register, /account β€” Passkey-based UI (overridable)
  • /admin β€” User and agent management
  • /authorize, /token β€” OAuth endpoints
  • /.well-known/jwks.json β€” Public key discovery
  • /api/webauthn/* β€” Registration and login flows
  • /api/session/ssh-keys β€” SSH-key enrollment and listing (see below)
  • /api/auth/* β€” Unified challenge/authenticate for SSH-key auth (humans + agents)
  • /api/admin/* β€” User, agent, and registration URL management

Configuration via openapeIdp in nuxt.config.ts:

openapeIdp: {
  rpName: 'My IdP',
  rpID: 'id.example.com',
  rpOrigin: 'https://id.example.com',
  requireUserVerification: true,  // NIS2 strict mode
  residentKey: 'required',        // true passkey experience
  attestationType: 'none',        // or 'direct' for enterprise
}

See the dedicated nuxt-auth-idp docs for the full module option surface, environment variables, and store interfaces.

SSH-key authentication

Alongside passkeys, the IdP accepts Ed25519 SSH keys as a first-class credential for agents (and humans who prefer key-based auth, e.g. CI scripts). Keys are email-keyed β€” they are not bound to an RP, so the same SSH key authenticates against every hostname the IdP serves.

Manage keys on a logged-in user account:

RoutePurpose
GET /api/session/ssh-keysList keys registered to the caller's account
POST /api/session/ssh-keysAdd a public key β€” body { publicKey: string, name?: string }
DELETE /api/session/ssh-keys/:keyIdRemove a key

The publicKey field accepts the standard OpenSSH one-line format (ssh-ed25519 AAAA… comment). The comment is captured as the key's display name if name is omitted.

Authenticate with an SSH key (challenge/response, used by @openape/apes and escapes):

POST /api/auth/challenge   { email, publicKey }
β†’  { challenge: "<random>", challengeId: "<id>" }

(client signs the challenge with the matching private key)

POST /api/auth/authenticate  { challengeId, signature }
β†’  { token: "<JWT>" }

The returned JWT carries the same act claim discipline as passkey sessions (human or agent). SPs verifying the token do not need to distinguish the authentication method.

Admin-side key management is available at /api/admin/users/:email/ssh-keys β€” GET, POST, DELETE /:keyId β€” for operators provisioning CI or agent keys on behalf of users.

@openape/nuxt-auth-sp

Drop-in Nuxt module. Stateless. Zero server storage.

Auto-registered routes:

  • /api/login β€” initiate DDISA login flow
  • /api/callback β€” handle OAuth callback
  • /api/logout β€” destroy session
  • /api/me β€” current user info
  • /.well-known/sp-manifest.json β€” SP metadata

Composable: useOpenApeAuth() for client-side auth state.

Component: <OpenApeAuth /> β€” prebuilt login form with customizable slots and CSS variables.

See the dedicated nuxt-auth-sp docs for full API reference.