Skip to content

feat!: drop per-user App access (access.users) - #158

Merged
jbouder merged 2 commits into
mainfrom
feat/drop-access-users
Oct 21, 2026
Merged

jbouder merged 2 commits into
mainfrom
feat/drop-access-users

Conversation

@jbouder

@jbouder jbouder commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Apps now restrict who may open them by Keycloak group only. This removes spec.access.users and everything that served it. spec.access.managers.users (who may manage an App) is unchanged.

  • operator: AppAccess.Users is removed from the CRD; the deepcopy file, the CRD and crd.gen.ts are regenerated. The enforcing authz sidecar is added only for private Apps that list groups, and it no longer gets AUTHZ_USERS.
  • authz: AUTHZ_USERS and AUTHZ_USERS_CLAIM are removed, along with the username match. Enforcing mode now requires AUTHZ_GROUPS.
  • api: users is removed from the access model and from the mapping to the CR. Create and patch now refuse unknown access keys with a 422, so an old client that still sends users gets an error instead of an App open to more people than it asked for. Reads ignore a stale users list on an old CR. Also fixes /apps/upload returning 500 instead of 422 for an invalid manifest.
  • mcp: removes the users argument from launch_app and the users wording from its resources and prompts.
  • ui: removes the "Allowed users" field from the launch form and the users part of the access line.
  • docs, README, AGENTS.md, chart, skill, examples: describe group-only access.
  • CRD policy: this is a one-off exception to the additive-only rule. check_crd_compat.py allows just this one removal and reports it as a warning. The exception is recorded in the CRD reference.

Breaking change / upgrade

The new CRD's structural schema prunes access.users from existing Apps:

  • An App restricted only by users, with no groups, becomes open to every signed-in user.
  • Users who were let in only by name lose access to Apps that also list groups.

upgrading.md has a kubectl + jq check that lists the affected Apps before an upgrade, so admins can move those users into a Keycloak group first.

Related: #153 (updated to drop the access.users work).

Testing

All of these were run locally and pass:

  • operator and authz: build, vet, go test -race, golangci-lint, plus the operator envtests.
  • api: pytest (303), ruff, mypy.
  • mcp: pytest (60), ruff, mypy.
  • ui: check:ci, build, npm test (251), Playwright e2e (143).
  • docs: bun test, build.
  • helm lint.
  • The CRD-types, doc-paths, versions and CRD-compat checks.

Not yet verified on a cluster.

🤖 Generated with Claude Code

https://claude.ai/code/session_016pvMUQJoLkBDk6B94TTm45

jbouder and others added 2 commits October 21, 2026 09:43
Apps now restrict who may open them by Keycloak group only. Remove
spec.access.users and everything that served it:

- operator: drop AppAccess.Users from the CRD (regenerated deepcopy, CRD
  and ui/src/lib/crd.gen.ts); an App is restricted, and gets an enforcing
  authz sidecar, only when it is private and lists groups. The sidecar no
  longer gets AUTHZ_USERS.
- authz: drop Users/UsersClaim, AUTHZ_USERS and AUTHZ_USERS_CLAIM and the
  username match; enforcing mode now requires AUTHZ_GROUPS, and the 403
  names the allowed groups.
- api: drop users from the access model and the CR mapping. Create and
  patch bodies refuse unknown access keys (422), so a client still
  sending users is not given an App open to more people than it asked
  for; reads ignore a users list still stored on an old CR. The upload
  route now returns 422, not 500, for an invalid manifest.
- mcp: drop the users argument of launch_app and the users wording in
  its resources and prompts.
- ui: drop the "Allowed users" field, its form state and the users part
  of the access line.
- docs, README, AGENTS.md, chart values/README, skill and examples:
  describe group-only access.

spec.access.managers.users (who may manage an App) is unchanged.

BREAKING CHANGE: the new CRD's structural schema prunes access.users from
existing Apps. An App that restricted access only by users (no groups)
becomes open to every signed-in realm user after the upgrade, and users
let in only by name lose access to Apps that also list groups. Before
upgrading, list the affected Apps with

  kubectl get apps.apps.nebari.dev -A -o json | jq -r '.items[] |
    select(.spec.access.users // [] | length > 0) |
    "\(.metadata.namespace)/\(.metadata.name)"'

and move those users into a Keycloak group listed in access.groups. See
docs/src/content/docs/upgrading.md, "Upgrading to group-only access".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pvMUQJoLkBDk6B94TTm45
@github-actions

Copy link
Copy Markdown

📄 Docs preview for feat/drop-access-users:
https://feat-drop-access-users.apps-pack.pages.dev

@jbouder
jbouder merged commit 220cf11 into main Oct 21, 2026
15 checks passed
@jbouder
jbouder deleted the feat/drop-access-users branch October 21, 2026 13:55
jbouder added a commit that referenced this pull request Oct 21, 2026
The switch was read-only because the landing page could hide a tile only
by group, not by username. Apps now restrict by group only (#158), so the
form offers it again. A launch sends exactly what the switch shows, even
when the cluster default is on; an edit sends landingPage only when the
switch is flipped, so an App on the cluster default keeps it.


Claude-Session: https://claude.ai/code/session_016pvMUQJoLkBDk6B94TTm45

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant