# Vault as an OAuth/OIDC Identity Provider

**URL:** <https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964>\
**Category:** Vault\
**Created:** [July 25, 2020, 2:27am UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964 "2020-07-25T02:27:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![coryjamesfisher](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/coryjamesfisher/32/8709_2.png) [@coryjamesfisher](https://discuss.hashicorp.com/u/coryjamesfisher)\
**Post date:** [July 25, 2020, 2:27am UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/1 "2020-07-25T02:27:12Z")

</div>

Good Evening. Can vault can be used as an OAuth identity provider. It appears that it can by the documentation, however it is a little vague, so I just wanted to be sure. My idea is to integrate it with spring security’s oauth implementation so I can have users authenticate via vault and use it just like any other oauth provider (ex: google/github/etc).

The specific documentation pages I’m referring to are located here:

> **[Identity - Secrets Engines | Vault by HashiCorp](https://www.vaultproject.io/docs/secrets/identity#token-generation)**
>
> The Identity secrets engine for Vault manages client identities.

  

> **[Identity Secret Backend: Identity Tokens - HTTP API | Vault by HashiCorp](https://www.vaultproject.io/api/secret/identity/tokens#generate-a-signed-id-token)**
>
> This is the API documentation for configuring, acquiring, and validating vault issued identity tokens.

Thanks for all your great work. I love Hashicorp’s products.

---

<div class="post-metadata">

**Author:** ![candlerb](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/candlerb/32/16984_2.png) [@candlerb](https://discuss.hashicorp.com/u/candlerb)\
**Post date:** [February 21, 2021, 11:44am UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/2 "2021-02-21T11:44:44Z")

</div>

I couldn’t find any page saying that Vault can act as an OAuth or OpenIDC provider.

However, Vault _can_ issue OIDC identity tokens:

> **[Identity Secret Backend: Identity Tokens - HTTP API | Vault by HashiCorp](https://www.vaultproject.io/api-docs/secret/identity/tokens)**
>
> This is the API documentation for configuring, acquiring, and validating vault issued identity tokens.

Unfortunately, I don’t think this by itself is sufficient to turn Vault into an OpenID Connect provider (in the style of Dex IDP or Keycloak), although it could be a building block.

Firstly, the OIDC provider needs to act as an endpoint for the OIDC protocol exchange, rather than the Vault REST API.

Secondly, the user has to authenticate themselves to Vault, and then use their Vault token to issue an OIDC token. In the simplest case, an OIDC frontend could display a webpage asking for username and password, and use the [userpass](https://www.vaultproject.io/docs/auth/userpass) secrets engine to get a vault token for that user. Making this properly secure would require some form of 2FA.

Thirdly, the OIDC provider needs to store a client\_id and client\_secret for each OIDC client (although I note that `identity/oidc/role` already includes a `client_id`. Maybe the role name is really the client\_id, and the client\_id is really the client\_secret? Except that `allowed_client_ids` in the [key](https://www.vaultproject.io/api-docs/secret/identity/tokens#create-a-named-key) contradicts that)

And fourthly, the OIDC provider must include additional claims in the JWT, limited to the scopes which the client requested, and which the user has explicitly granted permission for. The [endpoint](https://www.vaultproject.io/api/secret/identity/tokens#generate-a-signed-id-token) which issues tokens doesn’t seem to have a way to control claims, although the [role](https://www.vaultproject.io/api-docs/secret/identity/tokens#create-or-update-a-role) includes a “template string to use for generating tokens” (without further explanation).

If I decode the sample token shown in the API response at [jsonwebtoken.io](http://jsonwebtoken.io), I get:

```auto
# Header
{
 "typ": "JWT",
 "alg": "RS256",
 "kid": "2d0b8b9d-f04d-71ec-b674-c7358432bc5b"
}

# Payload
{
 "aud": "P6CfCzyHsQY4pMcA6kWAOCItA7",
 "exp": 1561488412,
 "iat": 1561402012,
 "iss": "https://example.com:1234",
 "sub": "6c65eaf7-d4f4-1333-02bc-1c75219c3102"
}

```

As far as I can see, this is the most important missing piece: the ability to map entity metadata to JWT claims, and to control which claims are included on a token-by-token basis. (This includes mapping Vault groups to JWT group claims).

If that existed, so that Vault could become a general OIDC provider, that would indeed be awesome!

---

<div class="post-metadata">

**Author:** ![candlerb](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/candlerb/32/16984_2.png) [@candlerb](https://discuss.hashicorp.com/u/candlerb)\
**Post date:** [February 21, 2021, 12:39pm UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/3 "2021-02-21T12:39:16Z")

</div>

The ID token templating is documented [here](https://www.vaultproject.io/docs/secrets/identity#token-contents-and-templates) and I found the source [here](https://github.com/hashicorp/vault/tree/master/sdk/helper/identitytpl). According to the test cases, you should be able to map entity metadata, and add claims such as

```auto
"groups": {{identity.entity.groups.names}}

```

or

```auto
"groups": {{identity.entity.groups.ids}}

```

I’ve tested this:

```auto
vault write identity/oidc/key/oidckey - <<'EOH'
{
  "allowed_client_ids": "*"
}
EOH

vault write identity/oidc/role/openid_profile - <<"EOH"
{
  "key": "oidckey",
  "template": "{\"foo\":\"bar\",\"groups\":{{identity.entity.groups.names}}}"
}
EOH

# Policy to allow issuing tokens
vault policy write oidc_token - <<"EOH"
path "identity/oidc/token/*" {
  capabilities = ["read"]
}
EOH

vault auth enable userpass
vault write auth/userpass/users/example password=tcpip123 policies=oidc_token
# note the entity id and add to two new groups:
vault write identity/group name="engineers" member_entity_ids=c930e32a-493e-90e4-226a-d8ef8506e2e8
vault write identity/group name="staff" member_entity_ids=c930e32a-493e-90e4-226a-d8ef8506e2e8

# Login as this user and issue token
vault login -method=userpass username=example password=tcpip123
vault read identity/oidc/token/openid_profile

```

Resulting token decodes as:

```auto
{
 "aud": "2PuGzZuAbgqcaME5FMmxAp4dR8",
 "exp": 1613997204,
 "foo": "bar",
 "groups": [
  "engineers",
  "staff"
 ],
 "iat": 1613910804,
 "iss": "http://10.12.255.56:8200/v1/identity/oidc",
 "namespace": "root",
 "sub": "c930e32a-493e-90e4-226a-d8ef8506e2e8"
}

```

This is very impressive. I think it would require only a thin layer on top of this to act as OpenIDC provider.

As far as I can see, it does mean that you need to define a separate [role](https://www.vaultproject.io/api-docs/secret/identity/tokens#create-or-update-a-role) for every unique combination of oidc [scopes](https://openid.net/specs/openid-connect-basic-1_0.html#Scopes) that you’re prepared to accept - but if you have only a few combinations, like `openid` and `openid profile`, then you’re fine. I also haven’t looked into how refresh tokens might work, but I presume they’d take the form of Vault tokens.

---

<div class="post-metadata">

**Author:** ![stuart-c](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/stuart-c/32/10789_2.png) [@stuart-c](https://discuss.hashicorp.com/u/stuart-c)\
**Post date:** [February 21, 2021, 1:39pm UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/4 "2021-02-21T13:39:08Z")

</div>

Making Vault a full OIDC provider sounds out of scope for what it really is - a secrets management solution, rather than an identity/user management system. However that doesn’t stop you using Vault as part of such a solution, with something like LDAP to handle the user administration and Vault for the tokens.

---

<div class="post-metadata">

**Author:** ![candlerb](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/candlerb/32/16984_2.png) [@candlerb](https://discuss.hashicorp.com/u/candlerb)\
**Post date:** [March 23, 2021, 9:25am UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/5 "2021-03-23T09:25:34Z")

</div>

BTW, I had a go at making a stateless OIDC provider frontend to Vault - I even got as far as doing the full password grant flow.

There is, however, a fundamental problem when it comes to code grant. The relying party may include a nonce in the [authentication request](https://openid.net/specs/openid-connect-core-1_0-17.html#AuthRequest), and if they do, the generated JWT must also contain that nonce. But Vault’s [token identity endpoint](https://www.vaultproject.io/api-docs/secret/identity/tokens#generate-a-signed-id-token) doesn’t provide a way to insert a nonce. If you insert it yourself, of course you invalidate the JWT signature.

It’s also rather inconvenient that every [token signing role](https://www.vaultproject.io/api-docs/secret/identity/tokens#create-or-update-a-role) in Vault contains a fixed client ID. This means that you have to create a separate role for each openID client. Worse, if you want to support different sets of scopes (e.g. “openid”, “openid email”, “openid email profile”) then you need separate roles for those, with different templates, multiplied by the number of clients.

In the end, I think a more practical approach is to use Vault as a backend for a separate OpenID provider which does its own token signing. I’ve done this for Dex: the patch is [here](https://github.com/dexidp/dex/pull/2039). It supports Vault for both OpenID and userpass authentication.

Unfortunately, Dex doesn’t yet have any concept of custom claims other than groups, so if you want to map Vault metadata into claims, they have to appear as groups. (Dex may in future gain custom claims as part of the work on middleware).

---

<div class="post-metadata">

**Author:** ![candlerb](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/candlerb/32/16984_2.png) [@candlerb](https://discuss.hashicorp.com/u/candlerb)\
**Post date:** [November 18, 2021, 1:54pm UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/6 "2021-11-18T13:54:36Z")

</div>

FYI, Vault 1.9.0 includes:

- **OIDC Provider (Tech Preview)** : Vault can now act as an OIDC provider. Applications that support OIDC can now delegate authentication and authorization to Vault using OIDC.

Documentation [here](https://www.vaultproject.io/docs/concepts/oidc-provider), [here](https://www.vaultproject.io/docs/secrets/identity/oidc-provider) and [here](https://www.vaultproject.io/api-docs/secret/identity/oidc-provider).

I am looking forward to trying this out!

EDIT: I have tried it - it works fine with Apache mod\_auth\_openidc as the relying party. I found a [minor issue](https://github.com/hashicorp/vault/issues/13204) with OIDC spec compatibility which will be fixed in v1.9.1. I had [some thoughts](https://github.com/hashicorp/vault/issues/13224) about the way access is limited to client\_ids.

But from what I’ve seen, you get an out-of-the-box authorization code flow for OpenIDC, meaning you can have a single source of truth for web logins, SSH certificates, X509 certificates etc. Very nice indeed!

---

<div class="post-metadata">

**Author:** ![Wolfsrudel](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/wolfsrudel/32/28465_2.png) [@Wolfsrudel](https://discuss.hashicorp.com/u/Wolfsrudel)\
**Post date:** [November 18, 2021, 8:04pm UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/7 "2021-11-18T20:04:53Z")

</div>

And don’t forget the learn platform:

> **[What's New in Vault 1.9 | Vault - HashiCorp Learn](https://learn.hashicorp.com/tutorials/vault/what-is-new?in=vault%2Fnew-release)**
>
> A quick overview of what is new in Vault 1.9 release.

---

<div class="post-metadata">

**Author:** ![candlerb](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/candlerb/32/16984_2.png) [@candlerb](https://discuss.hashicorp.com/u/candlerb)\
**Post date:** [December 13, 2021, 2:22pm UTC](https://discuss.hashicorp.com/t/vault-as-an-oauth-oidc-identity-provider/11964/8 "2021-12-13T14:22:08Z")

</div>

I’ve made a writeup here:

> **[Using Vault as an OpenID Connect Identity Provider](https://brian-candler.medium.com/using-vault-as-an-openid-connect-identity-provider-ee0aaef2bba2)**
>
> In a previous article I wrote about using Hashicorp Vault as an SSH certificate authority. As of version 1.9, Vault has gained the ability…
