CAS-SSO

The Wikimedia Developer SSO Portal at idp.wikimedia.org is a single sign-on (SSO) infrastructure built on Apereo CAS.
When logging into a CAS-enabled website without an active SSO session you'll be redirected to the CAS login page (https://idp.wikimedia.org/login) The CAS service collects LDAP group memberships and makes them available to services for making authorisation choices. After authentication the users get redirected to the initiating service.
The authentication happens with your Wikimedia developer account. There's also the possibility of adding a second factor using U2F, see below how to enable it. 
Instructions for using SSO can be found at Single Sign On. 
If you select "Remember Me" during, a long term session is initiated. It lasts for seven days (or until you logout via https://idp.wikimedia.org/logout). This option must only be enabled when working from a machine that only you use. If that's not the case and "Remember Me" is not used, your SSO session will expire after one hour of inactivity.
== Service ==
The source code is in the operations/software/cas-overlay-template repository.
The service runs mainly on idp1001 in Eqiad and idp2001 in Codfw.
== Enabling U2F as a second factor ==
Apereo CAS supports U2F as a second factor. This is configured on a per-user opt in basis and configured via LDAP. Supported browsers
are Chrome/Chromium, Firefox (ESR68 and later, ESR60 had some issues in tests, but it's EOLed anyway now) and Safari (13 and later).
All Yubikeys issued by OIT should be compatible. Onlykeys were also reported to work (https://phabricator.wikimedia.org/T242438)
=== Requesting to enable U2F (if you're not in SRE) ===
Mid-term, enabling U2F for web SSO will be part of our account management. Until then, please open a task in Phabricator and apply the LDAP-Access-Requests tag. Your SSO account will be U2F-enabled by the SRE person currently on Clinic Duty.
See also: Single Sign On#Enabling 2FA using a YubiKey.
=== Enabling U2F for an account ===
To enable U2F as a second factor, run the following on either mwmaint1002 or mwmaint2002:
 sudo modify-mfa --enable UID
To disable U2F, use
 sudo modify-mfa --disable UID
Note that CAS operates on the readonly LDAP replicas, so it might take up to two minutes minutes until the LDAP change is effective. To verify the change actually took place:
 ldapsearch -x 'uid=UID' | grep mfa-method
should return mfa-method: mfa-u2f
UID is the shell username here (as that's what identifies your identity on the LDAP level, not the Wikimedia Developer Name). Once it's enabled, the next time you login to the SSO session, you will be asked to register your U2F token. This registration screen is disabled after you have entered your username and password. Subsequent logins will require you authenticate via the U2F token in a similar manner i.e enter username and password then get forwarded to a screen to authenticate with your U2F tokens.
If you want to force the U2F registration immediately instead of waiting for your SSO session to expire, simply logout and log back in
Mid-term we'll have a proper identity management solution which will make registration on the shell obsolete. 
In the current version CAS only supports a single token. If you lose your token it needs to be removed from configuration at which point a replacement token can be added.
== Known issues / FAQ ==
* We don't implement full Single Logout yet, will be handled via https://phabricator.wikimedia.org/T233941
=== What username do services use ===
When user logs into a CAS protected service a number of attributes are used to authenticate the user to the original services. The main attributes which are used for this are as follows, mapped directly to a users ldap entry:
* cn
* uid
* memberOf
The memberOf attribute is the one most often used for authorisation as such if a user can login to https://idp.wikimedia.org and they are in the correct ldap group for a specific services then they should be able to login with no issue. 
Some services will create local accounts for every user and to do this they need to use a unique attribute representing the user. The majority of services use the uid attribute for this but some definitely do use the cn (for example Gerrit and Gitlab). As such if the uid and cn are different for your account you may notice differences when switching between services, however one shouldn't suffer any issues.
One of the areas where we do have issues though is for services expecting to use the REMOTE_USER environment variable for authentication, specifically Icinga. In this case we have a strange combinations of issues:
* Our LDAP instance is configured to compare cn in a case insensitive manner
* CAS passes the username as entered by the user as an additional value namely cas_user
* Apache web servermod_auth_cas maps the cas_user attribute to REMOTE_USER
The combination of theses things means that we can see strange issues when logging into services that key off the REMOTE_USER if users login using mixed or unexpected cases. Currently the only service affected by this is Icinga
== Debugging ==
The first thing to get a user to do is to try and login to https://idp.wikimedia.org directly and ensure they can loging and that the attributes shown for the user looks correct. Further to this you can ask the user to visit https://idp-test.wikimedia.org/ and ensure the output there looks correct.
=== mod_auth_cas ===
mod_auth_cas stores session information in /var/cache/apache2/mod_auth_cas/$vhost. As such if an application is protected using mod_auth_cas you should be able to check the user sessions with something like the following
$ sudo grep -lr jbond /var/cache/apache2/mod_auth_cas/ 
/var/cache/apache2/mod_auth_cas/grafana-rw.wikimedia.org/***REDATED***
$ sudo cat $(!!)
sudo cat $(sudo grep -lr jbond /var/cache/apache2/mod_auth_cas/) 
<cacheEntry xmlns="http://uconn.edu/cas/mod_auth_cas">
<user>jbond</user>
<issued>1642085590748873</issued>
<lastactive>1642085603972189</lastactive>
<path>/d/C0lCOf3Mz/</path>
<ticket>***REDACTED***</ticket>
<attributes>
 <attribute name="org.apereo.cas.authentication.principal.REMEMBER_ME">
 <value>true</value>
 </attribute>
 <attribute name="clientIpAddress">
 <value>192.0.2.42</value>
 </attribute>
 <attribute name="sshPublicKey">
 <value>ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIELDJGi+7kchVkEJNgqGvLOT2UOS4CP5HUSUBdyATdfc jbond@work-laptop</value>
 </attribute>
 <attribute name="isFromNewLogin">
 <value>false</value>
 </attribute>
 <attribute name="mail">
 <value>jbond@wikimedia.org</value>
 </attribute>
 <attribute name="authenticationDate">
 <value>2022-01-10T14:55:50.941850Z</value>
 </attribute>
 <attribute name="bypassMultifactorAuthentication">
 <value>false</value>
 </attribute>
 <attribute name="authnContextClass">
 <value>mfa-u2f</value>
 </attribute>
 <attribute name="successfulAuthenticationHandlers">
 <value>U2FAuthenticationHandler</value>
 </attribute>
 <attribute name="userAgent">
 <value>Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0</value>
 </attribute>
 <attribute name="cn">
 <value>Jbond</value>
 </attribute>
 <attribute name="credentialType">
 <value>U2FTokenCredential</value>
 </attribute>
 <attribute name="samlAuthenticationStatementAuthMethod">
 <value>urn:oasis:names:tc:SAML:1.0:am:unspecified</value>
 </attribute>
 <attribute name="uid">
 <value>jbond</value>
 </attribute>
 <attribute name="authenticationMethod">
 <value>U2FAuthenticationHandler</value>
 </attribute>
 <attribute name="serverIpAddress">
 <value>127.0.0.1</value>
 </attribute>
 <attribute name="longTermAuthenticationRequestTokenUsed">
 <value>false</value>
 </attribute>
 <attribute name="memberOf">
 <!-- trimmed -->
 <value>cn=wmf,ou=groups,dc=wikimedia,dc=org</value>
 <!-- trimmed -->
 </attribute>
 <attribute name="mfa-method">
 <value>mfa-u2f</value>
 </attribute>
</attributes>
</cacheEntry>
== Alerting ==
=== DownProbe - idp.wikimedia.org down ===
Most likely Tomcat or the Apereo CAS application has crashed. 
Try restarting Tomcat, this is always safe to do. The service will be unavailable while Tomcat is restarting, but no state is stored within CAS itself, and restarting cannot damage anything.
$ sudo systemctl restart tomcat10
If restarting does not fixes the issue, but the standby CAS node is responsive, fail-over to the standby. This is done by updating the record in https://gerrit.wikimedia.org/r/plugins/gitiles/operations/dns/+/refs/heads/master/templates/wikimedia.org.
There are currently two nodes available, one in codfw idp200X.wikimedia.org and idp100X.wikimedia.org in eqiad. If the active, and failed node is idp200X, fail-over to idp100X.
== External link ==
* https://idp.wikimedia.org
Category:SRE Infrastructure Foundations