Page MenuHomePhabricator

Define auth strategy for GitLab
Closed, ResolvedPublic

Description

There has been some discussion, but will need concrete answers for implementation

  • CAS OmniAuth vs LDAP?
  • SSHKey/Email information from LDAP/CAS?
  • Group strategy

Event Timeline

summary of current state

First, there's a test instance of Apereo CAS at idp.wmcloud.org.

Second, the Omnibus gitlab-test.wmcloud.org is configured as follows (notes inline):

# I believe this should create CAS-authenticated users at login:
gitlab_rails['omniauth_allow_single_sign_on'] = ['cas']

gitlab_rails['omniauth_providers'] = [
  {
      "name" => "cas3",
      "label" => "cas",
      "args" => {
          "url" => 'https://idp.wmcloud.org',
          "login_url" => '/login',
          "service_validate_url" => '/p3/serviceValidate',
          "logout_url" => '/logout'
      }
  }
]

This works for my existing user on gitlab-test, so I assume it's keying off uid of brennen - I get this in /var/log/gitlab/gitlab-rails/application.log:

2021-02-16T21:36:37.669Z: (OAuth) saving user temp-email-for-oauth-brennen@gitlab.localhost from login with admin => true, extern_uid => brennen
2021-02-16T21:36:54.313Z: Successful Login: username=brennen ip=[redacted] method=two-factor admin=true

Additionally, under Admin -> Settings -> General -> Sign-in, there's a checkbox for "Password authentication enabled for web interface". That gives the following interface:

Screenshot from 2021-02-16 16-02-36.png (1×1 px, 116 KB)

I was hoping that turning on auto sign-on with the provider (docs here) would let users use the GitLab sign-in form but be redirected to IDP, but this causes an exception to be thrown:

gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'cas'

Notes about that on T274954.

open questions

Copying some of these in from elsewhere.

  • Keying off of uid is probably fine, as long as it's not something users can change and hijack accounts?
  • Does omniauth_allow_single_sign_on work the way I think it does? We should test a users that doesn't match any existing UID on the test box.
  • What password will GitLab use for HTTPS git remotes?
    • Admin -> Settings -> General -> Sign-in has "Password authentication enabled for Git over HTTP(S)" and says "When disabled, a Personal Access Token must be used to authenticate." That sounds kind of clunky for users, but I don't know if there's a way to have git auth against the IDP for this.
  • Is CAS actually the right provider to be using here, or should we be using the SAML one instead? The CAS plugin is pretty sparsely documented compared to https://docs.gitlab.com/ce/integration/saml.html
    • This may be a stupid question. I'm basing it on Apereo docs saying that Apereo CAS provides SAML, but this isn't an area I know well.
  • Does the CAS integration support attribute mapping, similar to the SAML integration?
  • How often is information synced between GitLab and the IDP? i.e., if a user changes their group membership or SSHkey attribute how long does it take or what is required for GitLab to pick up this change?
    • How do we clean up/delete and invalidate a user entry?

Probably missing a couple here...

cc: @jbond, @MoritzMuehlenhoff

2021-02-16T21:36:37.669Z: (OAuth) saving user temp-email-for-oauth-brennen@gitlab.localhost from login with admin => true, extern_uid => brennen

2021-02-16T21:36:54.313Z: Successful Login: username=brennen ip=[redacted] method=two-factor admin=true

Cas should be sending your email address to gitlabe so i would have hoped that it didn't need to create a temp-email-for -oauth. Are we able to enable some debuggin loggin to see a) if gitlab is receiving attributes; b) what its doing with them?

You can also automatically link SAML users with existing GitLab users if their email addresses match by adding the following setting:
For Omnibus package:

gitlab_rails['omniauth_auto_link_saml_user'] = true

Keying off of uid is probably fine, as long as it's not something users can change and hijack accounts?

The SAML docs mention the following so it seems there are code paths to also use the email

That sounds kind of clunky for users, but I don't know if there's a way to have git auth against the IDP for this.

I suspect not in all honestly however i personally think we should encourage or possibly even require ssh keys. Perhaps having the hurdle to create a token is enough to encourage users to just use ssh. For api/scripted access i think using a token is reasonable.

Is CAS actually the right provider to be using here, or should we be using the SAML one instead? The CAS plugin is pretty sparsely documented compared to

We can use either. The saml endpoints for cas are can be found on the cas docs page, just remove the /cas/ prefix i.e. . Cas is a lighter wait and simpler to implement then saml, however SAML is much more mature so products generally have better integrations. You should already be able to test using SAML but let me know if you hit any issues

When i tried to login to the gitlab interface i recived the following error message

Signing in using your cas account without a pre-existing GitLab account is not allowed.

Are we able to add the following configuration, we dont want to have to create and manage useres in two places

gitlab_rails['omniauth_allow_single_sign_on'] = true # or ['cas']

