.. _12-external-idp-support: Unit 12: Authentication against external Identity Providers =========================================================== **Prerequisites:** - :ref:`Unit 11: Kerberos ticket policy <11-kerberos-ticket-policy>` In this module you will explore how to manage use external OAuth 2.0 servers to authorize issuance of Kerberos tickets in FreeIPA. **Note:** To complete this module, FreeIPA-4.10 or later is needed. Authentication using external Identity Providers ------------------------------------------------ It is possible to let FreeIPA to delegate authentication and authorization process of issuing Kerberos tickets to an external entity. FreeIPA has been supporting RADIUS server proxying for some time. This is exposed over Kerberos with the help of 'otp' pre-authentication mechanism. Configuration of the RADIUS proxy authentication is done in two steps: first, create a RADIUS proxy object in FreeIPA and then associate the user account with this RADIUS proxy object. There is no specific requirement as to how RADIUS proxy actually authenticates the user. It is left outside the FreeIPA scope. The connection to the RADIUS server becomes critical and is important to protect. This approach has been extended to allow FreeIPA to contact an OAuth 2.0 Authorization Server instead of RADIUS server. OAuth 2.0 authorization framework is a modern way to delegate authorization decisions between loosely coupled parties. It heavily relies on the ability to use HTTP redirects to guide a user's browser to hop between OAuth 2.0 parties and reach the one that logs user in and the one that authorizes the access. Traditionally, it was hard to integrate with OAuth 2.0-enabled systems in POSIX environment because there is no way to run a browser session from within the shell or console. Most of OAuth 2.0 identity providers (IdP) heavily rely on JavaScript and other modern browser features to provide an enhanced user experience. Emulating the login pages as part of line- and packet-oriented SSH protocol or console login script is not possible. OAuth 2.0 Device Authorization Grant is defined in `RFC 8628 `_ and allows devices that either lack a browser or input constrained to obtain user authorization to access protected resources. Instead of performing the authorization flow right at the device where OAuth authorization grant is requested, a user would perform it at a separate device that has required rich browsing or input capabilities. Following figure demonstrates a generic device authorization flow: .. uml:: participant "End User at Browser" participant "Device Client" participant "Authorization Server" "Device Client" -> "Authorization Server": (A) Client Identifier "Authorization Server" -> "Device Client": (B) Device Code, User Code & Verification URI "Device Client" -> "End User at Browser": (C) User Code & Verification URI "End User at Browser" <-> "Authorization Server": (D) End user reviews authorization request "Device Client" -> "Authorization Server": (E) Polling with Device Code and Client Identifier "Authorization Server" -> "Device Client": (F) Access Token (& Optional Refresh Token) FreeIPA implements a variation of this flow and hides it behind Kerberos KDC. A special pre-authentication method in MIT Kerberos, ``idp`` is implemented in SSSD 2.7.0 to facilitate the process outlined above. Device authorization grant flow decouples the process into several steps: - the device initiates OAuth 2.0 flow and receives a response from the Authorization Server that contains a special code and a link to a website user needs to visit to authorize the device; - user opens this website somewhere else (mobile, desktop, etc) where a proper browser is available; - user is asked to enter the special code; - if needed, user would be asked login into an OAuth 2.0-based IdP; - once logged in, IdP would ask user if they authorize this device to access certain user information; - once the access request is granted, user comes back to the device's prompt and confirms it; - the device at this point would poll OAuth 2.0 Authorization Server on whether it is allowed to access user information already. Set up external IdP integration in FreeIPA ------------------------------------------ In order to perform OAuth 2.0 device authorization grant flow against an IdP, an OAuth 2.0 client has to be registered with the IdP and a capability to allow the device authorization grant has to be given to it. Not all IdPs support this feature. Out of the known public ones, following IdPs do support device authorization grant flow: * Microsoft Identity Platform, including Azure AD * Google * Github * Keycloak, including Red Hat SSO * Okta Many OAuth 2.0 platforms do not support device authorization grant flow and cannot be directly enabled to operate with FreeIPA. However, one can always chain (federate) IdPs. It means that, for example, one can deploy Keycloak locally to allow users to sign in with identities from a different IdP. In that case the local Keycloak instance would need to be registered as an OAuth 2.0 client with the remote IdP. Local Keycloak instance would then be registered with IPA. Setting up IdP references (OAuth 2.0 clients) in IPA can be done with ``ipa idp-add`` command. The command accepts an option to specify a pre-defined template for one of the known IdPs. If none of the pre-defined templates is suitable, individual parameters can also be added:: ipa help idp-add Usage: ipa [global-options] idp-add NAME [options] Add a new Identity Provider reference. Options: -h, --help show this help message and exit --auth-uri=STR OAuth 2.0 authorization endpoint --dev-auth-uri=STR Device authorization endpoint --token-uri=STR Token endpoint --userinfo-uri=STR User information endpoint --keys-uri=STR JWKS endpoint --issuer-url=STR The Identity Provider OIDC URL --client-id=STR OAuth 2.0 client identifier --secret OAuth 2.0 client secret --scope=STR OAuth 2.0 scope. Multiple scopes separated by space --idp-user-id=STR Attribute for user identity in OAuth 2.0 userinfo --setattr=STR Set an attribute to a name/value pair. Format is attr=value. For multi-valued attributes, the command replaces the values already present. --addattr=STR Add an attribute/value pair. Format is attr=value. The attribute must be part of the schema. --provider=['google', 'github', 'microsoft', 'okta', 'keycloak'] Choose a pre-defined template to use --organization=STR Organization ID or Realm name for IdP provider templates --base-url=STR Base URL for IdP provider templates --all Retrieve and print all attributes from the server. Affects command output. --raw Print entries as stored on the server. Only affects output format. In this part we would use Keycloak IdP to integrate with IPA. Next section shows how to set up Keycloak on a host enrolled into IPA domain. All shell scripts below assume execution under ``root`` privileges. Set up Keycloak IdP on enrolled IPA client ------------------------------------------ In this section, we set up `Keycloak `_ IdP on IPA client and use it to authenticate IPA users. User database in Keycloak would be different from the one in IPA, one would need to keep user accounts duplicated in both places but this would simplify our configuration. We also would use automation provided by the Keycloak to set up OAuth 2.0 clients and user accounts. First, we would download keycloak and unpack it into ``/opt/keycloak-`` as ``root``:: [root@client ~]# dnf -y install java-11-openjdk-headless openssl #### download keycloak #### [root@client ~]# export KEYCLOAK_VERSION=18.0.0 [root@client ~]# wget https://github.com/keycloak/keycloak/releases/download/${KEYCLOAK_VERSION}/keycloak-${KEYCLOAK_VERSION}.tar.gz [root@client ~]# tar zxf keycloak-${KEYCLOAK_VERSION}.tar.gz -C /opt #### add keycloak system user/group and folder #### [root@client ~]# groupadd keycloak [root@client ~]# useradd -r -g keycloak -d /opt/keycloak-${KEYCLOAK_VERSION} keycloak [root@client ~]# chown -R keycloak:keycloak /opt/keycloak-${KEYCLOAK_VERSION} [root@client ~]# chmod o+x /opt/keycloak-${KEYCLOAK_VERSION}/bin/ [root@client ~]# restorecon -R /opt/keycloak-${KEYCLOAK_VERSION} Next step would be to prepare a TLS certificate to be used to protect HTTPS connections in Keycloak. Since our system is already enrolled into IPA, we can rely on two features: * Enrolled IPA client has Kerberos host principal registered with keytab in ``/etc/krb5.keytab`` * Enrolled IPA client host Kerberos principal can manage Kerberos services on the same host This means we can create ``HTTP/client...`` Kerberos service right from the IPA client and use ``certmonger`` to issue TLS certificate for it. Certmonger would automatically renew the certificate. The following sequence of commands demonstrates how to achieve this, run as root:: ########## setup TLS certificate using IPA CA ############################### [root@client ~]# kinit -k [root@client ~]# ipa service-add HTTP/$(hostname) [root@client ~]# ipa-getcert request -K HTTP/$(hostname) -D $(hostname) \ -o keycloak -O keycloak \ -m 0600 -M 0644 \ -k /etc/pki/tls/private/keycloak.key \ -f /etc/pki/tls/certs/keycloak.crt \ -w [root@client ~]# keytool -import \ -keystore /etc/pki/tls/private/keycloak.store \ -file /etc/ipa/ca.crt \ -alias ipa_ca \ -trustcacerts -storepass Secret123 -noprompt [root@client ~]# chown keycloak:keycloak /etc/pki/tls/private/keycloak.store The private key for this certificate is stored in ``/etc/pki/tls/private/keycloak.key``, only accessible to the keycloak user. Public part of the certificate is stored in ``/etc/pki/tls/certs/keycloak.crt`` and has permissions 0644. We also import IPA CA's chain to a Java keystore that would be used by Keycloak, stored at ``/etc/pki/tls/private/keycloak.store``. Finally, we need to set up ``systemd`` service to run Keycloak:: # Setup keycloak service and config files [root@client ~]# cat > /etc/sysconfig/keycloak < /etc/systemd/system/keycloak.service <ipa_client.json <`` key. If authorization was granted, KDC will issue a Kerberos ticket to and it will be stored in the credentials cache:: [root@client ~]# klist Ticket cache: KCM:0:58420 Default principal: testuser1@IPADEMO.LOCAL Valid starting Expires Service principal 05/09/22 07:48:23 05/10/22 07:03:07 krbtgt/IPADEMO.LOCAL@IPADEMO.LOCAL Similar process happens when ``pam_sss`` PAM module is used, for example, to authenticate and authorize access to PAM services. Applications which use PAM to authenticate and authorize remote access can also benefit from the flow. For example, SSH daemon can be configured with ``keyboard-interactive`` method which will allow PAM authentication and authorization. As part of it, PAM messages will be relayed to the SSH client and SSH client's user input will be sent back to PAM:: $ ssh testuser1@client.ipademo.local (testuser1@client.ipademo.local) Authenticate at https://client.ipademo.local:8443/auth/realms/master/device?user_code=XYFL-ROYR and press ENTER. Last login: Mon May 9 07:48:25 2022 from 10.0.190.227 -sh-5.1$ klist Ticket cache: KCM:7800003:58420 Default principal: testuser1@IPADEMO.LOCAL Valid starting Expires Service principal 05/09/22 07:49:38 05/10/22 07:49:24 krbtgt/IPADEMO.LOCAL@IPADEMO.LOCAL -sh-5.1$ Once initial Kerberos ticket is available, it can be used to perform normal IPA operations: - access IPA API with command line tool ``ipa`` or through a Web UI in a browser - login to other systems with GSSAPI authentication - access PAM services which use ``pam_sss_gss`` module in their PAM stack definitions Direct authentication to Web UI with the help of OAuth 2.0 client is not implemented yet. Troubleshooting IdP integration ------------------------------- Communication with an IdP server happens on IPA server when KDC calls out to ``ipa-otpd`` daemon and ``ipa-otpd`` daemon launches ``oidc_child`` helper. Journal logs for ``ipa-otpd`` can be checked with the ``journalctl`` tool. ``ipa-otpd`` processes start on demand and content from all sessions can be captured with the following command:: [root@master #] journalctl -u 'ipa-otpd@*' The output would look similar to the following real world example:: May 02 18:51:28 dc.ipa.test systemd[1]: Started ipa-otpd service (PID 1473660/UID 0). May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: LDAP: ldapi://%2Frun%2Fslapd-IPA-TEST.socket May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: request received May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: user query start May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: user query end: uid=ab,cn=users,cn=accounts,dc=ipa,dc=test May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: idp query start: cn=github,cn=idp,dc=ipa,dc=test May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: idp query end: github May 02 18:51:28 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: oauth2 start: Get device code May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: Received: [{"device_code":"f071833afe966eaf596d83646f55250cfdb57418","expires_in":899,"interval":5} May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: oauth2 {"verification_uri": "https://github.com/login/device", "user_code": "ECD3-4310"} May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: ] May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: sent: 0 data: 200 May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: ..sent: 200 data: 200 May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: ab@IPA.TEST: response sent: Access-Challenge May 02 18:51:29 dc.ipa.test ipa-otpd[1636136]: Socket closed, shutting down... First part of the output until ``idp query start`` is similar to RADIUS proxy operation. Unlike RADIUS proxy, in the case of IdP communication, ``ipa-otpd`` first receives an initial state from the ``oidc_child`` process and sends it back to the KDC within a RADIUS packet with ``Access-Challenge`` message. The state is then transferred to the Kerberos client and results in a message that instructs to visit the verification URI and enter the code. Some IdPs also return a complete message to show, like in the case of Keycloak in our examples above. Once the Kerberos client returns, another ``ipa-otpd`` call is performed, this time to request an access token:: May 02 18:51:50 dc.ipa.test systemd[1]: Started ipa-otpd service (PID 1473661/UID 0). May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: LDAP: ldapi://%2Frun%2Fslapd-IPA-TEST.socket May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: request received May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: user query start May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: user query end: uid=ab,cn=users,cn=accounts,dc=ipa,dc=test May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: idp query start: cn=github,cn=idp,dc=ipa,dc=test May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: idp query end: github May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: oauth2 start: Get access token May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: Received: [abbra] May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: sent: 0 data: 20 May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: ..sent: 20 data: 20 May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: ab@IPA.TEST: response sent: Access-Accept May 02 18:51:50 dc.ipa.test ipa-otpd[1636149]: Socket closed, shutting down... An access token request followed by the request to obtain a user information. The resource owner's subject then compared with the value set in the LDAP entry for this Kerberos principal with the help of ``--idp-user-id`` option. Subject's field name is chosen through the same option to the IdP reference. If the check is successful, ``ipa-otpd`` sends a RADIUS packet with ``Access-Accept`` response code. Communication performed by ``oidc_child`` is not included into the journal logs by default. If there are issues in accessing IdPs, a special option can be added to ``/etc/ipa/default.conf`` to increase log level of ``oidc_child`` output. By default, it is 0 and could be any number between 0 and 10:: [global] oidc_child_debug_level=10 A value greater than 6 would include debug output from the ``libcurl`` utility:: May 02 18:51:50 dc.ipa.test oidc_child[1636150]: oidc_child started. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Running with effective IDs: [0][0]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Running with real IDs [0][0]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: JSON device code: [{"device_code":"f071833afe966eaf596d83646f55250cfdb57418","expires_in":899,"interval":5}]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Result does not contain the 'user_code' string. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Result does not contain the 'verification_uri' string. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Result does not contain the 'verification_url' string. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Result does not contain the 'verification_uri_complete' string. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Result does not contain the 'message' string. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: device_code: [f071833afe966eaf596d83646f55250cfdb57418]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: expires_in: [899]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: interval: [5]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: POST data: [grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=some-client-id&device_code=f071833afe966eaf596d83646f55250cfdb57418]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Trying 140.82.121.3:443... May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Connected to github.com (140.82.121.3) port 443 (#0) May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * ALPN, offering h2 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * ALPN, offering http/1.1 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * successfully set certificate verify locations: May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * CAfile: /etc/pki/tls/certs/ca-bundle.crt May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * CApath: none May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (OUT), TLS handshake, Client hello (1): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Server hello (2): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Certificate (11): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, CERT verify (15): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Finished (20): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (OUT), TLS handshake, Finished (20): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * ALPN, server accepted to use h2 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Server certificate: May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * subject: C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=github.com May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * start date: Mar 15 00:00:00 2022 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * expire date: Mar 15 23:59:59 2023 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * subjectAltName: host "github.com" matched cert's "github.com" May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS Hybrid ECC SHA384 2020 CA1 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * SSL certificate verify ok. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Using HTTP2, server supports multiplexing May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Connection state changed (HTTP/2 confirmed) May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Using Stream ID: 1 (easy handle 0x562cd1ee96e0) May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: > POST /login/oauth/access_token HTTP/2 Host: github.com user-agent: SSSD oidc_child/0.0 accept: application/json content-length: 139 content-type: application/x-www-form-urlencoded May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * We are completely uploaded and fine May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * old SSL session ID is stale, removing May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < HTTP/2 200 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < server: GitHub.com May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < date: Mon, 02 May 2022 18:51:50 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < content-type: application/json; charset=utf-8 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < vary: X-PJAX, X-PJAX-Container May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < permissions-policy: interest-cohort=() May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < etag: W/"some-e-tag-value" May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < cache-control: max-age=0, private, must-revalidate May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < strict-transport-security: max-age=31536000; includeSubdomains; preload May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-frame-options: deny May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-content-type-options: nosniff May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-xss-protection: 0 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < expect-ct: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors" May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < content-security-policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; child-src github.com/assets-cdn/worker/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.git> May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < vary: Accept-Encoding, Accept, X-Requested-With May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-github-request-id: D1EA:541D:48A585:4BF8E5:62702846 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < May 02 18:51:50 dc.ipa.test oidc_child[1636150]: {"access_token":"some-access-token","token_type":"bearer","scope":"user"} May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Connection #0 to host github.com left intact May 02 18:51:50 dc.ipa.test oidc_child[1636150]: Result does not contain the 'id_token' string. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: access_token: [some-access-token]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: id_token: [(null)]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Trying 140.82.121.6:443... May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Connected to api.github.com (140.82.121.6) port 443 (#0) May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * ALPN, offering h2 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * ALPN, offering http/1.1 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * successfully set certificate verify locations: May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * CAfile: /etc/pki/tls/certs/ca-bundle.crt May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * CApath: none May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (OUT), TLS handshake, Client hello (1): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Server hello (2): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Certificate (11): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, CERT verify (15): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Finished (20): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (OUT), TLS handshake, Finished (20): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * ALPN, server accepted to use h2 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Server certificate: May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * subject: C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=*.github.com May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * start date: Mar 16 00:00:00 2022 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * expire date: Mar 16 23:59:59 2023 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * subjectAltName: host "api.github.com" matched cert's "*.github.com" May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS Hybrid ECC SHA384 2020 CA1 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * SSL certificate verify ok. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Using HTTP2, server supports multiplexing May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Connection state changed (HTTP/2 confirmed) May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Server auth using Bearer with user '' May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Using Stream ID: 1 (easy handle 0x562cd1f92ae0) May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: > GET /user HTTP/2 Host: api.github.com authorization: Bearer some-token-value user-agent: SSSD oidc_child/0.0 accept: application/json May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * old SSL session ID is stale, removing May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < HTTP/2 200 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < server: GitHub.com May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < date: Mon, 02 May 2022 18:51:50 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < content-type: application/json; charset=utf-8 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < content-length: 1357 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < cache-control: private, max-age=60, s-maxage=60 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < vary: Accept, Authorization, Cookie, X-GitHub-OTP May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < etag: "some-e-tag-value" May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < last-modified: Mon, 14 Mar 2022 14:05:20 GMT May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-oauth-scopes: user May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-accepted-oauth-scopes: May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-oauth-client-id: some-client-id May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-github-media-type: github.v3 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-ratelimit-limit: 5000 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-ratelimit-remaining: 4996 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-ratelimit-reset: 1651520567 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-ratelimit-used: 4 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-ratelimit-resource: core May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < access-control-expose-headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scop> May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < access-control-allow-origin: * May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < strict-transport-security: max-age=31536000; includeSubdomains; preload May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-frame-options: deny May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-content-type-options: nosniff May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-xss-protection: 0 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < content-security-policy: default-src 'none' May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < vary: Accept-Encoding, Accept, X-Requested-With May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < x-github-request-id: C5B8:5B48:4C0EB7:4D8AF2:62702846 May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: < May 02 18:51:50 dc.ipa.test oidc_child[1636150]: {"login":"abbra","id":some-id,"node_id":"some-node","avatar_url":"some-avatar-url","gravatar_id":"","url":"some-user-url","html_ur May 02 18:51:50 dc.ipa.test oidc_child[1636150]: l":"some-url","followers_url":"some-api-url","following_url":"some-following-url","gists_url":"some-gists-url> May 02 18:51:50 dc.ipa.test oidc_child[1636150]: libcurl: * Connection #0 to host api.github.com left intact May 02 18:51:50 dc.ipa.test oidc_child[1636150]: userinfo: [{"login": "abbra", "id": some-id, "node_id": "some-node", "avatar_url": "some-avatar-rul", "gravatar_id": "", "url": "some-user-url", "> May 02 18:51:50 dc.ipa.test oidc_child[1636150]: User identifier: [abbra]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: User identifier: [abbra]. May 02 18:51:50 dc.ipa.test oidc_child[1636150]: oidc_child finished successful! Don't forget to remove ``oidc_child_debug_level`` from the ``/etc/ipa/default.conf`` once troubleshooting is done. Information like above often contains personal details of the user and should probably not stored in the system journal.