-
-
Notifications
You must be signed in to change notification settings - Fork 38
blog: better auth multi-tenancy #409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis pull request introduces a new guide on building multi-tenant applications using the Better-auth framework and ZenStack, detailing the architecture and setup of a sample Todo List application. Additionally, it includes modifications to an existing guide on StackAuth to improve text clarity and correctness. Updates to the Clerk integration documentation enhance user management and authentication details, providing new examples and references for multi-tenant setups. Changes
Possibly related PRs
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (5)
blog/better-auth/index.mdx (5)
75-85: Consider using a production-grade database.While SQLite is great for development and demos, consider recommending PostgreSQL or MySQL for production deployments, especially for multi-tenant applications where data isolation and concurrent access are important.
227-247: Add indexes for better query performance.Consider adding indexes for:
- Foreign key fields (
ownerId,organizationId,listId)- Commonly queried fields (
createdAtfor sorting)model TodoList { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String owner User @relation(fields: [ownerId], references: [id]) ownerId String organization Organization? @relation(fields: [organizationId], references: [id]) organizationId String? todos Todo[] + + @@index([ownerId]) + @@index([organizationId]) + @@index([createdAt]) } model Todo { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String done Boolean @default(false) listId String list TodoList @relation(fields: [listId], references: [id]) + + @@index([listId]) + @@index([createdAt]) }
390-425: Enhance security with additional checks and logging.The implementation could benefit from:
- Session validation timeout
- Audit logging for security-sensitive operations
- Rate limiting for API requests
async function getPrisma() { const reqHeaders = await headers(); + const requestId = crypto.randomUUID(); + + // Add audit logging + console.info(`[${requestId}] API request initiated`); + const sessionResult = await auth.api.getSession({ headers: reqHeaders, }); if (!sessionResult) { + console.info(`[${requestId}] Anonymous access`); return enhance(prisma); } + // Validate session age + const { session } = sessionResult; + const sessionAge = Date.now() - session.createdAt.getTime(); + if (sessionAge > 24 * 60 * 60 * 1000) { // 24 hours + console.warn(`[${requestId}] Session expired`); + return enhance(prisma); + } let organizationId: string | undefined = undefined; let organizationRole: string | undefined = undefined; - const { session } = sessionResult; if (session.activeOrganizationId) { + console.info(`[${requestId}] Organization context: ${session.activeOrganizationId}`); organizationId = session.activeOrganizationId; const org = await auth.api.getFullOrganization({ headers: reqHeaders }); if (org?.members) { const myMember = org.members.find( (m) => m.userId === session.userId ); organizationRole = myMember?.role; + console.info(`[${requestId}] User role: ${organizationRole}`); } } const userContext = { userId: session.userId, organizationId, organizationRole, }; + console.info(`[${requestId}] Enhanced client created for user: ${session.userId}`); return enhance(prisma, { user: userContext }); }
430-513: Consider additional fine-grained access controls.The current access control implementation is solid but could benefit from:
- Rate limiting for create/update operations
- Soft delete support
- Field-level encryption for sensitive data
model TodoList { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String + deleted Boolean @default(false) + deletedAt DateTime? owner User @relation(fields: [ownerId], references: [id]) ownerId String organization Organization? @relation(fields: [organizationId], references: [id]) organizationId String? todos Todo[] // deny anonymous users @@deny('all', auth() == null) // deny access to lists that don't belong to the user's active organization @@deny('all', auth().organizationId != organizationId) + // implement soft delete + @@deny('all', deleted == true) + + // rate limiting: max 100 lists per user + @@deny('create', _count.filtered(auth().userId == ownerId) > 100) }🧰 Tools
🪛 LanguageTool
[grammar] ~504-~504: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ... read a list, he has full access to its Todo items ```zmodel title="/schema.zmodel"...(TO_DO_HYPHEN)
31-31: Maintain consistent hyphenation in documentation.For better readability and consistency, consider using "To-do" instead of "Todo" throughout the documentation. This applies to terms like:
- "To-do List" instead of "Todo List"
- "To-dos" instead of "Todos"
- "To-do items" instead of "Todo items"
Also applies to: 224-224, 504-504
🧰 Tools
🪛 LanguageTool
[grammar] ~31-~31: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...The target application we'll build is a Todo List. Its core functionalities are simp...(TO_DO_HYPHEN)
[grammar] ~31-~31: It appears that a hyphen is missing in the plural noun “to-dos”?
Context: ...are simple: creating lists and managing todos within them. However, the focus will be...(TO_DO_HYPHEN)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
blog/better-auth/cover.pngis excluded by!**/*.png,!**/*.pngblog/better-auth/initial-ui.pngis excluded by!**/*.png,!**/*.pngblog/better-auth/list-ui.gifis excluded by!**/*.gif,!**/*.gifblog/better-auth/sign-in.pngis excluded by!**/*.png,!**/*.png
📒 Files selected for processing (3)
blog/better-auth/index.mdx(1 hunks)blog/stackauth-multitenancy/index.mdx(1 hunks)docs/guides/authentication/clerk.md(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- blog/stackauth-multitenancy/index.mdx
🧰 Additional context used
🪛 LanguageTool
blog/better-auth/index.mdx
[grammar] ~31-~31: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...The target application we'll build is a Todo List. Its core functionalities are simp...
(TO_DO_HYPHEN)
[grammar] ~31-~31: It appears that a hyphen is missing in the plural noun “to-dos”?
Context: ...are simple: creating lists and managing todos within them. However, the focus will be...
(TO_DO_HYPHEN)
[grammar] ~48-~48: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: ...Regular members have full access to the todo lists they own. - Regular members can...
(TO_DO_HYPHEN)
[grammar] ~49-~49: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: ...lar members can view the other members' todo lists and manage their content. The es...
(TO_DO_HYPHEN)
[grammar] ~224-~224: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ... work on the application-specific ones: Todo List and Todo. As mentioned previously,...
(TO_DO_HYPHEN)
[grammar] ~224-~224: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...pplication-specific ones: Todo List and Todo. As mentioned previously, we should upd...
(TO_DO_HYPHEN)
[uncategorized] ~328-~328: Loose punctuation mark.
Context: ...ash npm install @zenstackhq/server ``` , and then create a "/app/api/[...path]/r...
(UNLIKELY_OPENING_PUNCTUATION)
[style] ~385-~385: The word ‘biggest’ tends to be overused in this context. Consider an alternative.
Context: ...ich is obviously not what we want. The biggest value ZenStack adds above Prisma is access co...
(A_GREAT_NUMBER)
[style] ~427-~427: Replace ‘get’ with a more descriptive word to set your writing apart from others.
Context: ...s via the special auth() function. To get it to work, we'll use a type to define the sh...
(GET_STYLISH)
[grammar] ~504-~504: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ... read a list, he has full access to its Todo items ```zmodel title="/schema.zmodel"...
(TO_DO_HYPHEN)
[uncategorized] ~521-~521: Use a comma before “and” if it connects two independent clauses (unless they are closely connected and short).
Context: ...ally, the UI With the CRUD APIs secured and frontend hooks generated, implementing ...
(COMMA_COMPOUND_SENTENCE_2)
[style] ~566-~566: ‘end result’ might be wordy. Consider a shorter alternative.
Context: ...combining better-auth and ZenStack. The end result is a secure application with great flex...
(EN_WORDINESS_PREMIUM_END_RESULT)
🔇 Additional comments (1)
docs/guides/authentication/clerk.md (1)
97-98: LGTM! Good cross-referencing.
The addition of a reference to the multi-tenant setup blog post enhances the documentation by providing readers with more advanced implementation details.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (1)
blog/better-auth/index.mdx (1)
443-515: Consider additional security measures.While the access control policies are well-implemented, consider adding:
- Rate limiting for API calls to prevent abuse
- Audit logging for sensitive operations (create, update, delete)
- Soft delete support for data recovery
🧰 Tools
🪛 LanguageTool
[uncategorized] ~465-~465: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...uth().userId == ownerId) } ``` #### 3. Owner and admins have full access By default...(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
[grammar] ~504-~504: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...} ``` #### 6. A user as full access toTodoif he can read its parent `TodoList` ...(TO_DO_HYPHEN)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
blog/better-auth/index.mdx(1 hunks)
🧰 Additional context used
🪛 LanguageTool
blog/better-auth/index.mdx
[grammar] ~31-~31: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...The target application we'll build is a Todo List. Its core functionalities are simp...
(TO_DO_HYPHEN)
[grammar] ~31-~31: It appears that a hyphen is missing in the plural noun “to-dos”?
Context: ...are simple: creating lists and managing todos within them. However, the focus will be...
(TO_DO_HYPHEN)
[grammar] ~48-~48: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: ...Regular members have full access to the todo lists they own. - Regular members can...
(TO_DO_HYPHEN)
[grammar] ~49-~49: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: ...lar members can view the other members' todo lists and manage their content. The es...
(TO_DO_HYPHEN)
[grammar] ~224-~224: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ... work on the application-specific ones: Todo List and Todo. As mentioned previously,...
(TO_DO_HYPHEN)
[grammar] ~224-~224: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...pplication-specific ones: Todo List and Todo. As mentioned previously, we should upd...
(TO_DO_HYPHEN)
[uncategorized] ~307-~307: You might be missing the article “the” here.
Context: ...sociated with it. ::: Then regenerate Prisma schema and push changes to the database...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~328-~328: Loose punctuation mark.
Context: ...ash npm install @zenstackhq/server ``` , and then create a "/app/api/[...path]/r...
(UNLIKELY_OPENING_PUNCTUATION)
[style] ~385-~385: The word ‘biggest’ tends to be overused in this context. Consider an alternative.
Context: ...ich is obviously not what we want. The biggest value ZenStack adds above Prisma is access co...
(A_GREAT_NUMBER)
[style] ~427-~427: Replace ‘get’ with a more descriptive word to set your writing apart from others.
Context: ...s via the special auth() function. To get it to work, we'll use a type to define the sh...
(GET_STYLISH)
[uncategorized] ~465-~465: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...uth().userId == ownerId) } ``` #### 3. Owner and admins have full access By default...
(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)
[grammar] ~504-~504: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...} ``` #### 6. A user as full access to Todo if he can read its parent `TodoList` ...
(TO_DO_HYPHEN)
[grammar] ~521-~521: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...r changing ZModel. ::: ## Finally, the Todo list UI With the CRUD APIs secured and...
(TO_DO_HYPHEN)
[uncategorized] ~523-~523: Use a comma before “and” if it connects two independent clauses (unless they are closely connected and short).
Context: ...Todo list UI With the CRUD APIs secured and frontend hooks generated, implementing ...
(COMMA_COMPOUND_SENTENCE_2)
[style] ~568-~568: ‘end result’ might be wordy. Consider a shorter alternative.
Context: ...combining better-auth and ZenStack. The end result is a secure application with great flex...
(EN_WORDINESS_PREMIUM_END_RESULT)
🔇 Additional comments (2)
blog/better-auth/index.mdx (2)
331-348: Add error handling for API routes.
The current implementation lacks error handling for potential failures during request processing.
526-558: Enhance UI with better error handling and loading states.
The UI implementation would benefit from proper loading states, error handling, and optimistic updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
blog/better-auth/index.mdx (2)
75-85: Add error handling for database adapter initialization.The current setup doesn't handle potential initialization failures. Consider wrapping the adapter initialization with try-catch.
export const auth = betterAuth({ appName: 'Better Auth Demo', - database: prismaAdapter(prisma, { - provider: 'sqlite', - }), + database: (() => { + try { + return prismaAdapter(prisma, { + provider: 'sqlite', + }); + } catch (error) { + console.error('Failed to initialize database adapter:', error); + throw error; + } + })(), ... });
227-247: Add indexes and cascading delete behavior.Consider the following improvements:
- Add indexes on foreign key fields (
ownerId,organizationId,listId) for better query performance- Add cascading delete behavior to ensure data integrity when parent records are deleted
model TodoList { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String - owner User @relation(fields: [ownerId], references: [id]) - ownerId String - organization Organization? @relation(fields: [organizationId], references: [id]) - organizationId String? + owner User @relation(fields: [ownerId], references: [id]) + ownerId String @index + organization Organization? @relation(fields: [organizationId], references: [id]) + organizationId String? @index - todos Todo[] + todos Todo[] @relation("ListTodos", onDelete: Cascade) } model Todo { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String done Boolean @default(false) - listId String - list TodoList @relation(fields: [listId], references: [id]) + listId String @index + list TodoList @relation("ListTodos", fields: [listId], references: [id], onDelete: Cascade) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
blog/better-auth/index.mdx(1 hunks)
🧰 Additional context used
🪛 LanguageTool
blog/better-auth/index.mdx
[grammar] ~31-~31: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...The target application we'll build is a Todo List. Its core functionalities are simp...
(TO_DO_HYPHEN)
[grammar] ~31-~31: It appears that a hyphen is missing in the plural noun “to-dos”?
Context: ...are simple: creating lists and managing todos within them. However, the focus will be...
(TO_DO_HYPHEN)
[grammar] ~48-~48: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: ...Regular members have full access to the todo lists they own. - Regular members can...
(TO_DO_HYPHEN)
[grammar] ~49-~49: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: ...lar members can view the other members' todo lists and manage their content. The es...
(TO_DO_HYPHEN)
[grammar] ~224-~224: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ... work on the application-specific ones: Todo List and Todo. As mentioned previously,...
(TO_DO_HYPHEN)
[grammar] ~224-~224: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...pplication-specific ones: Todo List and Todo. As mentioned previously, we should upd...
(TO_DO_HYPHEN)
[uncategorized] ~328-~328: Loose punctuation mark.
Context: ...ash npm install @zenstackhq/server ``` , and then create a "/app/api/[...path]/r...
(UNLIKELY_OPENING_PUNCTUATION)
[style] ~385-~385: The word ‘biggest’ tends to be overused in this context. Consider an alternative.
Context: ...ich is obviously not what we want. The biggest value ZenStack adds above Prisma is access co...
(A_GREAT_NUMBER)
[style] ~427-~427: Replace ‘get’ with a more descriptive word to set your writing apart from others.
Context: ...s via the special auth() function. To get it to work, we'll use a type to define the sh...
(GET_STYLISH)
[grammar] ~504-~504: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...} ``` #### 6. A user as full access to Todo if he can read its parent `TodoList` ...
(TO_DO_HYPHEN)
[grammar] ~506-~506: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...the TodoList model, and rules for the Todo model are yet to be defined. Fortunate...
(TO_DO_HYPHEN)
[grammar] ~506-~506: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...te permission check to a relation (here Todo -> TodoList). ```zmodel title="/sch...
(TO_DO_HYPHEN)
[grammar] ~521-~521: It appears that a hyphen is missing in the noun “To-do” (= task) or did you mean the verb “to do”?
Context: ...r changing ZModel. ::: ## Finally, the Todo list UI With the CRUD APIs secured and...
(TO_DO_HYPHEN)
[uncategorized] ~523-~523: Use a comma before “and” if it connects two independent clauses (unless they are closely connected and short).
Context: ...Todo list UI With the CRUD APIs secured and frontend hooks generated, implementing ...
(COMMA_COMPOUND_SENTENCE_2)
[style] ~570-~570: ‘end result’ might be wordy. Consider a shorter alternative.
Context: ...combining better-auth and ZenStack. The end result is a secure application with great flex...
(EN_WORDINESS_PREMIUM_END_RESULT)
🔇 Additional comments (3)
blog/better-auth/index.mdx (3)
331-348: Add error handling for API routes.
The current implementation doesn't handle potential errors that might occur during request processing.
390-425: Add error handling and type safety improvements.
The implementation needs improvements in error handling and type safety.
526-559: Enhance UI with better error handling and loading states.
The current implementation could benefit from better error handling and loading states.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation