Authenticating internal applications on Kubernetes via Okta, Istio, and OAuth2-Proxy

Anthony Sung
The Storyblocks Tech Blog
4 min readJul 28, 2023

Storyblocks has recently moved to using Okta for our IAM (Identity and Access Management) needs. This enabled us to leverage Okta in our Kubernetes cluster for accessing internal applications.

Employee client connecting to internal application in Kubernetes and being authenticated via Okta
Employee client connecting to internal application in Kubernetes and being authenticated via Okta

General Flow

  1. Employee tries to access an internal application (i.e. admin-service).
  2. The employee connects to the internal application url and the request is sent to the Istio service mesh inside our Kubernetes cluster.
  3. We have an Istio authorization policy that limits access to the admin service.
  4. The authorization policy points uses the custom extension provider, Oauth2-Proxy. Oauth2-Proxy is setup to connect with our identity provider which is Okta.
  5. The employee’s request is redirected to Okta for login. On successful authentication it passes through the Istio authorization policy and connects with the admin service.

Technologies Used

We found a surprisingly small number of tutorials when trying to set this up ourselves so here is our quick tutorial.

1. Create an Okta Application for OAuth2-Proxy

This Okta application will allow for access management to your application.

OAuth2-Proxy application in Okta
Okta application settings

Make sure to add the url to your internal application under the sign-in redirect URI. This will authorize Okta to redirect to your internal app after authenticating an employee.

You can add other internal app urls to this application, but know that any Okta users/groups you add to this Okta application will be able to access every internal application url that is listed here.

If you want to separate who has access to an application (i.e. only the finance team can access this application and not engineering), you will need to create a separate OAuth2-Proxy app in Okta for each application you want to customize access to.

2. Deploy OAuth2-Proxy to Kubernetes

This will be the same process as deploying any other application to Kubernetes; you will just need to add a couple of specific configs. The biggest lesson we learned was that you do NOT need the redirect-url. You will be specifying the redirect URL’s in the Okta application later on. We added clientID, clientSecret, and cookieSecret configs via our secrets management process, but I put it in this yaml excerpt for readability.

Here’s a link to the OAuth2-Proxy and Okta documentation — just ignore the fact that they include the redirect-url in their configuration file.

# Oauth client configuration specifics
oauth2-proxy:
config:
clientID: <SEE OKTA OAUTH2-PROXY APP>
clientSecret: <SEE OKTA OAUTH2-PROXY APP>
cookieSecret: <SEE OKTA OAUTH2-PROXY APP>
extraArgs:
provider: oidc
oidc-issuer-url: "<COMPANY_OKTA_URL>"
pass-access-token: true
skip-provider-button: true
reverse-proxy: true
cookie-domain:
- <WHITELIST_COOKIE_DOMAINS>
email-domain: "*"
whitelist-domain:
- <WHITELIST_DOMAINS>
upstream: static://200
# redirect url - not needed since you will have it in your Okta application

3. Add OAuth2-Proxy as an extension provider in Istio

Inside your Istio mesh config, you will need to add an extension provider. This will reference the OAuth2-Proxy deployment and will allow us to use OAuth2-Proxy as a CUSTOM action in our Istio Authorization Policy.

# Istio extension provider specifics
istiod:
meshConfig:
extensionProviders:
- name: "oauth2-proxy"
envoyExtAuthzHttp:
service: "<KUBERNETES SERVICE URL i.e.oauth2-proxy.default.svc.cluster.local>"
port: "80"
includeHeadersInCheck: ["authorization", "cookie"] # headers sent to the oauth2-proxy in the check request.
headersToUpstreamOnAllow: ["authorization", "path", "x-auth-request-user", "x-auth-request-email", "x-auth-request-access-token"] # headers sent to backend application when request is allowed.
headersToDownstreamOnDeny: ["content-type", "set-cookie"] # headers sent back to the client when request is denied.

4. Add Istio Authorization policy

This CUSTOM authorization policy allows us to restrict access to the host specified and authenticate via Okta and the OAuth2-Proxy. See the Istio reference document for more info.

# Istio authorization policy
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: admin-service-okta-auth-policy
namespace: admin-service
spec:
action: CUSTOM
provider:
name: oauth2-proxy # reference oauth2-proxy extension provider
rules:
- to:
- operation:
hosts:
- <INTERNAL APPLICATION HOST>
selector:
matchLabels:
app.kubernetes.io/instance: <KUBERNETES SERVICE NAME i.e. admin-service>
app.kubernetes.io/name: <KUBERNETES SERVICE NAME i.e. admin-service>

5. Enjoy secure access to your internal application!

Okta login page when trying to access an internal application

If this work sounds interesting, consider joining our team!

--

--