Oauth2-proxy

19 September 2023

In this article, Antoine will explain how it can be possible to link any IdP to any app using oauth2-proxy. It will allow you to implement SSO on your apps within kubernetes. Another example of setting up SSO is shown in this article from Oscar. SSO makes the access to your apps more secure and more practical.

SSO: a good way to strengthen the security of webapps

What is an IdP?

An IdP is a service that lets people connect to apps using a central digital identity. It is useful to centrally manage the access to different resources.

Take IdPs as authentication-as-a-service tools, they allow you to connect to several resources without having to re-create accounts on the actual resources you want to connect to.

You have probably already used several IdPs, such as Facebook, Google, or Github when connecting to an app.

An IdP is an essential tool for allowing federated identity on your infrastructure.

To sum up, thanks to IdP, users can use a single authentication method to access several different apps. That method is called SSO (Single Sign On).

How to use IdPs?

An IdP is essentially a service that helps you to centralize your identity, but for it to work, you need to make it communicate with your apps. That is where protocols like SAML, OAUTH2, or OIDC are useful.

These standards are all helpful in plugging an IdP to an app for it :

  • SAML relies on exchanging messages to authenticate in XML SAML format, as opposed to JWT. It is often used to assist enterprise users in signing in to multiple applications with a single login.
  • OAuth2 is a widely adopted authorization framework that enables third-party applications to access user data without requiring the user's credentials. It operates on a series of grants that are issued by the Resource Owner to the Client. These grants typically include an access token that permits the Client to retrieve specific resources in the name of the Resource Owner.
  • OIDC (OpenID Connect) is a simple identity layer on top of the OAuth 2.0 protocol. It is designed to help clients authenticate end-users and obtain user information.
    OIDC allows the client to verify the identity of the end-user based on the authentication performed by an authorization server. It also allows obtaining basic profile information about the end-user in an interoperable and REST-like manner. You can learn about other uses of OIDC in this article about EKS and IAM.

In this article, we will focus on the OIDC standard.

Why is SSO a good way to enhance the security of apps?

SSO (Single Sign On) is a good way to enhance application security, it allows users to use a single authentication method to access multiple different applications. This avoids the need to create multiple accounts for different applications, which can lead to security issues such as using weak passwords or password reuse.

In addition, taking the infrastructure of a big company providing many apps for users, it may be painful or almost impossible to provide every individual an account on every app.

In this kind of situation, it may be common (though really bad in terms of security) to see one using a single account shared with several individuals. In this case, the password may get lost, and everyone's access relies on just getting access to the credentials. This even complicates the onboarding and offboarding process of companies.

Oauth2-proxy to plug any IdP to any app

What is oauth2-proxy?

In fact, until now, the purpose of oauth2-proxy may seem unclear to you. You have been told that we could use OIDC to plug an IdP to your app. So what could be the problem?

The following is the ideal situation :

ideal-situation-idp

Unfortunately, all apps do not support the OIDC or SAML standards to plug an IdP with their RBAC.

For several reasons, some apps could also make this feature costly, or some may not be compatible with it, such as internally developed tools.

Hence, the real situation looks more like this :

actual-situation-idp

In the graph above, you can see that despite using an IdP for my app1, I have to use different credentials to access my App2 and App3.

It is in this kind of situation that oauth2-proxy can be really useful.

useful-oauth2-proxy

Oauth2-proxy acts as an authentication gateway between a user and a service using an IdP.

As you can see in the image above, thanks to oauth2-proxy, we can actually implement SSO behind apps that do not support OIDC.

It is a free option to implement SSO on any app without additional costs.

Features oauth2-proxy can offer

Oauth2-proxy allows you to handle authentication to your webapps and authorization in some use cases.

As a reminder, authentication is the process of verifying a user's identity to let him access or not an app. Authorization, on the other hand, is the process of determining what actions a user is allowed to perform within a system based on their authenticated identity and the permissions assigned to them.

In this article, we won’t dive much into the authorization feature yet, mainly on the authentication process, but you can find more information in the oauth2-proxy documentation.

Oauth2-proxy can handle authentification with a bunch of identity providers natively. In our example, we will use GitHub IdP. If your IdP is not on the list but follows OIDC standard, it will also be compatible with oauth2-proxy.

compatible-idp

How to implement oauth2-proxy?

In this article, we will take the example of apps deployed on a Kubernetes cluster and oauth2-proxy being plugged to a GitHub IdP.

Prerequisites:

  • You will first need, of course, to have your apps plug your IdP in ready and to have a Kubernetes cluster ready with an ingress-controller.
  • You need to be able to create DNS records. You can learn more about DNS and its implementation within AWS by reading this article.
    • Create a record for OAuth2-Proxy: oauth2-proxy.<DNS_ZONE_DOMAIN>
    • Have a record for your apps already deployed.
  • You need to have an exposed app ready to be protected on your cluster.
  • Optionally: I advise you to implement a way to consume cloud secrets so that your OIDC credentials do not appear in clear text in your manifests. You can, for example, install external-secret to your cluster.