Keying off of uid is probably fine, as long as it's not something users can change and hijack accounts?

Yes. the data in LDAP is secure by the OpenLDAP ACLs. Only the users themselves and a few privileged users (SRE using a special r/w account) can alter them.

Does omniauth_allow_single_sign_on work the way I think it does? We should test a users that doesn't match any existing UID on the test box.

Depends on what you mean with any existing UID? Generally any time anyone can create user (sans some blacklisted usernames), so potentially every username can be taken/created any time. Right now there are only three users on the IDP test LDAP (brennen, jbond and jmm), so you can simply try logging in with anyother user if you want to test that flow.

Is CAS actually the right provider to be using here, or should we be using the SAML one instead? The CAS plugin is pretty sparsely documented compared to https://docs.gitlab.com/ce/integration/saml.html

SAML is most certainly wider in use as far as Gitlab installations are concerned. CAS as a protocol is what we currently use for integrating all our services, but SAML is also supported by CAS as an IDP.

CAS standardises some workflows and reduces complexity, from my PoV using CAS (as a protocol) is preferable for Gitlab unless there are technical hurdles in the Omniauth implementation.

See https://ldapcon.org/2017/wp-content/uploads/2017/08/16_Cl%C3%A9ment-Oudot_PRE_LDAPCon2017_SSO-1.pdf for some slides comparing auth protocols (the conclusion is a little exaggerated, there is no genuine security downside to using CAS how we deploy it)

Does the CAS integration support attribute mapping, similar to the SAML integration?

Yes, this is already in use and you can see it for the IDP in production: If you log into https://idp.wikimedia.org/, you can see them under "Click here to view attributes resolved and retrieved for Brennen".

How often is information synced between GitLab and the IDP? i.e., if a user changes their group membership or SSHkey attribute how long does it take or what is required for GitLab to pick up this change?
What password will GitLab use for HTTPS git remotes?

These are questions we should relay to the consultants.

Are we able to add the following configuration, we dont want to have to create and manage useres in two places

gitlab_rails['omniauth_allow_single_sign_on'] = true # or ['cas']

i just noticed we have ['cas'] however i see the omniauth_provider is named cas3 which would be the issues

The SAML docs mention the following so it seems there are code paths to also use the email

Perhaps setting

gitlab_rails['omniauth_sync_email_from_provider'] = 'cas3'

I also wonder if we can get the ssh key with

gitlab_rails['omniauth_sync_profile_attributes'] = ['email', 'sshPublicKey']

Thanks both for the detailed responses. I'll cherry-pick a couple of things here and then respond in more detail.

I suspect not in all honestly however i personally think we should encourage or possibly even require ssh keys. Perhaps having the hurdle to create a token is enough to encourage users to just use ssh. For api/scripted access i think using a token is reasonable.

Yeah, I like this.

Are we able to enable some debuggin loggin to see a) if gitlab is receiving attributes; b) what its doing with them?

I'll see what I can dig up. There's already quite a bit of logging as it is with all the services the omnibus edition bundles up, so it's possible I'm missing useful stuff in a different logfile.

CAS standardises some workflows and reduces complexity, from my PoV using CAS (as a protocol) is preferable for Gitlab unless there are technical hurdles in the Omniauth implementation.

Makes sense.

Looks like a couple of things to try with config; I'll give that stuff a shot and update here.

Also added you both as admins to the gitlab-test project, in case you want to have a look at anything there at any point. GitLab omnibus config is all in /etc/gitlab/gitlab.rb; logs are in /var/log/gitlab.

(saw this scroll by on IRC)

I suspect not in all honestly however i personally think we should encourage or possibly even require ssh keys. Perhaps having the hurdle to create a token is enough to encourage users to just use ssh. For api/scripted access i think using a token is reasonable.

Yeah, I like this.

SSH access is often blocked or rate limited by universities, libraries and so on, so having authenticated HTTPS access is pretty crucial. Gerrit requires users to use a specially generated "HTTPS password", so a similarly created token for GitLab wouldn't really be a burden/hurdle compared to the status quo.

@jbond wrote:

Perhaps setting
gitlab_rails['omniauth_sync_email_from_provider'] = 'cas3'
I also wonder if we can get the ssh key with
gitlab_rails['omniauth_sync_profile_attributes'] = ['email', 'sshPublicKey']

Currently have both of those set, if you want to take a crack at logging in without a pre-existing GitLab account again.

@Legoktm wrote:

SSH access is often blocked or rate limited by universities, libraries and so on, so having authenticated HTTPS access is pretty crucial.

Yeah, very good point.

Currently have both of those set, if you want to take a crack at logging in without a pre-existing GitLab account again.

i have tried logging in with both jbond and a new ldap account i just created in both cases i get the following error

"Your account has been blocked. Please contact your GitLab administrator if you think this is an error."

Looking at the logs it seems my account was created however it was done so again with the temp email suggesting the gitlab is not retrieving the email attribute

