kavachOS
AuthenticationOAuth providers

Apple

Sign in with Apple using OAuth 2.0 and OpenID Connect.

A full Sign in with Apple setup guide is coming soon. The provider works today — this page will walk through the Apple Developer Console steps in detail when complete.

Sign in with Apple uses OAuth 2.0 with some Apple-specific quirks: the client secret is a JWT you generate from a private key, and Apple only returns the user's name and email on the very first sign-in. Plan your data model accordingly.

Configuration

lib/kavach.ts
import { createKavach } from '@kavachos/core';
import { oauth } from '@kavachos/core/plugins/oauth';

const kavach = await createKavach({
  database: { provider: 'postgres', url: process.env.DATABASE_URL! },
  secret: process.env.KAVACH_SECRET!,
  baseUrl: 'https://auth.example.com',
  plugins: [
    oauth({
      providers: [
        {
          id: 'apple',
          clientId: process.env.APPLE_CLIENT_ID!,       // Your Services ID
          clientSecret: process.env.APPLE_CLIENT_SECRET!, // Generated JWT
        },
      ],
    }),
  ],
});
APPLE_CLIENT_ID=com.example.app.auth
APPLE_CLIENT_SECRET=eyJ...  # JWT signed with your .p8 private key

What you will need from Apple Developer

  • An App ID with Sign in with Apple capability enabled
  • A Services ID (this is your clientId)
  • A private key (.p8 file) used to sign the client secret JWT
  • Your Team ID and Key ID

Scopes

Default scopes: name email

Apple uses form_post response mode, which means the user data comes in a POST body on the first authorization only. KavachOS handles this automatically.

User data returned

FieldNotes
idStable Apple user identifier (24-character string)
emailMay be a private relay address (@privaterelay.appleid.com)
nameOnly returned on first authorization — store it immediately

Apple returns the user's name only once, during the first sign-in. On subsequent sign-ins, name is absent. KavachOS stores it after first auth, but make sure your getUserProfile logic accounts for this.

Register interest

Need the full setup guide sooner? Open an issue on GitHub.

On this page