How do you configure your IdP?

In this example, I will show you how to configure OIDC with github. Know that the steps may differ with other IdP. The most important is to register your oauth2-proxy app in your IdP.

The first step is to create an Oauth app on your identity provider. The most important after that is to keep in mind your clientID and your clientSecret to reuse them in oauth2-proxy.

How do you configure github IdP?

In Github, the process is as follows :

create-oauthapp

  • Give it a name

  • For the Homepage URL, use the domain you intend to run OAuth2-Proxy on. Use HTTPS.

    Ex : https://oauth2-proxy.<DNS_ZONE_DOMAIN>

  • For the Authorization callback URL, use the callback URL of the domain you intend to run OAuth2-Proxy on. Use HTTPS.

    Ex : https://oauth2-proxy.<DNS_ZONE_DOMAIN>/oauth2/callback

URL-callbakc

How to configure oauth2-proxy?

To deploy oauth2-proxy, you need to provide it with three pieces of information:

  • The client ID and client secret of the IdP. You should get it from your IdP app you created previously.

    client-ID
  • a secret cookie that you need to generate

While it is not mandatory to provide them as secrets for it to work, it is considered a best practice.

Therefore, we advise you to create an external secret to store them. To learn more about secrets in kubernetes, you can follow this blog post.

  • Generate a cookie-secret:

    dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64 | tr -d -- '\n' | tr -- '+/' '-_'; echo

And store the results safely somewhere.

  • If you installed external-secret, follow the steps to add the cookieSecret, clientID and clientSecret to your secretManager and import it with externalSecret.
  • Otherwise (less recommended): you can deploy a secret manually with the name oauth2-secret containing the cookieSecret, clientID and clientSecret.
To deploy oauth2-proxy

Here is the value file we advise you to use with your oauth2-proxy deployment. The lines following the comments “To customize” are unique to each project and should be changed.

ingress:
  enabled: true
  hosts:
		# To customize
    - oauth2-proxy.padok.cloud
  pathType: ImplementationSpecific
  className: whitelist

config: 
  configFile: |-
    redirect_url="/oauth2/callback"
    login_url="https://github.com/login/oauth/authorize"
    redeem_url="https://github.com/login/oauth/access_token"
		# To customize
    whitelist_domains="*.padok.cloud"
		# To customize
    cookie_domains=".padok.cloud"
    scope="user:email"
    provider="github"
    skip_provider_button="true"
    session_store_type="cookie"
    cookie_samesite="lax"
    cookie_secure="false"
    cookie_expire="12h"
    reverse_proxy="true"
    pass_access_token="true"
    pass_authorization_header="true"
    cookie_csrf_per_request="true"
    cookie_csrf_expire="5m"
    cookie_refresh="5m"
    set_xauthrequest="true"
    set_authorization_header="false"
    skip_auth_preflight="true"
		# To customize
    github_org="test-oauth2-proxy"
		# To customize
    email_domains="*"
  existingSecret: oauth2-secret

We can now deploy oauth2-proxy with a Helm chart.

If you want to restrict access to the applications through GitHub IdP, you can use three parameters in oauth2-proxy.yaml:

  • github_org: if you want to restrict access to a GitHub organization
  • github_team: if you want to restrict access to a GitHub team
  • email_domains: if you want to restrict access to emails with the specified domain. It should be "*" to authenticate any email.

Deploy oauth2-proxy:

helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
helm repo update
helm upgrade --install oauth2 oauth2-proxy/oauth2-proxy --values=oauth2-proxy.yaml

Adapt the existing ingress configuration

Now that oauth2-proxy is deployed, you just need to add the following annotations to your ingress configuration to plug it with oauth2-proxy :

nginx.ingress.kubernetes.io/auth-url: "https://oauth2-proxy.padok.cloud/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://oauth2-proxy.padok.cloud/oauth2/start?rd=https://$best_http_host$request_uri"

Note that you will have to change the URL with yours.

Conclusion

To sum it up, we have explored the benefits of using SSO to secure the access to your applications. By implementing oauth2-proxy to plug any IdP to handle authentication, we can improve the security of our applications and safeguard them from unauthorized access and login credential mess.

By following these best practices, we can ensure the security and reliability of our environment.

References and Resources

What is an IdP?

Different protocols for SSO

Oauth2-proxy repo

Oauth2-proxy documentation

A useful debugger for setting up OIDC

An interesting article on OIDC

Thank you for reading this article on SSO and oauth2-proxy. I hope you found this guide helpful and that you feel more confident in setting up SSO using this solution in your projects.