(have masked my real ip)

2021-02-23T09:58:39.708Z: User "jbond2" (temp-email-for-oauth-jbond2@gitlab.localhost) was created

==> /var/log/gitlab/gitlab-rails/application_json.log <==
{"severity":"INFO","time":"2021-02-23T09:58:39.709Z","correlation_id":"01EZ7574D3GCT2PNNFV613F5PM","message":"User \"jbond2\" (temp-email-for-oauth-jbond2@gitlab.localhost) was created"}

==> /var/log/gitlab/gitlab-rails/application.log <==
2021-02-23T09:58:39.734Z: Cannot obtain an exclusive lease. There must be another instance already in execution.

==> /var/log/gitlab/gitlab-rails/application_json.log <==
{"severity":"ERROR","time":"2021-02-23T09:58:39.734Z","correlation_id":"01EZ7574D3GCT2PNNFV613F5PM","message":"Cannot obtain an exclusive lease. There must be another instance already in execution."}

==> /var/log/gitlab/gitlab-rails/application.log <==
2021-02-23T09:58:39.734Z: (OAuth) saving user temp-email-for-oauth-jbond2@gitlab.localhost from login with admin => false, extern_uid => jbond2

==> /var/log/gitlab/gitlab-rails/application_json.log <==
{"severity":"INFO","time":"2021-02-23T09:58:39.734Z","correlation_id":"01EZ7574D3GCT2PNNFV613F5PM","message":"(OAuth) saving user temp-email-for-oauth-jbond2@gitlab.localhost from login with admin =\u003e false, extern_uid =\u003e jbond2"}

==> /var/log/gitlab/gitlab-rails/audit_json.log <==
{"severity":"INFO","time":"2021-02-23T09:58:39.735Z","correlation_id":"01EZ7574D3GCT2PNNFV613F5PM","author_id":85,"author_name":"jbond2","entity_id":85,"entity_type":"User","with":"cas3","target_id":85,"target_type":"User","target_details":"jbond2"}

==> /var/log/gitlab/gitlab-rails/application.log <==
2021-02-23T09:58:39.766Z: "Failed login for blocked user: user=jbond2 ip=192.0.2.17")

==> /var/log/gitlab/gitlab-rails/application_json.log <==
{"severity":"INFO","time":"2021-02-23T09:58:39.766Z","correlation_id":"01EZ7574D3GCT2PNNFV613F5PM","message":"\"Failed login for blocked user: user=jbond2 ip=192.0.2.17\")\n"}
greg triaged this task as Medium priority.Feb 24 2021, 5:37 PM
greg moved this task from Backlog to In Progress on the GitLab (Initialization) board.

cc: @OlyKalinichenkoSpeedAndFunction, @Eugene.chernov

Background:

My understanding of what we want to achieve at this point:

  • Login to GitLab should require a Wikitech account.
  • Authenticating to GitLab with our IDP should create a GitLab account, if one doesn't exist.
  • SSH key and mail should be synchronized from our IDP.
  • SAML is probably an option if the CAS integration doesn't work out, but we'd prefer to use CAS since it's simpler and we use it for everything else.
  • We plan to manage group membership on the GitLab side.
  • ...but we would like to mandate 2-factor auth for WMF employees and others with NDA / production access.
  • We need a clear picture of when things are synchronized between GitLab and CAS; ideally we don't have to do something out-of-band (for example run a service or cron job).

@jbond, @MoritzMuehlenhoff: Is the above accurate?

Thanks for the write up some minor comments inline

Wikitech developer accounts are how users create an LDAP objects for themselves:

The process for signup: https://wikitech.wikimedia.org/wiki/Help:Create_a_Wikimedia_developer_account

Just want to clarify that this background is useful however it should have no impact on the gitlab <-> cas integrations. specificity we do not want to sync data directly from LDAP.

if one doesn't exist.

some what tangential to the main topic however i would say all accounts should be created via cas <-> gitlab interactions (except for perhaps the god account)

SAML is probably an option

from the CAS side SAML is definitely an options but we would prefer to use the CAS 3.0 protocol

but we would like to mandate 2-factor auth for WMF employees and others with NDA / production access.

Just a note that we can mandate this on the cas side of things but it would be an all or nothing approach. something worth exploring or at least mentioning is that CAS can indicate if a user authenticated using 2FA. depending on gitlabs configuration it may be possible to use this attribute to require 2FA on a per repo bases instead of an all or nothing approach.

but we would like to mandate 2-factor auth for WMF employees and others with NDA / production access.

Just a note that we can mandate this on the cas side of things but it would be an all or nothing approach. something worth exploring or at least mentioning is that CAS can indicate if a user authenticated using 2FA. depending on gitlabs configuration it may be possible to use this attribute to require 2FA on a per repo bases instead of an all or nothing approach.

