Spaces: "Add member" gives no feedback; needs a member picker (autocomplete + validation) #210

Closed
opened 2026-08-13 13:22:33 +00:00 by Cordy · 4 comments
Owner

Found dogfooding the openbao-custody instance.

Repro:

  • In a Space, select a folder → use Add member → nothing visibly happens. No confirmation, no error — no feedback either way about whether a member was added.

Bug: the action gives no result feedback (success or failure). Likely the same unsurfaced-Response pattern as the folder-create empty error — worth checking whether the request is even firing / what it returns.

Enhancements requested (UX):

  • A dropdown of available members to pick from, instead of a free-text field.
  • Autocomplete against existing members while typing.
  • On selecting one, validate: does this user exist / is available, and are they already a member of this space? Surface that state instead of silently doing nothing.

Also: check whether the same no-feedback behaviour exists on the keycloak-profile instance (the other dogfood) — this is probably a general spaces-UI issue, not openbao-specific. Note how space membership is actually modeled (IdP groups vs. an in-app membership store) so "Add member" targets the right layer.

Found dogfooding the openbao-custody instance. **Repro:** - In a Space, select a folder → use **Add member** → nothing visibly happens. No confirmation, no error — no feedback either way about whether a member was added. **Bug:** the action gives no result feedback (success or failure). Likely the same unsurfaced-`Response` pattern as the folder-create empty error — worth checking whether the request is even firing / what it returns. **Enhancements requested (UX):** - A **dropdown of available members** to pick from, instead of a free-text field. - **Autocomplete** against existing members while typing. - On selecting one, **validate**: does this user exist / is available, and are they **already a member** of this space? Surface that state instead of silently doing nothing. **Also:** check whether the same no-feedback behaviour exists on the keycloak-profile instance (the other dogfood) — this is probably a general spaces-UI issue, not openbao-specific. Note how space membership is actually modeled (IdP groups vs. an in-app membership store) so "Add member" targets the right layer.
Author
Owner

Diagnosis (from the pod log + code).

The UI calls GET/POST /api/v1/spaces/{name}/members and both return Go's default 404 page not found (19-byte body) — the route isn't registered, not an app-level 404.

