How to Integrate Kinde with Your Headless CMS
Connect Kinde to your structured content so roles, permissions, organizations, and gated experiences stay in sync when editors publish changes.
What is Kinde?
Kinde is an authentication and identity platform for web and SaaS applications. It handles login, signup, social auth, SSO, multi-factor authentication, roles, permissions, organizations, and user management. Product and engineering teams use Kinde when they need developer-friendly auth without building identity flows from scratch.
Why integrate Kinde with a headless CMS?
Auth rules change more often than most teams expect. A pricing page adds a new plan, a help center adds partner-only articles, or a SaaS product introduces organization-level content. If Kinde controls who can access something, and your headless CMS controls what that thing says, those two systems need to agree.
Connecting Kinde to structured content lets you treat access rules as part of the content workflow instead of a separate spreadsheet. For example, an editor can publish a Sanity document with a permission key like "content.guides.pro.read", and a webhook or Sanity Function can create or update that permission in Kinde. Your frontend can then use Kinde session claims to decide whether to show the content, hide it, or ask the user to upgrade.
The disconnected version gets messy fast. Someone updates roles in Kinde, someone else edits gated pages, and a third person manually checks whether the access matrix still matches production. With Sanity, content is structured as typed JSON in the Content Lake, GROQ can select only the fields Kinde needs, and webhooks can trigger the sync when content is published, updated, or deleted.
Architecture overview
A typical Kinde and Sanity integration starts in Sanity Studio, where developers model access-related content as schema fields: permission keys, required roles, organization rules, plan labels, and gated content references. When an editor publishes one of those documents, a Sanity webhook fires with the document ID and mutation type. The webhook can call a Sanity Function or your own API route. That server-side code uses @sanity/client and GROQ to fetch the current published document from the Content Lake, including joined references such as roles or plans. It then requests a machine-to-machine access token from Kinde using the OAuth 2.0 client credentials flow, with the audience set to the Kinde Management API. With that token, the function calls Kinde's Management API to create or update permissions, roles, or organization metadata. At runtime, the end user signs in through a Kinde SDK, such as the Next.js SDK. Kinde returns session claims that include user, organization, role, and permission data. Your frontend uses those claims to render the right Sanity-powered experience, such as premium guides, customer-specific onboarding, or admin-only product documentation.
Common use cases
Permission-based content gates
Publish access policies in Sanity, sync permission keys to Kinde, and show premium articles only to users with matching permissions.
Organization-specific portals
Map Sanity content to Kinde organization codes so each customer sees the right docs, onboarding steps, and announcements.
Role-aware product education
Use Kinde roles like admin, billing manager, or member to personalize product guides and in-app help from the same content source.
Plan-aware SaaS experiences
Connect Sanity plan content with Kinde permissions so pricing copy, upgrade prompts, and gated features stay aligned.
Step-by-step integration
- 1
Set up Kinde
Create a Kinde account, add your application, configure callback URLs, and install the SDK for your app, such as @kinde-oss/kinde-auth-nextjs for Next.js. For server-to-server sync, create a machine-to-machine application, authorize it for the Kinde Management API, and copy the Kinde domain, client ID, and client secret into environment variables.
- 2
Model access rules in Sanity Studio
Create schema types for access policies, plans, roles, or gated content. Include fields such as title, permissionKey, description, requiredRole, organizationCode, and references to the content that should use the rule.
- 3
Create a publish trigger
Add a Sanity webhook that fires on create, update, and delete events for your access policy documents. Use a GROQ filter such as _type == "accessPolicy" so you don't sync unrelated content changes.
- 4
Add server-side sync logic
Use a Sanity Function, API route, or small worker to receive the webhook. Fetch the published document from the Content Lake with @sanity/client and GROQ, then call Kinde's OAuth token endpoint and Management API from the server. Don't expose the Kinde client secret in browser code.
- 5
Connect the frontend experience
Use the Kinde SDK in your frontend to handle login, logout, session checks, roles, permissions, and organization context. Use those claims to decide which Sanity content to query, render, or hide.
- 6
Test with real roles
Create at least three test users: one with no gated permissions, one with a paid-plan permission, and one organization admin. Publish a Sanity access policy, confirm it appears in Kinde, and verify that each user sees the expected content.
How Sanity + Kinde works
Build your Kinde integration on Sanity
Use Sanity as your AI Content Operating System for structured content, real-time publish events, and flexible APIs that connect cleanly with Kinde.
Start building free →CMS approaches to Kinde
| Capability | Traditional CMS | Sanity |
|---|---|---|
| Access rule structure | Access rules often live in plugins, page settings, or custom fields that are hard to reuse outside the site. | Access policies can be modeled as schema-backed documents with references across roles, plans, organizations, and gated content. |
| Sync timing to Kinde | Teams often rely on manual updates, scheduled jobs, or plugin hooks that vary by deployment. | Webhooks and Functions can trigger Kinde sync on content mutations without a separate worker or polling job. |
| Field-level API control | API responses may include full pages, rendered HTML, or extra fields your Kinde sync doesn't need. | GROQ can fetch exactly the permission key, role references, plan metadata, and gated content IDs in one query. |
| Frontend authorization flow | Content gating is often tied to server-rendered templates or membership plugins. | Your app can use Kinde session claims and Sanity queries together, while editors still work with clear fields in Sanity Studio. |
| Multi-channel gated content | Gated rules usually center on one website, with mobile or in-app experiences handled separately. | The same access policy documents can feed web, mobile, Kinde, and AI agent experiences from the Content Lake. |
Keep building
Explore related integrations to complete your content stack.
Sanity + Auth0
Connect structured content with Auth0 roles, rules, and app metadata for gated web and SaaS experiences.
Sanity + Clerk
Use Clerk user sessions and organization data to personalize Sanity-powered dashboards, docs, and onboarding flows.
Sanity + Firebase Auth
Pair Firebase Auth users with structured Sanity content for role-aware apps across web and mobile.