For additional context: 2FA access for the CAS login is currently on an opt-in basis, but our current process/tooling doesn't scale up to a level where we can handle U2F token/addition for the wider developer community. But if Gitlab supports additional self-managed 2FA within Gitlab this could be an option as well.

But if Gitlab supports additional self-managed 2FA within Gitlab this could be an option as well.

Yeah, it does, and it seems like we can enforce it on a per-group basis:

https://docs.gitlab.com/ce/security/two_factor_authentication.html#enforce-two-factor-authentication-2fa

Aside question for outbound ports for T276144: open firewall ports on gitlab1001.wikimedia.org (was: Port map of how Gitlab is accessed). Looking at https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol.html it seems that we need to ensure that the GitLab machines can make an HTTPS connection to the CAS machines -- is that accurate?

Aside question for outbound ports for T276144: open firewall ports on gitlab1001.wikimedia.org (was: Port map of how Gitlab is accessed). Looking at https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol.html it seems that we need to ensure that the GitLab machines can make an HTTPS connection to the CAS machines -- is that accurate?

That is already covered; outbound ports of gitlab1001 isn't restricted and the existing firewall rules for the IDPs already grant the necessary access.

@MoritzMuehlenhoff - @Sergey.Trofimovsky.SF is hoping to do some testing of CAS setup from gitlab-test.

Could we get the Speed & Function folks a handful of test accounts, or (only if appropriate - I don't know what else idp.wmcloud.org is used for) get them access to create accounts there?

Could we get the Speed & Function folks a handful of test accounts, or (only if appropriate - I don't know what else idp.wmcloud.org is used for) get them access to create accounts there?

Sure thing, I've added strofimovsky01 as a project admin for the "sso" project.

@Sergey.Trofimovsky.SF : You can now log into idp01.sso.eqiad1.wikimedia.cloud. This server runs the CAS installation behind idp.wmcloud.org and also runs a local slapd. Please see https://wikitech.wikimedia.org/wiki/Standalone-slapd#Create_a_user for how to add a user or https://wikitech.wikimedia.org/wiki/Standalone-slapd#Adding_a_group for adding a new group.

@Sergey.Trofimovsky.SF : You can now log into idp01.sso.eqiad1.wikimedia.cloud. This server runs the CAS installation behind idp.wmcloud.org and also runs a local slapd. Please see https://wikitech.wikimedia.org/wiki/Standalone-slapd#Create_a_user for how to add a user or https://wikitech.wikimedia.org/wiki/Standalone-slapd#Adding_a_group for adding a new group.

I just wanted to note that the SSO project provides the CAS service to other services in development. As such please only use your access for creating/updating ldap accounts. Do not change any of the CAS configuration. If there are some CAS changes you want to test please let us know here and we should be able to turn things around quite quickly.

Thanks

I just wanted to note that the SSO project provides the CAS service to other services in development. As such please only use your access for creating/updating ldap accounts. Do not change any of the CAS configuration. If there are some CAS changes you want to test please let us know here and we should be able to turn things around quite quickly.

Noted, that was the plan all along. Thank you!

So @Sergey.Trofimovsky.SF reports getting prompted for a credential when trying to follow the user creation docs:

strofimovsky01@idp01:~$ ldapadd -D "cn=admin,dc=sso,dc=eqiad1,dc=wikimedia,dc=cloud" -W -H ldapi:/// -f gltu.txt
Enter LDAP Password:

Something missing from the docs?

@Muehlenhoff @jbond - I don't know if either of you are active on WMF Slack (I'm pretty much there only for this project myself), but I added you both to a channel there we've used for comms with the Speed & Function folks.

So @Sergey.Trofimovsky.SF reports getting prompted for a credential when trying to follow the user creation docs:

Something missing from the docs?

ahh yes, i have placed the ldap cn=admin password in idp01.sso.eqiad1.wikimedia.cloud:/root/ldap

@Muehlenhoff @jbond - I don't know if either of you are active on WMF Slack (I'm pretty much there only for this project myself), but I added you both to a channel there we've used for comms with the Speed & Function folks.

i am on element if its bridged, and can jump onto slack to help if needed but its not something i generally have open or actively check

Something missing from the docs?

ahh yes, i have placed the ldap cn=admin password in idp01.sso.eqiad1.wikimedia.cloud:/root/ldap

Since this is a public knowledge, at least from this ticket, what do you think of adding -w $(cat /root/ldap) to the command in the original doc?

Something missing from the docs?

ahh yes, i have placed the ldap cn=admin password in idp01.sso.eqiad1.wikimedia.cloud:/root/ldap

Since this is a public knowledge, at least from this ticket, what do you think of adding -w $(cat /root/ldap) to the command in the original doc?

updated

For the moment, I'll just put it here for history, documentation to the 3rd party OmniAuth CAS Strategy module: https://github.com/tduehr/omniauth-cas3, which brings light to configuration options and features.

