Skip to content

Add Per-Namespace Permissions with Role Attributes - #24

Open
pozylon wants to merge 2 commits into
alexanderwolz:mainfrom
pozylon:main
Open

Add Per-Namespace Permissions with Role Attributes#24
pozylon wants to merge 2 commits into
alexanderwolz:mainfrom
pozylon:main

Conversation

@pozylon

@pozylon pozylon commented Feb 4, 2026

Copy link
Copy Markdown

Hi Alexander

Thanks for the keycloak-registry-mapper! I'm trying to use it together with the Docker registry but i stumbled upon a case.

I needed User X having access to Pull from repository A and pull/push from repository B while having
User Y having access to Pull from repository B and pull/push from repository A.

That doesn't align with the group approach and i searched for a solution on how to extend your plugin.
I'm not proficient in Kotlin so i vibe-coded (😳) an extension to your tooling that allows me to define specific client roles with fine-grained permissions.

I don't know if the code is mergable quality-wise but tests pass, it builds and i use it in a staging area where it "seems" to work just the way i wanted it.

Nevertheless, here is my PR. Totally understand of course if you don't want to review or merge it due to the circumstances of the "creational" process.

Also here is the Dockerfile of the Keycloak Instance i'm building for reference:

# Build keycloak-registry-mapper from source
FROM gradle:8-jdk21 AS mapper-builder
WORKDIR /build
RUN git clone https://github.com/pozylon/keycloak-registry-mapper.git .
RUN ./gradlew clean build -x test

FROM quay.io/keycloak/keycloak:26.5 AS builder

# Configure build-time options
ENV KC_DB=postgres
ENV KC_CACHE=ispn
ENV KC_CACHE_STACK=jdbc-ping
ENV KC_HEALTH_ENABLED=true
ENV KC_HTTP_ENABLED=true
ENV KC_FEATURES=docker,token-exchange

# Copy plugin from builder stage
COPY --from=mapper-builder /build/build/libs/*.jar /opt/keycloak/providers/

# Build optimized Keycloak
RUN /opt/keycloak/bin/kc.sh build

FROM quay.io/keycloak/keycloak:26.5

# Copy optimized build from builder stage
COPY --from=builder /opt/keycloak/ /opt/keycloak/

# Copy realm import files
COPY realm-*.json /opt/keycloak/data/import/

# Copy custom entrypoint for Docker secrets support
COPY entrypoint.sh /scripts/entrypoint.sh

USER root
RUN chmod +x /scripts/entrypoint.sh
USER keycloak

ENTRYPOINT ["/bin/bash", "/scripts/entrypoint.sh"]
CMD ["start", "--optimized", "--import-realm"]

@alexanderwolz

alexanderwolz commented Feb 4, 2026 via email

Copy link
Copy Markdown
Owner

@pozylon

pozylon commented Feb 4, 2026

Copy link
Copy Markdown
Author

Yeah i feel like the group-concept lacks the depth needed but i never tried the Keycloak "ACL" thing either and I don't have any experience using it although it seems to actually be what we are looking for:

https://www.keycloak.org/docs/latest/authorization_services/index.html#_resource_create

So that's why i opted in to attributes but actually any repository should be a "resource" imo in Keycloak speak when using the ACL features.

@alexanderwolz

alexanderwolz commented Feb 28, 2026

Copy link
Copy Markdown
Owner

Hi Pascal,

I finally found the time to get a closer look into your PR. Somehow I like the idea, but I'm afraid that we end up in a configuration hell.

From my concept I differ between "user", "editor" and "admin". Whereas users can only pull from namespaces they belong to by the "repo-mynamespace" group, editors can pull,push and admins can access every namespace with pull,push.

I understand that let's say: User John belongs to namespace "mycompany and he can pull+push (so he is an editor). User Jane belongs to namespace "mycompany2" and also can pull+push, but should be restricted to pull only on namespace "mycompany". I see that my design breaks here, because both users need to be "editors" in order to pull+push into their namespace repos (and hence can also push into the other namespace, when they are assigned to that group).

How would you handle your attributes approach? have these users only assign role "user" and overwrite the pull/push behavior there? Or would you create a new role like "attribute"?

I'm not so deep into these client attributes, but it seems you need to create a special client role with appropriate attributes for different use-cases?

@alexanderwolz

alexanderwolz commented Mar 2, 2026

Copy link
Copy Markdown
Owner

Hi Pascal,

I decided not to follow that attribute approach, instead I have published a new release, where you can work with sub-groups. e.g. registry-mynamespace/myrepository/editor
the last group is always either user or editor. it will override the given global namespace permission from client roles.

I will leave this PR open for discussions - feel free to close it if you are happy with my solution
you can grab the new release here: docker pull alexanderwolz/keycloak:26.5.4

@pozylon

pozylon commented Mar 2, 2026

Copy link
Copy Markdown
Author

This should work too. I addes different client roles for ex. "client-x" which can pull from domain/shared and pull push to domain/client-x/*. then i assigned that to the ci user (client-x).

i think the subgroup approach is a bit clumsy because it's not natural to follow a special convention there where as attributes are clearly something you have to know the convention. but in general it works for me.

something other i dislike a bit in your plugin is that "editor" naming and i'd line it up with the actual pull,push,catalog permissions native to docker. that way you'd have to do less mapping in code too. so subgroups beeing pull,push,catalog.

@pozylon

pozylon commented Mar 2, 2026

Copy link
Copy Markdown
Author

ah something else: currently i hsve groups like "forgejo-users" on the realm. this would interfere a bit because with your solution forgejo users would auto get access to pull from domain/forgejo-users. maybe a feat though 😂

@alexanderwolz

alexanderwolz commented Mar 5, 2026

Copy link
Copy Markdown
Owner

Hi Pascal,

I see your point and came to the same conclusion, but I explicitely decided to name the roles "user" and "editor" and "admin", as we are in a plain Keycloak environment here.
So if you are managing Keycloak realms, your are most likely to work with functional naming as role than technical. You mainly know what an editor does, but you probalby don't know that specific registry "pull push delete actions" are mapped to that. hence that naming.

Fair point. For me the new groups addon was the least invasive non-breaking change for me. Nevertheless you will end up in a configuration hell using both ways. If I find the time, I will dig in deeper into the role attibutes, but I fear that they might end up in the JWT blowing it up.

That forgejo-users thing: can you lighten me up? Normally there shouldn`t be a clash, because you have a prefix on the groups, such as "registry-forgejo-users". My plugin will only identify groups that start with the prefix "registry" (or any other that you might override)

Best, Alex

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.

2 participants