Okta Authentication in Vault using OpenID Connect (OIDC)
A long time ago in an internet far far away, the Okta plugin for Vault was the only way to use your Okta credentials to get into Vault. It still works very well, allowing you to associate a Vault policy with an Okta user or group but it has some limitations:
- The Okta auth method does not support all MFA methods, only Okta Push Verify
- It requires Vault have access to an Okta API token
- It doesn’t allow you to assign users to Vault as an Okta chicklet
More recently, the kind folks at HashiCorp released a fantastic new auth plugin that works with JWT/OIDC which means it also works with Okta. This tutorial will show you how authenticate to Vault using Okta with OIDC and be granted a Vault token based on your Okta group.
0. OpenID Connect 101
Before we get into how to make this setup work, it’s important to understand a bit of how OpenID Connect (OIDC) works. If you already grok this stuff, feel free to skip it. OpenID Connect is a simple identity layer on top of OAuth2. The protocol is fairly simple and allows client applications to request signed token asserting identity from authorization servers. The protocol looks like this:
The signed JWT we’re referring to, if you’re unfamiliar with the term, is a JSON Web Token, which is just a format for tokenizing and signing JSON data. It has a header, a payload and a signature. The payload is just a JSON object that includes some structured information, in this case, about identity. The signature is an HMAC value that verifies the integrity of the payload and headers. All this is just base64 encoded and added together with a .
You can play around with these things at jwt.io and a sample would look something like this:
Back to our particular use case of hooking up Vault and Okta with OIDC, you can think of Vault as the Client application and Okta as the Authorization Server.
1. Users and Groups
To do the remainder of the tutorial, you’ll need to be an Okta admin. We’ll assume that you already have a bunch of users you want to authenticate to Vault. Those users are going to need to authorize into Vault using a token policy and a role, but more on that later. For now, it’s a good idea to create some Okta groups that map to Vault roles by naming them something easy to understand. For this example, we’ll use vault_
and we’ll create one group called vault_admins
in Okta and add at least one user to it.
2. Okta Authorization Server
First, we’ll need to create (or modify) an authorization server that will suite our purposes. You can use the default authorization server or create your own, I’d recommend the latter, so that’s what we’ll do here. First go to Security > API
in Okta and you should land on a page where you’ll see Authorization Servers
. Go ahead and click Add Authorization Server
and you should get a pop up with a Name, Audience and Description field. Call the Name Vault
, the Audience api://vault
, and the Description something clever and cheeky.
You’ll be directed to the detailed page describing your new shiny authorization server. Take note of the Issuer
and Audience
fields as we’ll need them later.
Now we need a rule to allow interaction with our application, so lets go to the Access Policies
tab and click Add New Access Policy
assign it to “All Clients” and then once that’s created, click Add Rule
. You should get a popup, that looks like this. Go ahead and copy the following configuration, specifically the Scopes and Grant Type fields.
If you look back to our JWT sample in the first section, you’ll notice there’s a list of groups
. That’s called the groups “claim” and it’s not default in the response, but we can add it under the Claims
tab. Click Add Claim
and you should get a popup that looks like this. Go ahead and copy the following configuration:
That’s all for the authorization server :)
3. Vault Okta Application
Now we need to configure a new Okta application for Vault to use. This is going to be the popup that’s presented by Vault so the user can authenticate using their Okta credentials.
Go to the Applications
page in Okta and click Add Application > Create New App
. You’ll need to select Web
for Platform and OpenID Connect
as the Sign on method. You should be directed to a page that looks like this:
The important bit of configuration here is the Login Redirect URIs
. This URI is where Okta’s authorization server needs to redirect, along with the JWT, once the authentication is complete. You’ll also need to whitelist this value later on when we configure Vault.
On the next page, you’ll get the detailed view of this application. Take note of the Client ID and Client Secret on the bottom of this page as we’ll need those later. Next we’ll go to the Sign On
tab and add the groups claim filter here as well as the Authorization Server. Scroll down to the OpenID Connect ID Token
section and update the Groups claim filter
to have Claim name of groups
with a filter of vault_
just like before. While here, take note of that Audience
value as we’ll need that as well for the Vault configuration.
Next move over to the Assignments
tab and here, we’ll just assign the vault_admins
group to this application. You should already have a few users added into this group from the first step.
After that, move one tab over to Okta API Scopes
. Since this application will need the ability to read our user and group from the Okta API, we’ll need to explicitly allow that. You do that by granting access to the scopes okta.groups.read
and okta.users.read.self
. These are the minimum scopes necessary for this to work.
And now we’re done configuring Okta! You can now go back to the Authorization Server you created and see what a generated token will look like from Vault’s point of view by going to the Token Preview
tab:
As you can see here, on the left side, I’m supplying the information to Okta that the Vault server would, and on the right, you can see the decoded JWT that Okta would respond with. Take note of the aud
, iss
, email
, and groups
. Each of these will be “bound” in Vault to ensure Vault fully understands which user we’re talking about and what permissions to give.
Configuring Vault using Terraform
The preferred way to configure Vault in a repeatable way is using Terraform. For this I have created the onetwopunch/okta/vault
terraform module for you to use that automates this, so we’ll go through how to use it here. If you’re new to terraform, you’ll first need to download the executable and create a main.tf
file that looks like this:
We’ll assume you already have a role called admin
in Vault already set up either via Terraform or something else. Then we’re going the fill in the values with what we’ve setup in the previous steps. By default, this module mounts this plugin at okta_oidc
which is why our Redirect URI in Okta for the Vault application looks like this:
$VAULT_ADDR/ui/vault/auth/okta_oidc/oidc/callback
Other than that, you’ll need to grab the Issuer URI from the Authorization Server config as well as that first api://vault
audience we created in Step 2. You’ll also need to plug in the Client ID and Client Secret from Step 3.
Once all this is done, you only need to point this at your Vault server by exporting the corresponding environment variables and run the apply:
export VAULT_ADDR=https://<vault-domain>:8200
terraform apply
Now you should be able to go back to your Vault cluster user interface and log in as an admin with your Okta credentials. If you have MFA setup on Okta, you should be prompted for that as well!
Logging in with the CLI
Logging in locally with the CLI is a bit different since it needs to spin up a process locally to respond to the callback. What this means is you’ll have to whitelist this URL in your Okta Application or else you’ll get a 400 error that has something to do with the redirect_uri
. This is handled by default in the Terraform module, but you’ll have to add the following URI to your list of Redirect URIs as you did in Step 3:
http://localhost:8250/oidc/callback
Now you can go back to the command line, you just need to login with the following:
vault login -method=oidc -path=okta_oidc role=okta_admin
This should start the local process (by default on 8250, but you can override with port=xxx
) and then open up your default browser so you can login with Okta.
Next steps:
I hope this was helpful!
- Have a deeper look at
onetwopunch/okta/vault
- Read: HashiCorp Vault and Terraform on Google Cloud — Security Best Practices