Code Monkey home page Code Monkey logo

keycloak-docker-group-role-mapper's Introduction

Docker v2 - Groups and Role Mapper for Keycloak 23.x

GitHub release (latest by date) GitHub GitHub GitHub GitHub GitHub code size in bytes GitHub all releases

🧑‍💻 About

This repository provides a MappingProvider for Keycloak's Docker-v2 protocol. It manages registry access for users with client role admin or editor and who are assigned to realm groups named like registry-${namespace}. Clients without any roles are treated as user and will be granted read-only access to the namespace by default. This behavior can be overwritten by environment variables (see configuration)

🛠️ Build

  1. Create jar resource using ./gradlew clean build
  2. Copy /build/libs/*.jar into Keycloak´s /opt/keycloak/providers/ folder
  3. Build keycloak instance using /opt/keycloak/bin/kc.sh build

See also Keycloak Dockerfile for reference in examples section.

🔬 Basic Concept

  • Users can be grouped to the same repository namespace by assigning them to one or several groups starting with registry-.
  • Without any client roles assigned, users will be granted read-only access to their namespaces.
  • Default namespaces (repositories without prefix/) can only be accessed by admins.
  • Assigning the client role editor will allow users to also push and delete images in their namespaces.
  • Assigning the client role admin will allow access to any resource in the whole registry and give full access.
  • Users could be grouped to domain-namespaces according to their email-addresses (can be configured via environment variables, default off)
  • Without having any roles and groups assigned, users will have full access to the namespace if it matches their username (can be configured via environment variables, default off)

⚙️ Configuration

This mapper supports following environment variables (either set on server or in docker container):

Variable Name Values Description
REGISTRY_CATALOG_AUDIENCE editor, user Will allow editors or users to access registry:catalog:* scope. That would be of interest to users who want to access UI frontends.
No scope is set by default, so only admins are allowed to access registry scope.
REGISTRY_NAMESPACE_SCOPE group, domain, sld, username If group is set, users are checked for group membership and will be granted access to the repository according to their roles.
If domain is set, users are checked against their email domain and will be granted access to the repository (e.g. company.com/image) according to their roles.
If sld is set, users are checked against their email second level domain (sld) and will be granted access to the repository (e.g. company/image) according to their roles.
If username is set, users will be granted full access to the namespace if it matches their username (lowercase check).

Namespace scope group is set by default or if value is empty or no value matches group, domain, sld or username (all values can be concatenated with ,).
REGISTRY_GROUP_PREFIX any String Custom group prefix. Will default to registry-. Comparisons will be checked with lowercase String representation.

🔒 Keycloak Setup

Keycloak must be setup to have a docker-v2 registry client, roles and optional groups. The registry then must be configured to use OIDC configuration provided by Keycloak

Enable Docker v2 Protocol Feature

  1. In order to use the Docker v2 protocol, the feature docker must be enabled during Keycloak server startup.
  2. This can be done by setting the environment variable KC_FEATURES=docker,token-exchange.

Create Registry Client Configuration

  1. Go to realm and choose "Clients" section
  2. Create new client by clicking "Create client"
  3. Choose Client Type docker-v2 and insert client id e.g. "myregistry"
  4. Set valid redirect URL

Create Client Roles

  1. In Client Page, choose "Roles"-tab
  2. Click "Create role" and set role name to admin
  3. Go back to "Roles"-tab
  4. Click "Create role" and set role name to editor

Set the Mapper

  1. in Client Page, choose "Client scopes"-tab
  2. Go to "myregistry-dedicated" scope
  3. Delete "docker-v2-allow-all-mapper" configuration
  4. Click "Configure a new mapper" button
  5. Choose "Allow by Groups and Roles" mapper (this mapper)
  6. Give it a name e.g. "Allow by Groups and Roles Mapper"

Keycloak Registry Client Config

Create Roles

  1. Go to realm and choose "Groups" section
  2. Click "Create group"
  3. Name it "registry-mycompany"

Assign Roles to users

  1. Go to realm and choose "Users" section
  2. Choose your user and select "Role mapping"
  3. Click "Assign role"
  4. Filter by "clients" and search for 'myregistry'
  5. Choose either admin or editor
  6. Click "Assign"

Assign Groups to users

  1. Go to realm and choose "Users" section
  2. Choose your user and select "Groups"
  3. Click "Join Group"
  4. Select "registry-mycompany"
  5. Click "Join"
  6. Now the user will have access to registry namespace myregistry.com/mycompany/

Keycloak Registry Client Config


Made with ❤️ in Bavaria
© 2024, Alexander Wolz

keycloak-docker-group-role-mapper's People

Contributors

alexanderwolz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

rayshoo

keycloak-docker-group-role-mapper's Issues

Client Type "docker-v2" doesn't exist

I have put the .jar file into the /opt/keycloak/providers/ directory. However, I can't find any "docker-v2" option there. How am I able to find that "docker-v2" option?

image

Thank you

Unable to gain access to objects inside top-level repositories

Dear Alexander, hello

My setup inside Docker

  • Docker Registry 2
  • Keycloak as SSO server ( a custom image with your Provider )
  • Traefik as HTTPS reverse proxy

Both are exposed on internet using:

Keycloak exported adapter config is:

auth:
  token:
    realm: https://sso.mydomain.com/realms/registry/protocol/docker-v2/auth
    service: registry
    issuer: https://sso.mydomain.com/realms/registry

Keycloak certificate is in the Docker Registry Compose configuration.

My problem

My registry dont have a lot of groups, a lot of images are on the top-level. ( myregistry.mydomain.com/v2/<repository>/ ) without groups or usernames in the path.
When i setup Keycloak like you recommend, i can list "catalog:*" as admin but i cant find images inside a top-level repository.

My script authentication flow is made of 3 steps:

  • Phase 1: Basic Auth ( failing with Token Auth, moving to P2 )
  • Phase 2: SSO Auth with P1 Headers ( realm, service, scope )
  • Phase 3: Bearer Auth with Registry ( OK )

In the below example, the commands are:

  • version
  • catalog
INFO:registry:Phase 1: Testing Registry Basic Auth
{'method': 'Bearer', 'realm': 'https://sso.mydomain.com/realms/registry/protocol/docker-v2/auth', 'service': 'registry'}
INFO:registry:Phase 2: Basic Auth failed, fetching IDP with realm, service and scope
INFO:registry:Phase 3: Connecting to Registry with Credentials
{'method': 'Bearer', 'realm': 'https://sso.mydomain.com/realms/registry/protocol/docker-v2/auth', 'service': 'registry', 'scope': 'registry:catalog:*'}
{}

( Docker Registry dont send version on /v2/ )

INFO:registry:Phase 1: Testing Registry Basic Auth
{'method': 'Bearer', 'realm': 'https://sso.mydomain.com/realms/registry/protocol/docker-v2/auth', 'service': 'registry', 'scope': 'registry:catalog:*'}
INFO:registry:Phase 2: Basic Auth failed, fetching IDP with realm, service and scope
INFO:registry:Phase 3: Connecting to Registry with Credentials
{'method': 'Bearer', 'realm': 'https://sso.mydomain.com/realms/registry/protocol/docker-v2/auth', 'service': 'registry', 'scope': 'registry:catalog:*'}
{'repositories': ['REDACTED']}

The problem is that the Keycloak server is always sending 'scope': 'registry:catalog:*' for both Version and Catalog

Things i dont understand

  • I need to access: https://myregistry.mydomain.com/v2/<repository>/tags/list but Keycloak always sending me 'scope': 'registry:catalog:* and a 401 UNAUTHORIZED
  • How are groups used ? ( path format ? )
  • How are users used ? ( path format ? )

what i did wrong ???

If you need full configuration/output with debug you can message me.
Regards.

ldap subgroup members not recognized

I am able to successfully configure this as follows: I create a group in keycloak called "registry-path-1" , I add users "directly" to that group, then those users (and only those users) can pull packages from repository.com/path-1/...

This works great!

Now a little bit harder setup... I have a group (Group_A) that is an LDAP Federated group. My initial thought was to still create a new group called registry-path-1 and then add Group_A as a "child group" /"subgroup" to registry-path-1 group . Keycloak has an option to "Include sub-group users" so when I select that, all my users in Group_A show up in registry-path-1 via the UI.

However, when a user tries to pull a package from "repository.com/path-1/..." it says requested access to the resource is denied.

If I keep all things the same and then add in a single user directly to "registr-path-1" group, that user can pull packages, but the other users still can not, even though they are listed there in registry-path-1 (inherited from the subgroup).

I also made sure this wasn't an LDAP thing... so I did the same test with two groups created directly in keycloak (parent being registery-) and the same behavior occurred

So it would seem this mapper can read users that are "directly" in the registry- group, however, it won't look at users that are in registry- via subgroup.

Is this intentional and/or do you have any recommendations on how it can include subgroups when it checks for group access? Alternatively, is there a way I can configure this to use "Group_A" directly instead of the "registry-" prefix? I don't have control over the name of "Group_A". I do have control over the registry-path-1 though. Was hoping this mapper could be configured such that I wouldn't need "registry-" group at al.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.