| name | notion-enterprise-rbac |
| description | Configure Notion enterprise access control with OAuth, workspace permissions, and audit logging.
Use when implementing OAuth public integrations, managing multi-workspace access,
or building permission-aware Notion applications.
Trigger with phrases like "notion SSO", "notion RBAC",
"notion enterprise", "notion OAuth", "notion permissions", "notion multi-workspace".
|
| allowed-tools | Read, Write, Edit |
| version | 1.38.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","productivity","notion"] |
| compatibility | Designed for Claude Code |
Notion Enterprise RBAC
Overview
Implement enterprise-grade access control for Notion integrations. This covers the full OAuth 2.0 authorization flow for public integrations (multi-tenant), per-workspace token storage with encryption at rest, Notion's page-level permission model and how to handle ObjectNotFound vs RestrictedResource, an application-level role system (admin/editor/viewer) layered on top of Notion's permissions, comprehensive audit logging to a Notion database, and workspace deauthorization cleanup.
Prerequisites
- Notion public integration created at https://www.notion.so/my-integrations (for OAuth)
@notionhq/client v2+ installed (npm install @notionhq/client)
- Python alternative:
notion-client (pip install notion-client)
- Database for storing per-workspace tokens (PostgreSQL, DynamoDB, etc.)
- HTTPS endpoint for OAuth callback (required by Notion)
Instructions
The workflow has three steps. Each is summarized here with its key entry
point; the complete, copy-ready code for all three lives in
the full implementation reference.
Step 1: OAuth 2.0 Authorization Flow
Notion uses OAuth 2.0 for public integrations to reach external workspaces.
Build an authorization URL with a random state for CSRF protection, redirect
the user, then on callback verify the state and exchange the code for a
workspace access token. Notion's token endpoint uses HTTP Basic auth with your
client id and secret:
function getAuthorizationUrl(state: string): string {
const params = new URLSearchParams({
client_id: process.env.NOTION_OAUTH_CLIENT_ID!,
response_type: 'code',
owner: 'user',
redirect_uri: process..!,
state,
});
;
}