feat: add user role assignment expiry and history tracking#1816
Conversation
User role assignments can now have optional expiration timestamps for time-limited access grants. Compatible with warp-tech/warpgate#1816. Changes: - Added expiry block to warpgate_user_role resource with expires_at field - Added UpdateContext to allow modifying expiry on existing assignments - New UserRoleAssignment struct with expiry and activity metadata - Updated AddUserRole to accept optional expiresAt parameter - Added GetUserRole, UpdateUserRoleExpiry, and RemoveUserRoleExpiry client methods - GetUserRoles now returns UserRoleAssignment with expiry fields - Updated docs with time-limited assignment example Example usage: resource "warpgate_user_role" "temporary" { user_id = warpgate_user.alice.id role_id = warpgate_role.contractor.id expiry { expires_at = "2026-12-31T23:59:59Z" } }
|
Could you please remove the history tracking part from this PR? I actually had a different approach to this in mind - using the log as a source of data and having a "User audit log" link from the user profile to a pre-filtered log viewer. Log entries tagged as audit would then have an independent, longer expiry as well. As for the UI, the log viewer could then include dedicated UI elements for specific log entry types The background behind this is that there are more important audit log types than just role assignments and I don't want to build separate UI and database structures for them all |
|
@Eugeny Got it ! I have removed the role assignement history from this PR! Let me know if you want to reduce further the scope of the. Edit: Do you need me also to remove the UI of the Connection History from the user UI if it was also planned to be somewhere else ? |
Add time-limited role assignments with optional expiry timestamps. Expired and revoked roles are automatically denied during authorization. Backend: - Migration m00033: adds granted_at, granted_by, expires_at, revoked_at, revoked_by columns to user_roles table - UserRoleAssignment entity extended with expiry/revocation fields - New API endpoints: get_user_role, update_user_role_expiry, remove_user_role_expiry - add_user_role now accepts optional expires_at body; re-activates revoked/expired assignments instead of returning 409 - delete_user_role soft-deletes (sets revoked_at) - authorize_target filters out expired/revoked role assignments - SSO role removal uses soft-delete - delete_role cleans up user_roles and target_roles FK references - sessions list accepts optional username filter Frontend: - Role list shows expiry status with live countdown timer - Expired roles shown with strikethrough and Re-enable button - Expiry modal with presets (4h/8h/12h/1d/3d/7d/30d) and custom picker - Connection history section on user page Tests: - 9 E2E tests covering grant with TTL, expired denied, re-enable, revoke, reactivate, API state listing, duplicate detection - Permission enforcement test cases for new endpoints - OIDC stale role test updated for soft-delete behavior
2040b56 to
a94d17d
Compare
|
Thank you - I've simplified the UI a bit |
|
Thanks @Eugeny I have seen that you have merge the PR ! I was meaning to take a look into it to fix the failing build test tomorrow ! But U did fix that ! DO you want me to prepare the File transfer restriction related PR or not ? |
…#1816) Add time-limited role assignments with optional expiry. ## What's new - **Role expiry** — assign roles with an optional `expires_at` timestamp; expired roles are automatically denied during authorization - **Soft revocation** — revoking a role sets `revoked_at` instead of deleting the row - **Re-activation** — `POST /users/:id/roles/:role_id` on a revoked/expired assignment re-activates it (instead of 409) - **Admin UI** — expiry presets (4h/8h/12h/1d/3d/7d/30d), live countdown timers, re-enable expired roles - **Connection history** — user page shows past sessions with protocol, target, and duration - **9 E2E tests** covering expiry, revocation, and re-activation ## Screenshots ### User roles with mixed expiry states <img width="802" alt="role-list" src="https://github.com/user-attachments/assets/abf2c49a-8b01-4901-b945-3e7066d63af9" /> ### Permanent access <img width="601" alt="permanent-access" src="https://github.com/user-attachments/assets/6797d3c4-1c47-48f6-b4ff-0d13660dd030" /> ### Expiry modal with presets <img width="534" alt="expiry-modal" src="https://github.com/user-attachments/assets/94bd8733-d930-4c28-a8dc-c3c3e2e883e4" /> ## API changes ### Modified endpoint | Method | Path | Change | |--------|------|--------| | `POST` | `/users/:id/roles/:role_id` | Body is now optional. Accepts `{"expires_at": "..."}` or no body (permanent). Re-activates revoked/expired assignments instead of 409. | ### New endpoints | Method | Path | Description | |--------|------|-------------| | `GET` | `/users/:id/roles` | List all role assignments with expiry info | | `GET` | `/users/:id/roles/:role_id` | Get single assignment details | | `PUT` | `/users/:id/roles/:role_id/expiry` | Set or update expiry | | `DELETE` | `/users/:id/roles/:role_id/expiry` | Remove expiry (make permanent) | ## Migration `m00033_user_role_expiry_history`: - Adds `granted_at`, `granted_by`, `expires_at`, `revoked_at`, `revoked_by` columns to `user_roles` - Backfills `granted_at` for existing rows --------- Co-authored-by: Eugene <inbox@null.page>

Add time-limited role assignments with optional expiry.
What's new
expires_attimestamp; expired roles are automatically denied during authorizationrevoked_atinstead of deleting the rowPOST /users/:id/roles/:role_idon a revoked/expired assignment re-activates it (instead of 409)Screenshots
User roles with mixed expiry states
Permanent access
Expiry modal with presets
API changes
Modified endpoint
POST/users/:id/roles/:role_id{"expires_at": "..."}or no body (permanent). Re-activates revoked/expired assignments instead of 409.New endpoints
GET/users/:id/rolesGET/users/:id/roles/:role_idPUT/users/:id/roles/:role_id/expiryDELETE/users/:id/roles/:role_id/expiryMigration
m00033_user_role_expiry_history:granted_at,granted_by,expires_at,revoked_at,revoked_bycolumns touser_rolesgranted_atfor existing rows