registerSpaces runs only when apiH.Spaces != nil (api.go), and main.go builds that only when a Keycloak admin client exists — if enc.KeycloakBaseURL != "" && enc.KeycloakClientID != "" (main.go:727). Those storage.encryption.keycloak* fields do double duty: keycloak-profile key custody and the groups/spaces manager (spaces.Manager, #94/#96). The openbao dogfood's deployed config doesn't have them, so the entire self-service spaces surface (create space, list/add/remove members) is off.

Two things to decide, beyond the frontend bug:

  1. Coupling. Spaces management is gated on config fields named for encryption custody. An openbao / AD / LDAP instance that wants spaces management must still set those Keycloak-admin fields. Either decouple them (a dedicated spaces/groupAdmin block) or document clearly that "self-service spaces need a Keycloak admin client regardless of key custody."
  2. Owner requirement. Even once wired, member management targets Cairn-created spaces — POST /api/v1/spaces sets creator = owner. A group created directly in Keycloak (like Fall 3) has no owner, so ownerOrAdminErrNoSpace → "no such space". Add-member on a hand-made group can't work through this API by design; the space has to be born through Cairn.

Frontend bug (independent, real): the UI fires the request and swallows the 404 with no feedback. It should surface "spaces management isn't available on this instance" (feature-detect, like the audit panel #173) or the real error — plus the requested picker: dropdown of candidate members, type-ahead, and an already-member / not-found check.

**Diagnosis (from the pod log + code).** The UI calls `GET`/`POST /api/v1/spaces/{name}/members` and both return **Go's default `404 page not found`** (19-byte body) — the route isn't registered, not an app-level 404. `registerSpaces` runs only when `apiH.Spaces != nil` (api.go), and main.go builds that only when a Keycloak **admin** client exists — `if enc.KeycloakBaseURL != "" && enc.KeycloakClientID != ""` (main.go:727). Those `storage.encryption.keycloak*` fields do **double duty**: keycloak-profile key custody *and* the groups/spaces manager (`spaces.Manager`, #94/#96). The openbao dogfood's deployed config doesn't have them, so the entire self-service spaces surface (create space, list/add/remove members) is off. Two things to decide, beyond the frontend bug: 1. **Coupling.** Spaces management is gated on config fields named for *encryption custody*. An `openbao` / AD / LDAP instance that wants spaces management must still set those Keycloak-admin fields. Either decouple them (a dedicated `spaces`/`groupAdmin` block) or document clearly that "self-service spaces need a Keycloak admin client regardless of key custody." 2. **Owner requirement.** Even once wired, member management targets Cairn-**created** spaces — `POST /api/v1/spaces` sets creator = owner. A group created directly in Keycloak (like `Fall 3`) has no owner, so `ownerOrAdmin` → `ErrNoSpace` → "no such space". Add-member on a hand-made group can't work through this API by design; the space has to be born through Cairn. **Frontend bug (independent, real):** the UI fires the request and swallows the 404 with no feedback. It should surface "spaces management isn't available on this instance" (feature-detect, like the audit panel #173) or the real error — plus the requested picker: dropdown of candidate members, type-ahead, and an already-member / not-found check.
Author
Owner

Confirmed the same root cause also breaks create-space: the Spaces-list "New folder" button calls POST /api/v1/spaces404 (19-byte 404 page not found), identical unwired-h.Spaces. So #209 is the same issue surfaced through the create-space button; this issue (#210) is the member surface. Both come down to: the spaces-management API is not registered on this instance (no Keycloak admin client), and the UI neither feature-detects that nor surfaces the error.

Confirmed the same root cause also breaks **create-space**: the Spaces-list "New folder" button calls `POST /api/v1/spaces` → `404` (19-byte `404 page not found`), identical unwired-`h.Spaces`. So **#209 is the same issue** surfaced through the create-space button; this issue (#210) is the member surface. Both come down to: the spaces-management API is not registered on this instance (no Keycloak admin client), and the UI neither feature-detects that nor surfaces the error.
Author
Owner

Split status: the feedback + validation half of this issue is shipped and verified — "Add member" no longer fails silently. On v0.6.18 the members dialog gives clear feedback: adds render immediately, re-adding an existing member shows "Already a member — change their role in the list above", and entering the owner shows "The owner always has full access." Verified on both cairn-openbao (app-owned path) and cairn-enc (IdP-managed path). The unsurfaced-Response root cause (same class as #136) was also fixed (v0.6.18 members-dialog .json()).

The remaining picker half — candidate dropdown + type-ahead — is tracked in #226 (deferred because it needs an enumerable user list). Keeping this open to close together with #226, which is being worked now.

Split status: the **feedback + validation** half of this issue is shipped and verified — "Add member" no longer fails silently. On v0.6.18 the members dialog gives clear feedback: adds render immediately, re-adding an existing member shows "Already a member — change their role in the list above", and entering the owner shows "The owner always has full access." Verified on both **cairn-openbao** (app-owned path) and **cairn-enc** (IdP-managed path). The unsurfaced-`Response` root cause (same class as #136) was also fixed (v0.6.18 members-dialog `.json()`). The remaining **picker** half — candidate dropdown + type-ahead — is tracked in #226 (deferred because it needs an enumerable user list). Keeping this open to **close together with #226**, which is being worked now.
Author
Owner

Both halves of this issue are now shipped:

  • Feedback + validation (v0.6.18): "Add member" gives clear feedback; already-member / owner / not-found are surfaced up front. Verified live on both dogfoods.
  • Member picker (v0.6.19, #226): candidate dropdown + type-ahead via GET /api/v1/spaces/{name}/candidates, degrading to validated free-text where no user source is enumerable. CI-green, deployed to both instances.

Closing together with #226.

Both halves of this issue are now shipped: - **Feedback + validation** (v0.6.18): "Add member" gives clear feedback; already-member / owner / not-found are surfaced up front. Verified live on both dogfoods. - **Member picker** (v0.6.19, #226): candidate dropdown + type-ahead via `GET /api/v1/spaces/{name}/candidates`, degrading to validated free-text where no user source is enumerable. CI-green, deployed to both instances. Closing together with #226.
Cordy closed this issue 2026-08-13 23:41:05 +00:00
Sign in to join this conversation.
No labels
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#210
No description provided.