SSO integration with Foreman via Keycloak

Hello,

I have been working on the SSO integration with foreman using keycloak, my finding are( refering to the awesome blog post by Pep: https://www.theforeman.org/2018/06/using-saml-for-single-sign-on-to-foreman-through-keycloak.html):

  1. By default, when we try to login in to https://foreman.example.com we get directly redirected to the saml page.
  2. For internal users to login, they need to specifically mention https://foreman.example.com /users/login
  3. Once logged in via sso we have the user created within foreman with the permissions and roles that are specified in keycloak for the user.

Suggestions on how to implement keycloak :

  1. The current configuration leads to the user to remeber two urls
    a) https://foreman.example.com or https://foreman.example.com /users/extlogin
    b) https://foreman.example.com /users/login
    Instead, i would suggest we can have a link on the login page that says external login to
    redirect to the keycloak authentication page.

  2. Having an option for enabling/disabling the keycloak service from the foreman-installer. This would
    enable the users to decide whether they require/need this feature or not.

These are my thoughts for implementing sso with foreman, any suggestions or comments would be highly appreciated :slight_smile:

Thanks,

If I understand the proposal, as long as a user has self-configured keycloak, Foreman needs only to add an option that can link to an external login page on the actual login page?

Is this simply to know when to show the external login page link? I see mention of “enabling” Keycloak the service but I don’t think Foreman should handle any part of the Keycloak service itself.

Follow up question, there is a proposal to move our application server to Puma behind an Apache proxy. Does that change how Keycloak external authentication is handled?

I would actually suggest that if configured, the default experience should be to use SAML. Then, if we want a non SAML item then go to a different URL.

I am also curious about impacts on hammer :slight_smile:

Title updated at @rabajaj’s request, just in case anyone is filtering on title… :stuck_out_tongue:

1 Like

Yes, that’s correct, the Keycloak service would be unmanaged. If we’re saying that with SSO option turned on, we won’t have a visible way of logging in via local users – then we’re good. Otherwise, we may need to add something on the login page.

I agree, Keycloak the service shouldn’t be handled by Foreman. But apart from detecting if SSO logins are enabled on Foreman, we may also need to set/unset Apache settings and Foreman’s settings.yaml related to login_delegation. For example when the user wishes to disable SSO.

It does not change much. The only changes that we anticipate are:

  1. Apache’s handling of <Location /saml2> and <Location /users/extlogin>. It must intercept these URLs and not pass it on to the Puma server.
  2. Pass on the Mellon env vars to Puma (?).

I agree. I suppose if they configure an external login then it’s a primary way of authentication.
So the current implementation makes sense to me.

We can’t use external login with API (and hammer) at all now, so there will be no impact :slight_smile:

Seriously now:
Good portion of important features to support that has been implemented: sessions in both API & hammer plus support for multiple authentication ways and session retry in hammer.

Two more things are imho necessary to get external auth sources working with hammer:

  • add an equivalent of users/extlogin into the API
  • create an authenticator in hammer that uses the api extlogin when the session doesn’t exist

Hello,

I was looking out for a solution for the SSO integration, there are only
two approached that is possible right now with keycloak(these solutions were suggested by one of the members of the keycloak team):

  1. Command-line tools in userspace would probably fall under guidelines given in RFC8252[0]. To summarize, it would basically mean hammer providing a callback mechanism (i.e.localhost port) and spinning up a web browser for the auth process.

  2. The keycloak team is also working on the offline token initiative, whereby apps can store long-lived credentials so users don’t have to continually re-auth (if that isn’t desired).

I was keen on implementing the second approach as it is been commonly used and would be easy for the users to adapt to but since the timeline for the feature to be implemented is not certain I think we should go with the first approach. The first approach is not really clear to me, I need to look into it more closely.

Do you have any thoughts over this @Tomas_Strachota @Anurag?

[0] https://tools.ietf.org/html/rfc8252

Thanks,

Here is an interesting topic on this.

One thing I would be curious about from folks, would it be acceptable to require the use of sessions in hammer if oauth is setup? That would allow for the webserver trick to only be used once per session.

+1 for using a temporary web server @rabajaj Do you thing it would be possible to avoid opening a login page in a browser and send credentials from hammer?

Requiring sessions in such configuration (regardless of if it’s on in the config) makes sense to me. It should be seamless for users.

Temporary webserver on hammer side because of the callback sounds very hacky to me. Also very prone to errors, users would need to reconfigure firewall and update selinux on every client host they would use hammer on. Is there some other open source CLI that integrates keycloak? How they solve it? If not, could the Foreman be the thing that receives callback?

Or let’s wait until keycloak has tokens support?

Hello,

The approach that I am implementing now is:

Collect credentials directly in the CLI and exchange for a token
this token is further passed to foreman to validate the token and
provide a session to the user. The session is then used to provide
the required output to the user in CLI.

My findings ( Following steps are involved in the implementation ):

  1. Getting the token from CLI by giving keycloak username/password.
  2. Passing this token to foreman
  3. Use this JWT token for validation(which involves):
    a) Validation of the JWT token
    b) If JWT token is valid then authenticate the user using it.

progress for the feature : https://github.com/theforeman/foreman/pull/6395