Uploaded image for project: 'James Server'
  1. James Server
  2. JAMES-3680

OIDC setup for JMAP, IMAP, SMTP

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • 3.8.0
    • IMAPServer, JMAP, SMTPServer
    • None

    Description

      Email on the mailing list: https://www.mail-archive.com/server-dev@james.apache.org/msg71313.html

      TLDR: am deeply convinced this efforts [OIDC implementation] would help James admins more control over exposed authentication mechanisms and ultimately offer state of the
      art authentication options. This should help James check a few more
      boxes in security reviews and eventually ease adoption!

      -----------------------------------------

      Hello Jamers!

      As part of my work at Linagora, we are looking toward

      • better integrating James within our product suite and for us this
        means support "Single Sign On" and "Single Log Out" for JMAP following
        the OpenId connect standard [0].
      • Improving security standards used to opperate James. (We have a
        growing activity within the health care market, sensible to security
        arguments)

      Regarding security standards we should ideally:

      • Be able to NOT advertise AUTH / LOGIN capabilities of unencrypted
        channels (Correspond to IMAP plainAuthDissallowed but generalized to
        other protocols)
      • Be able to require OAUTH/OIDC authentication for all protocols (IMAP,
        SMTP, JMAP) - this is what some of the health care providers we spoke to
        desired to do.
      • For our collaborative suite usage, while OIDC only for JMAP makes
        sense, we still wish to maintain PLAIN AUTH for IMAP and SMTP.
      • Of course settings for regular users not interested in OIDC should
        not change (no breaking changes, OIDC adoption is opt-in only).

      As such we propose ourselves to:

      • Contribute IMAP and SMTP SASL OAUTH extension described in [RFC-7628]
      • Modularize JMAP authentication mechanisms (letting the admin choose
        which one she wishes to use)
      • Enable authentication through a header mechanism eg `X-USER:
        btell...@apache.org`, which can be used to delegate OIDC authentication
        through a third party API gateway. We have Krackend [1] in mind.
      • Share documentation and a docker-compose of OIDC setup for IMAP, SMTP
        and JMAP in
        https://github.com/apache/james-project/tree/master/examples/oidc. This
        would include:
      • A LDAP still used by James UsersRepository. Provisionned with a
        testing user.
      • A pre-configured Keycloack [2] OpenID connect provider.
      • A pre-configured Krakend API gateway proxying JMAP
      • And finally a James server configured to only accept OIDC as an
        authentication mechanism for IMAP, SMTP and JMAP.
      • Unit tests for existing IMAP `plainAuthDissallowed` configuration
        parameter.

      Finally this is a good opportunity to restructure authentication related
      settings in imapserver.xml and smtpserver.xml file.

      Here are proposals for both files:

      [imapserver.xml]

          <imapserver enabled="true">
              <jmxName>imapserver-ssl</jmxName>
              <bind>0.0.0.0:993</bind>
              <tls socketTLS="true" startTLS="false">
                  <privateKey>file://conf/private.key</privateKey>
                  <certificates>file://conf/certs.self-signed.csr</certificates>
              </tls>
              <!-- ... -->
              <authentication>
                  <plainAuthEnabled>true|false</plainAuthEnabled> <!--
      defaults to true -->
                  <oauth> <!-- ommiting this block would disable oauth. All
      fields are compulsory -->
                      <jwksURL>https://example.com/jwks</jwksURL> 
                      <oidcConfigurationURL>https://example.com/.well-known/openid-config</oidcConfigurationURL>
                      <claim>mailAddress</claim>
                  </oauth>
              </authentication>
          </imapserver>
      

      [smtpserver.xml]

          <smtpserver enabled="true">
              <jmxName>smtpserver-ssl</jmxName>
              <bind>0.0.0.0:465</bind>
              <tls socketTLS="true" startTLS="false">
                  <privateKey>file://conf/private.key</privateKey>
                  <certificates>file://conf/certs.self-signed.csr</certificates>
              </tls>
              <!--- ... -->
              <requireAuthForRelay>true|false</requireAuthForRelay>
              <authentication>
                  <plainAuthEnabled>true|false</plainAuthEnabled> <!--
      defaults to true -->
                  <oauth> <!-- ommiting this block would disable oauth. All
      fields are compulsory -->
                      <jwksURL>https://example.com/jwks</jwksURL> 
                      <oidcConfigurationURL>https://example.com/.well-known/openid-config</oidcConfigurationURL>
                      <claim>mailAddress</claim>
                  </oauth>
              </authentication>
          </smtpserver>
      

      You can see that:

      • The `plainAuthDissallowed` parameter is proposed to be renamed to
        `auth.requireSSL`. (of course we should support fallback NOT to have a
        breaking change)
      • `auth.plainAuthEnabled` enable turning on/off plain auth, which
        allows having OIDC only mechanism.
      • `auth.requireSSL` will be generalized to SMTP.
      • In SMTP `requireAuth` setting is very misleading as it rather is
        `requireAuthForRelay`. I propose we rename this configuration option (of
        course we should support fallback NOT to have a breaking change).

      Here is the implementation strategies we would follow:

      • For JMAP have Krakend doing all the hard job for us, and use a
        dedicated header to carry the information over to James.
      • Our code contributions aims at easing such a setup (that would only
        require configuration)
      • Provide an informative example using krakend. We understand that
        this choice is ours, yet sharing it could allow reuse or similar setup
      • If some people wishes to write an OIDC authentication strategy
        directly in James then they perfectly can! (Reusing the modularization
        of JMAP authentication strategies we would provide).
      • For IMAP and SMTP then we proposes to check the bearer payload
        against a dynamically configured public key (calling the OIDC provider JWKS endpoint) for these protocols. (Sadly
        there is no API gateway for those protocols)
      • Drawbacks includes no revocation of access tokens (once it's signed
        it is always valid), revocation do not shut down existing connections
        authenticated with the revocated token.
      • One alternative would be to systematically ask the OpenID server to
        validate the bearer. This might be acceptable as IMAP and SMTP are long
        lived protocols that do not often establish new connections. While this
        do not change anything regarding already opened connection management,
        this solves revocation at the price of exposing
        more the identity provider...
      • Of course James could expose a back-channel for token invalidation,
        stored in some kind of shared storage, but this complexify things a bit.

      I am deeply convinced this efforts would help James admins more control
      over exposed authentication mechanisms and ultimately offer state of the
      art authentication options. This should help James check a few more
      boxes in security reviews and eventually ease adoption!

      Useful links:

      [0] OpenId spec: https://openid.net/specs/openid-connect-core-1_0.html
      [1] Krakend: https://www.krakend.io/
      [2] Keycloack: https://www.keycloak.org/
      [RFC-7628] SASL OATH mechanism for SMTP and IMAP:
      https://datatracker.ietf.org/doc/html/rfc7628
      Krakend configured with keycloack:
      https://www.krakend.io/docs/authorization/keycloak/
      Krakend configured with token revocation:
      https://www.krakend.io/docs/authorization/revoking-tokens/

      Java library for JWKS: https://github.com/auth0/jwks-rsa-java

      Attachments

        1. OAUTH_SMTP_JAMES_DEMO.mp4
          4.91 MB
          Tung TRAN
        2. OAUTH_IMAP_JAMES.mp4
          20.68 MB
          Tung TRAN

        Activity

          People

            aduprat Antoine Duprat
            btellier Benoit Tellier
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 46h 20m
                46h 20m