feat: RBAC — role-based access control integrated with Databricks workspace identity#21
Open
feat: RBAC — role-based access control integrated with Databricks workspace identity#21
Conversation
…kspace identity Implements issue #6: access control using Databricks workspace identity and Unity Catalog-style permission levels. | Role | Query | Configure gateways | Create/Delete gateways | Manage users | |--------|-------|--------------------|------------------------|--------------| | use | ✓ | | | | | manage | ✓ | ✓ | | | | owner | ✓ | ✓ | ✓ | ✓ | Workspace admins (Databricks 'admins' group) are always treated as owner. - `services/rbac.py`: role resolution — checks SCIM /Me for workspace admin, then user_roles table, then defaults to 'use' - `api/rbac_routes.py`: `/api/users/me`, `/api/users`, `/api/users/{email}/role` (POST/DELETE) — all owner-gated except /me - `storage_pgvector.py` + `storage_local.py` + `storage_dynamic.py` + `database.py`: user_roles table (pgvector) / dict (local) with get/set/list/delete CRUD - `gateway_routes.py`: POST /gateways → owner; PUT /gateways → manage; DELETE /gateways → owner; DELETE cache → manage; PUT /settings → owner - `main.py`: registers rbac_router at /api prefix - `context/RoleContext.jsx`: fetches /api/users/me on mount; provides { role, isOwner, isManage, loading } - `main.jsx`: wraps app in RoleProvider - `services/api.js`: getMyRole, listUsers, setUserRole, deleteUserRole - `GatewayListPage`: "New Gateway" button hidden for non-owners - `GatewayDetailPage`: "Delete gateway" hidden for non-owners; Settings tab hidden for 'use' role - `SettingsPage`: adds "Access Control → Users" sidebar section (owner only) with role matrix table, user list, add/remove user form Co-authored-by: Isaac
Per updated spec: manage can list, assign, and remove user roles. Previously only owner could do so. Updated role matrix: use → query only manage → configure gateways, clear cache, manage users owner → full control (create/delete gateways + everything manage can do) Co-authored-by: Isaac
Performance:
- rbac.py: cache is_workspace_admin result (60s TTL, keyed on token) and
get_user_role result (120s TTL, keyed on identity) to avoid SCIM+DB I/O on
every protected request; shared module-level httpx.AsyncClient eliminates
per-call TCP handshake
- rbac_routes.py / gateway_routes.py: call invalidate_role_cache after every
set_user_role / delete_user_role write so changes take effect immediately
Auth model:
- gateway_routes._require_role: switch from _get_token() (which has a
service-token fallback) to extract_bearer_token() — using the SP token for
authorization checks would grant the SP's role to unauthenticated callers
Code reuse:
- rbac.py / rbac_routes.py / gateway_routes.py: replace inline
`if not host.startswith("http")` with ensure_https() from app.auth,
matching the pattern used in 4 other route files
Bug:
- SettingsPage users useEffect: dep array had [isOwner, ...] but condition
checked isManage — manage-role users would never see the users list load;
fixed to [isManage, activeSection]; added usersLoadedRef to avoid re-fetching
after removing the last user
UX / efficiency:
- handleAddUser: use response from setUserRole for optimistic local upsert
instead of a second listUsers round-trip
- RoleContext: useMemo on context value to avoid re-rendering all consumers
on unrelated parent state changes
- SettingsPage: useMemo on SIDEBAR (stable once role resolves)
Co-authored-by: Isaac
Delete _get_token() and replace all call sites with extract_bearer_token(), which requires a real user token (X-Forwarded-Access-Token or Authorization Bearer) and raises 401 immediately if absent. No SP/service token fallback anywhere in the request path. Co-authored-by: Isaac
f41f8dc to
0052fb9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #6
Summary
use(query only),manage(configure gateways + clear cache + manage users),owner(full control)/Mecheckuser_rolestable in LakebasePermission matrix
usemanageownerTest plan
userole: only sees query + read-only viewsmanagerole: can configure gateways, clear cache, manage users/api/users/mereturns correct role for each user type