below is a summary of the current issues copied from slack

  • We would like to use the e-mail and ssh public key provided by CAS, but the names provided by Apereo do not match the names expected by Gitlab. That can happen with LDAP as well, but with LDAP the plugin has a mapping of names capability

See below think this is mostly resolved now

  • Login/Logout - issues. I think you already addressed a solution for some of the issues. If I remember correctly the use case was: I want to ban a user from Gitlab. I can log out that user from Gitlab via the admin interface, but the user will get logged in again automatically. If I ban in Apereo, Gitlab login will continue to be available for the mentioned timeout duration (1-3 hours). That might be acceptable? If not a manual workflow would be ban in both tools? Do we have this issue in other tools?

This is a general issue with SSO. Moritz and myself have an OKR this Q to provide a tool for banning users and reaping sessions across all sso services as such i dont think we should worry about it in this project.

  • User dangle issue. If a user is deleted in Apereo and then another user gets created with the same name, the user would "inherit" everything in Gitlab of the old user. Do we delete users in Apereo? Or are there other solutions that we have?

AFAIK we don't delete users so this would never be an issues pingging @MoritzMuehlenhoff in case i have missed some edge case. It is worth noting though that if this is an issue it would be one regardless os using ldap or cas

quoiting @brennen

my understanding from this thread is Apereo CAS is a hard requirement from SRE's perspective, but not necessarily the CAS protocol.

correct:

Is CAS actually the right provider to be using here, or should we be using the SAML one instead? The CAS plugin is pretty sparsely documented compared to

We can use either. The saml endpoints for cas are can be found on the cas docs page, just remove the /cas/ prefix i.e. . Cas is a lighter wait and simpler to implement then saml, however SAML is much more mature so products generally have better integrations. You should already be able to test using SAML but let me know if you hit any issues

Also worth mentioning apereo cas also supports: WS-Federation, OAuth2, OpenID, OpenID Connect

quoting @Sergey.Trofimovsky.SF

