File tree Expand file tree Collapse file tree
internal-packages/rbac/src Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -2072,6 +2072,12 @@ const EnvironmentSchema = z
20722072 // Force RBAC to not use the plugin
20732073 RBAC_FORCE_FALLBACK : BoolEnv . default ( false ) ,
20742074
2075+ // Per-process pool sizes for an RBAC plugin that owns its own database
2076+ // client (the fallback queries through Prisma and ignores these). Writes
2077+ // are rare role mutations; reads run on the per-request auth hot path.
2078+ RBAC_DATABASE_WRITER_CONNECTION_LIMIT : z . coerce . number ( ) . int ( ) . default ( 2 ) ,
2079+ RBAC_DATABASE_READER_CONNECTION_LIMIT : z . coerce . number ( ) . int ( ) . default ( 5 ) ,
2080+
20752081 // Force SSO to not use the plugin (contributors without the cloud
20762082 // plugin installed can opt in to a clean OSS-only experience).
20772083 SSO_FORCE_FALLBACK : BoolEnv . default ( false ) ,
Original file line number Diff line number Diff line change @@ -27,5 +27,18 @@ export const rbac = plugin.create(
2727 { primary : prisma , replica : $replica as PrismaClient } ,
2828 // SESSION_SECRET signs delegated user-actor tokens; the plugin verifies
2929 // them with it in authenticateUserActor.
30- { forceFallback : env . RBAC_FORCE_FALLBACK , userActorSecret : env . SESSION_SECRET }
30+ {
31+ forceFallback : env . RBAC_FORCE_FALLBACK ,
32+ userActorSecret : env . SESSION_SECRET ,
33+ // A plugin that owns its own database client gets the same
34+ // writer/replica topology the webapp's Prisma clients use (see
35+ // getClient/getReplicaClient in db.server.ts): control-plane URLs win,
36+ // and with no replica configured reads share the writer.
37+ database : {
38+ writerUrl : env . CONTROL_PLANE_DATABASE_URL ?? env . DATABASE_URL ,
39+ readerUrl : env . CONTROL_PLANE_DATABASE_READ_REPLICA_URL ?? env . DATABASE_READ_REPLICA_URL ,
40+ writerConnectionLimit : env . RBAC_DATABASE_WRITER_CONNECTION_LIMIT ,
41+ readerConnectionLimit : env . RBAC_DATABASE_READER_CONNECTION_LIMIT ,
42+ } ,
43+ }
3144) ;
Original file line number Diff line number Diff line change 11import type {
22 Permission ,
33 RbacAbility ,
4+ RbacDatabaseConfig ,
45 Role ,
56 RbacResource ,
67 RoleAssignmentResult ,
@@ -33,6 +34,11 @@ export type RbacCreateOptions = {
3334 // Platform secret used to verify delegated user-actor tokens (tr_uat_).
3435 // Threaded through to the plugin / fallback's authenticateUserActor.
3536 userActorSecret ?: string ;
37+ // Writer/reader connection URLs + pool sizes for a plugin that owns its
38+ // own database client, resolved by the host from its env so the plugin
39+ // follows the host's writer/replica topology. The fallback ignores this —
40+ // it queries through the Prisma clients passed as `RbacPrismaInput`.
41+ database ?: RbacDatabaseConfig ;
3642} ;
3743
3844// Route actions that historically authorised via the legacy checkAuthorization's
@@ -88,7 +94,10 @@ class LazyController implements RoleBaseAccessController {
8894 const module = await import ( moduleName ) ;
8995 const plugin : RoleBasedAccessControlPlugin = module . default ;
9096 console . log ( "RBAC: using plugin implementation" ) ;
91- return plugin . create ( { userActorSecret : options ?. userActorSecret } ) ;
97+ return plugin . create ( {
98+ userActorSecret : options ?. userActorSecret ,
99+ database : options ?. database ,
100+ } ) ;
92101 } catch ( err ) {
93102 // The dynamic import either succeeded or failed for one of two
94103 // distinct reasons. Distinguishing them is critical for debugging
Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ export type {
1616 UserActorAuthResult ,
1717 UserActorClaims ,
1818 RbacPluginConfig ,
19+ RbacDatabaseConfig ,
1920 SystemRole ,
2021 AuthenticatedEnvironment ,
2122} from "./rbac.js" ;
Original file line number Diff line number Diff line change @@ -430,6 +430,23 @@ export type RbacPluginConfig = {
430430 // Platform secret the host signs user-actor tokens with; the plugin uses
431431 // it to verify them in `authenticateUserActor`. Omitted → UAT auth 401s.
432432 userActorSecret ?: string ;
433+ // Database connections for a plugin that owns its own client. The host
434+ // resolves the URLs from its env so the plugin follows the same
435+ // writer/replica topology the host uses. Omitted → the plugin falls back
436+ // to its own defaults.
437+ database ?: RbacDatabaseConfig ;
438+ } ;
439+
440+ export type RbacDatabaseConfig = {
441+ // Primary (writer) connection URL. Mutations and read-your-writes
442+ // management reads run here.
443+ writerUrl : string ;
444+ // Read-replica URL for the per-request auth reads. Omitted → those reads
445+ // share the writer connection.
446+ readerUrl ?: string ;
447+ // Per-process pool sizes. Omitted → plugin defaults (writer 2, reader 5).
448+ writerConnectionLimit ?: number ;
449+ readerConnectionLimit ?: number ;
433450} ;
434451
435452export interface RoleBasedAccessControlPlugin {
You can’t perform that action at this time.
0 commit comments