nebari-dev / nebari-dev/nebari-frames

[ENH] - map keycloak groups to nebari frames roles

Open
#21 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs: discussion 💬 type: enhancement 💅🏼
Dominant language
Go
Stars
2
Forks
1
Avg merge
10h 55m
Merged PRs (30d)
9

Description

Feature description

The caller's role is currently read only from the stored Membership record. orgs.ResolveCaller (backend/internal/orgs/orgs.go) sets rbac.Role(m.Role) from the database and never consults the token's group membership. The pieces for group-based roles are partly present but unused: auth.Validator.Validate (backend/internal/auth/validator.go) already extracts the groups claim into Claims.Groups using OIDC_GROUPS_CLAIM (default groups), and there is a dormant auth.IsAdmin(adminGroup, claims) helper plus an auth.Config.AdminGroup field. AdminGroup is not wired in backend/cmd/server/main.go, and ResolveCaller never calls IsAdmin, so group-driven roles are effectively unimplemented.

Proposal: derive a caller's Frames role from their Keycloak group membership, so role changes happen in Keycloak rather than through direct edits to membership rows.

  • Mapping config: add a group to role map, for example OIDC_ROLE_GROUP_MAP=frames-admins:admin,frames-publishers:publisher. This generalizes the existing single AdminGroup idea. Roles are viewer, publisher, admin from backend/internal/rbac/rbac.go.
  • Multiple groups: when a user is in more than one mapped group, the highest role wins (admin > publisher > viewer).
  • Precedence with stored membership: decide whether an explicit membership row overrides the group mapping or the reverse. Recommendation: take the higher of the two so an explicit admin grant is never silently downgraded by group data. This needs a decision.
  • Org scoping: group strings are flat today, and the MVP is single-org via SEED_ORG_SLUG. Decide whether a group maps to a role in that one org or whether the group name encodes an org (for example nebari:<org-slug>:admin) for later multi-org support.
  • Keycloak side: the realm and the frames-web client must emit a groups claim in the token via a group membership mapper. Decide full group path versus group name, and document the client mapper setup.
  • Re-evaluation: the role is recomputed from the token on each request, so group changes take effect on the next token refresh. Note token lifetime when documenting expected propagation delay.

Code touch points:

  • backend/internal/auth/config.go: add the mapping config (extend or replace AdminGroup).
  • backend/internal/orgs/orgs.go: consume Claims.Groups when setting Caller.Role.
  • backend/cmd/server/main.go: wire the new env vars.
  • chart/values.yaml plus the deploy values in the GitOps repo: surface the mapping.
  • Keep rbac.Can as the single decision point. This issue only changes how Caller.Role is populated, not the permission checks.
Value and/or benefit

Access is managed in Keycloak, the identity provider already in use, instead of by hand-editing membership rows. Adding someone to a group gives them the right role, and removing them revokes it on the next token refresh. This reduces bespoke invite and membership bookkeeping and keeps authorization aligned with the organization's existing group structure.

Anything else?

Related: #22 (assign a default role to authenticated Keycloak users). That issue sets the baseline role for any valid login; this issue lets groups elevate it. Together they define how an authenticated identity becomes an authorized caller.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with orgs.ResolveCaller in backend/internal/orgs/orgs.go, then read auth.Config, auth.Validator.Validate, auth.IsAdmin, and the role definitions in backend/internal/rbac/rbac.go. Review backend/cmd/server/main.go and chart/values.yaml for configuration wiring. Done means the documented group-to-role behavior, precedence and org scope are decided, implemented, surfaced in deployment values, and reflected in Keycloak setup documentation.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
authentication, authorization, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.