Bad news:

  • SSH keys cannot be imported from SSO, regardless of SSO type, CAS or SAML(there's hope here)

If we can get this with SAML then that is probably enough of a reason to use SAML

  • Sticking with any SSO means HTTPS git remote passwords can only be local, regardless of SSO type, CAS or SAML

I dont see any way around this however we did discuss earlier (somewhere) that users would be able to generate an API key and use that if they really had no way of using ssh.

  • Group membership sync/import from SSO is not implemented, too

Not implemented in CAS? in SAML? in CE? or at all?

  • Logout is still an issue

See above i dont think this is an issue

Good news:

    • Name/email attributes can be imported, and synced upon following logins to Gitlab if changed on the SSO/LDAP side
  • There's hook for importing extra attributes that can be defined for CAS login, theoretically it can be used for SSH keys and other custom attributes. This is definitely out of scope for the MVP

Sounds promising, can you provide some links?

  • The username clash issue can be worked around with using a unique key from LDAP/SSO, this needs to be properly verified and tested. Not sure this belongs to the MVP as well.

The CN or uid attributes should both be fine for this, however we could also present the entryUUID in the attribute set

On the other hand, LDAP integration (which is not mutually exclusive with SSO btw)

Would be curious how you get SSO with ldap integration (without of course implementing a TGT protocol in ldap)

  • Logout is still an issue

See above i dont think this is an issue

I have just tested idp.wmfcloud.org configured with SingleSignOut. When a user logs out, CAS posts a message (see below) to gitlab and the omniauth plug-in should be able to handle that message and invalidate the session. There is not any logging on the cas side indicateing why this failed however from the cas documentation i think this is expected i.e. CAS fires and forgets in a best effort manner. My best guess of what the actual issue is would be ssl validation. Either (or both) because gitlab-test.wmcloud.org has a self signed certificate or because wmfcloud.org uses HSTS. Either way i personally think this is is tno worth spending effort on. having proper attribute and group mappings would, imo, be more usefull

example logout request

https://gitlab-test.wmcloud.org/users/auth/cas3/callback?url --data 'message=logoutRequest=%3Csamlp%3ALogoutRequest+xmlns%3Asamlp%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aprotocol%22+ID%3D%22LR-11-8uYBFJwTYCMcJh0GvTIiRTnt%22+Version%3D%222.0%22+IssueInstant%3D%222021-05-10T11%3A17%3A14Z%22%3E%3Csaml%3ANameID+xmlns%3Asaml%3D%22urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Aassertion%22%3Ejbond%3C%2Fsaml%3ANameID%3E%3Csamlp%3ASessionIndex%3EST-20-XbsqjVabcdefghi3f8z1JqgM-idp01%3C%2Fsamlp%3ASessionIndex%3E%3C%2Fsamlp%3ALogoutRequest%3E'
  • User dangle issue. If a user is deleted in Apereo and then another user gets created with the same name, the user would "inherit" everything in Gitlab of the old user. Do we delete users in Apereo? Or are there other solutions that we have?

AFAIK we don't delete users so this would never be an issues pingging @MoritzMuehlenhoff in case i have missed some edge case. It is worth noting though that if this is an issue it would be one regardless os using ldap or cas

Yeah, our current workflows don't allow a user to remove the account and the future IDM will also only ever disable an account, so this can be ignored. The only edge case would be an SRE removing an account with LDAP command line tools, but not a real world concern.

  • SSH keys cannot be imported from SSO, regardless of SSO type, CAS or SAML(there's hope here)

If we can get this with SAML then that is probably enough of a reason to use SAML

By SSO here I meant all SSO integrations (including, but not limited to, CAS and SAML). SSH key synchronization configuration/code is only related to LDAP.

  • Sticking with any SSO means HTTPS git remote passwords can only be local, regardless of SSO type, CAS or SAML

I dont see any way around this however we did discuss earlier (somewhere) that users would be able to generate an API key and use that if they really had no way of using ssh.

Direct LDAP integration allows using LDAP password with HTTPS remotes.

  • Group membership sync/import from SSO is not implemented, too

Not implemented in CAS? in SAML? in CE? or at all?

YES :-)

Enhanced integration, including group membership syncing is only implemented with LDAP and included with the EE version.

    • Name/email attributes can be imported, and synced upon following logins to Gitlab if changed on the SSO/LDAP side
  • There's hook for importing extra attributes that can be defined for CAS login, theoretically it can be used for SSH keys and other custom attributes. This is definitely out of scope for the MVP

Sounds promising, can you provide some links?

Sure. From the link above (https://github.com/tduehr/omniauth-cas3), this particular option seems promising (though not easy):

fetch_raw_info - Optional. Callback used to return additional "raw" user info from other sources.

provider :cas3,
         fetch_raw_info: lambda { |strategy, options, ticket, user_info|
           ExternalService.get(user_info[:user]).attributes
        }
  • The username clash issue can be worked around with using a unique key from LDAP/SSO, this needs to be properly verified and tested. Not sure this belongs to the MVP as well.

The CN or uid attributes should both be fine for this, however we could also present the entryUUID in the attribute set

On the other hand, LDAP integration (which is not mutually exclusive with SSO btw)

Would be curious how you get SSO with ldap integration (without of course implementing a TGT protocol in ldap)

SSO integration (OmniAuth) and LDAP are implemented separately and not mutually exclusive. I didn't dig deep into that, but Gitlab has a concept of internal vs external users, LDAP users being "internal" and SSO users being "external" is one of the possible use cases.

Anyway, given that the decision to stick with SSO has been made, we're going with CAS, having following limitations in mind:

  • No SSH keys import/sync at the moment (can probably be implemented at later stages with fetch_raw_info)
  • No group membership (turns out that was never a requirement)
  • No git remote passwords from SSO
  • Logout current state

Requesting some more information on the current LDAP schema, which attributes can and should be used for key mapping (https://github.com/tduehr/omniauth-cas3), specifically these:

uid_field (CN, uid, something else?) and all keys from Configurable options for values returned by CAS

Thank you.

More good news: inspired by this issue (https://gitlab.com/gitlab-org/gitlab/-/issues/24510), @Sfigor was able to make LogOut work on the Gitlab side.

For this, “After sign out path” must be set to either the IDP logout (https://idp.wmcloud.org/logout) or a status (for more choices) page

  • Group membership sync/import from SSO is not implemented, too

Not implemented in CAS? in SAML? in CE? or at all?

YES :-)

Enhanced integration, including group membership syncing is only implemented with LDAP and included with the EE version.

Just wanted to clarify a bit on this. looking at the docs there seems to be support for SAML groups. This is not quite manage group memberships via ldap however at the very least the admin group mapping functionality would be useful to us. I'm also curious if the following configuration would work (this may not be desirable but its good to know the options)

    • Name/email attributes can be imported, and synced upon following logins to Gitlab if changed on the SSO/LDAP side
  • There's hook for importing extra attributes that can be defined for CAS login, theoretically it can be used for SSH keys and other custom attributes. This is definitely out of scope for the MVP

Sounds promising, can you provide some links?

Sure. From the link above (https://github.com/tduehr/omniauth-cas3), this particular option seems promising (though not easy):

Thanks

  • The username clash issue can be worked around with using a unique key from LDAP/SSO, this needs to be properly verified and tested. Not sure this belongs to the MVP as well.

The CN or uid attributes should both be fine for this, however we could also present the entryUUID in the attribute set

On the other hand, LDAP integration (which is not mutually exclusive with SSO btw)

Would be curious how you get SSO with ldap integration (without of course implementing a TGT protocol in ldap)

SSO integration (OmniAuth) and LDAP are implemented separately and not mutually exclusive. I didn't dig deep into that, but Gitlab has a concept of internal vs external users, LDAP users being "internal" and SSO users being "external" is one of the possible use cases.

Hmm i see so, in this scenario i with UID jbond would be able to login using either the CAS sso login or directly with authentication happening via ldap. in both instances would i get mapped to the same user id or would i as jbond have an sso external CAS account and an LDAP internal account both with different gitlab uid's. My reading of internal and external groups would suggest that this method would require users to have two separate accounts on gitlab which would be undesirable. however gitlab_rails['omniauth_auto_link_saml_user'] = true suggests things would work more closely to the the first scenario?

In relation to internal and external useres. I notices from reading the docs that by default all internal users can create top level groups and projects. In Gerrit this is something we restrict to Gerrit admins as such we may want to add gitlab_rails['gitlab_default_can_create_group'] = false. (@brennen @thcipriani something for you to consider)

Probably out of scope for the MVP but bypass two factor authentication from what i can tell this enables CAS/SAML to indicate to gitlab if a user has authenticated using 2fa

Anyway, given that the decision to stick with SSO has been made, we're going with CAS, having following limitations in mind:

Most theses points seem fine to me however

  • No group membership (turns out that was never a requirement)

@brennen, @thcipriani, @wkandek, @faidon this would be a step backwards from what we have currently in gerrit and would add significant overhead and tooling to on-boarding, off-boarding, and audit capabilities. further it will likly lead to authorisation fragmentation some thing we try to avoid by defining high-level group rights in a central location

More good news: inspired by this issue (https://gitlab.com/gitlab-org/gitlab/-/issues/24510), @Sfigor was able to make LogOut work on the Gitlab side.

great news this is a nice step forward. Note to self: we change the endpoint to a page asking the user to first confirm they want to kill there sso session and logout of all SSout enabled services

Requesting some more information on the current LDAP schema, which attributes can and should be used for key mapping (https://github.com/tduehr/omniauth-cas3), specifically these:

uid_key: Depends, users authenticate on CAS(IDP with the cn attribute, but for shell operations and current git checkout the "uid" attribute is used
name_key: No equivalent attribute exists, if it's mandatory you could fall back to "cn"
email_key: "mail" attribute
nickname_key: No equivalent attribute exists
first_name_key: No equivalent attribute exists
last_name_key: No equivalent attribute exists
location_key: No equivalent attribute exists
image_key: No equivalent attribute exists
phone_key: No equivalent attribute exists

  • No group membership (turns out that was never a requirement)

@brennen, @thcipriani, @wkandek, @faidon this would be a step backwards from what we have currently in gerrit and would add significant overhead and tooling to on-boarding, off-boarding, and audit capabilities. further it will likely lead to authorisation fragmentation some thing we try to avoid by defining high-level group rights in a central location

Thanks to @hashar we have a rough list of gerrit groups that are currently mapped to ldap OU's

  • No group membership (turns out that was never a requirement)

@brennen, @thcipriani, @wkandek, @faidon this would be a step backwards from what we have currently in gerrit and would add significant overhead and tooling to on-boarding, off-boarding, and audit capabilities. further it will likely lead to authorisation fragmentation some thing we try to avoid by defining high-level group rights in a central location

Thanks to @hashar we have a rough list of gerrit groups that are currently mapped to ldap OU's

This list is a good example of how hard it is to reason about gerrit privileges.

For example: why is wmf in the qa group? unclear. Also, that we have a gerrit group called wmde that is populated with the ldap group wmde is...probably an anti pattern :)
We should not repeat this list.

There are some important groups here for onboarding and offboarding: ops, wmf, wmde, and gerritadmin. Of those, gerritadmin's gitlab equivalent can probably be managed manually in GitLab since there are like 10 people that are administrators and it doesn't correspond to a real-world organizational unit.

The groups that respond to a real-world org unit seem important for onboarding/offboarding: ops, wmf, wmde

If CAS is a requirement, and group membership syncing is a requirement, but the CAS omniauth provider does not provide group membership syncing: where does that leave us?

that we have a gerrit group called wmde that is populated with the ldap group wmde is...probably an anti pattern :)
We should not repeat this list.

I agree this is not great, ideally ldap groups would show up automaticity as something that can be directly assigned however having to provide one-to-one mappings is quite common in apps and is similar to how the gitlab-ee ldap mappings work

Of those, gerritadmin's gitlab equivalent can probably be managed manually in GitLab since there are like 10 people that are administrators

I think this is actually the one we could do as it looks similar to the SAML Admin groups

This list is a good example of how hard it is to reason about gerrit privileges.

To clarify i don't advocate gerrits system, im also not a power user or gerrit admin so am not the best person to offer constructive feedback, however centralising and unifying theses issues seems like a win

The groups that respond to a real-world org unit seem important for onboarding/offboarding: ops, wmf, wmde

yes exactly theses are the main groups which will need some on/offboard consideration, however with CAS future development the hope is to allow more fin grained groups at the ldap/IDM level

If CAS is a requirement

For SRE CAS the service, is a requirement cas the protocol is not. however as we stand right the only difference that LDAP offers over using CAS service (with SAML* or CAS** the protocol) is the ability to use git clone https://... instead of git clone ssh://... and with my security hat on i could argue that is a benefit and not a negative. however it was mentioned elsewhere that some users behind shared firewalling infrastructure i.e. universities may not have access to ssh. I'm not sure how much of an issue this is and i wonder if it it will be less of an issue when using port 22 instead of the current port

and group membership syncing is a requirement

From my perspective i think we should have some way do do this

, but the CAS omniauth provider does not provide group membership syncing

from what i see and i think @Sergey.Trofimovsky.SF confirmed, this is simply not possible in CE regardless of SAML/CAS (protocol or service)/LDAP

where does that leave us?

  • Without EE this is something we would have to either live with or implement our self, we may be able to knock something up using the gitlab API???
  • with EE its possible we could have a hybrid set up with SSO used for user authentication and ldap used for group syncing

*from what i can, when using the CE edition of gitlab, CAS with SAML offers feature parity with LDAP when it comes to groups and attribute mapping
**i think that S&F have done a great job at integrating CAS the protocol with gitlab however it seems that using SAML allows for a richer feature set so going forward.

with EE its possible we could have a hybrid set up with SSO used for user authentication and ldap used for group syncing

Just wanted to make a comment that SAML syncing may also be possible directly in EE. I say possible as the docs reference to both EE and gitlab.com so it could be that this is only possible for the SaaS offering.

as we stand right the only difference that LDAP offers over using CAS service (with SAML* or CAS** the protocol) is the ability to use git clone https://... instead of git clone ssh://...

I have just tested on gitlab-test.wmfcloud.org and users can create a personal access token which can be used with as a password with ones username to preform git operations over https. As such im not sure ldap with CE offers any additional features

Just wanted to make a comment that SAML syncing may also be possible directly in EE

Just for clarity: CE is a hard requirement.

I have just tested on gitlab-test.wmfcloud.org and users can create a personal access token which can be used with as a password with ones username to preform git operations over https.

Yeah, I don't have links handy, but we've discussed this elsewhere and it seems like a reasonable tradeoff (and probably a bit more secure, since it doesn't risk their main password) for those users who do need HTTPS remotes.

Just wanted to make a comment that SAML syncing may also be possible directly in EE

Just for clarity: CE is a hard requirement.

Ack thanks, i thought it was but wasn't 100%

I have just tested on gitlab-test.wmfcloud.org and users can create a personal access token which can be used with as a password with ones username to preform git operations over https.

Yeah, I don't have links handy, but we've discussed this elsewhere and it seems like a reasonable tradeoff (and probably a bit more secure, since it doesn't risk their main password) for those users who do need HTTPS remotes.

Agreed

from what i see and i think @Sergey.Trofimovsky.SF confirmed, this is simply not possible in CE regardless of SAML/CAS (protocol or service)/LDAP

Got it.

where does that leave us?

  • Without EE this is something we would have to either live with or implement our self, we may be able to knock something up using the gitlab API???
  • with EE its possible we could have a hybrid set up with SSO used for user authentication and ldap used for group syncing

As CE was the outcome of the community consultation, it sounds like the "knock something up using the gitlab API" option is the one that remains. I'd prefer not to block on implementation of the system, but finding agreement about how such system could be implemented would be a good conclusion.

As CE was the outcome of the community consultation, it sounds like the "knock something up using the gitlab API" option is the one that remains.

Agreed

I'd prefer not to block on implementation of the system, but finding agreement about how such system could be implemented would be a good conclusion.

Sure my intention was never to block (i don't i think have such powers ;)) more highlighting that this is something we will need to pick up. I'll try to have a look by the gitlab API's tomorrow and see what's exposed.

Change 699819 had a related patch set uploaded (by Brennen Bearnes; author: Brennen Bearnes):

[operations/gitlab-ansible@master] CAS: stop marking users as external

https://gerrit.wikimedia.org/r/699819

Change 699819 merged by Brennen Bearnes:

[operations/gitlab-ansible@master] CAS: stop marking users as external

https://gerrit.wikimedia.org/r/699819

Mentioned in SAL (#wikimedia-operations) [2021-06-22T20:46:35Z] <brennen> gitlab1001: running ansible to deploy [[gerrit:699819|CAS: stop marking users as external]] (T274461)

brennen edited projects, added GitLab; removed GitLab (Initialization).
brennen edited projects, added GitLab (Auth & Access); removed GitLab.

Mentioned in SAL (#wikimedia-releng) [2022-03-15T18:10:10Z] <brennen> gitlab: finished migrating access for all existing people groups to direct project membership (T274461, T300935)

thcipriani assigned this task to brennen.