migrate permissions to Cedar during application bootstrap#1653
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates existing group permission records into stored Cedar policies automatically during NestJS application startup, so Cedar authorization has policies available without running a separate migration step.
Changes:
- Invoke
migratePermissionsToCedar()during application bootstrap using the TypeORMDataSource. - Make the Cedar migration idempotent by skipping groups that already have a
cedarPolicy. - Improve migration completion logging to clarify skipped groups.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
backend/src/main.ts |
Runs the Cedar permission migration during application startup before listening. |
backend/src/entities/cedar-authorization/scripts/migrate-permissions-to-cedar.ts |
Skips already-migrated groups and updates the migration log message. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| console.log(`Migrated Cedar policies for ${migratedCount} groups`); | ||
| console.log(`Migrated Cedar policies for ${migratedCount} groups (skipped groups with existing policies)`); |
There was a problem hiding this comment.
This migration now runs as part of API startup, so logging via console.log will bypass the configured Winston/Nest logger (and any structured logging / log routing). Prefer using the existing application logger (e.g., Nest Logger or WinstonLogger) so the message is consistent with the rest of the service logs.
| ); | ||
|
|
||
| const dataSource = app.get(DataSource); | ||
| await migratePermissionsToCedar(dataSource); |
There was a problem hiding this comment.
Running a full permissions→Cedar migration as part of every application bootstrap can significantly delay startup and can prevent the API from coming up if the DB is temporarily unavailable or the migration errors. Consider gating this behind an explicit env flag (and/or CEDAR_AUTHORIZATION_ENABLED), and/or taking a DB advisory lock / single-run mechanism so multiple instances don’t race and repeat the work on deploy; alternatively run it as a separate one-off job and only log/report failures without crashing the server (depending on desired fail-fast behavior).
| await migratePermissionsToCedar(dataSource); | |
| if (process.env.CEDAR_MIGRATION_ON_BOOT !== 'false') { | |
| await migratePermissionsToCedar(dataSource); | |
| } |
| .leftJoinAndSelect('group.connection', 'connection') | ||
| .leftJoinAndSelect('group.permissions', 'permission') | ||
| .where('connection.id = :connectionId', { connectionId: connection.id }) | ||
| .andWhere('(group.cedarPolicy IS NULL OR group.cedarPolicy = :empty)', { empty: '' }) | ||
| .getMany(); |
There was a problem hiding this comment.
Now that this script runs during normal bootstrap, the migration approach can become a startup bottleneck: it loads groups per connection and then persists each group one-by-one. Consider reducing round-trips (e.g., query all groups needing migration in one pass, batch updates, and prefer update on cedarPolicy rather than save on fully loaded entities) to keep startup time predictable for large datasets.
No description provided.