Skip to content

A Vault plugin to automatically authenticate with all roles matching a JWT (or OIDC) token

License

Notifications You must be signed in to change notification settings

statnett/vault-plugin-auth-jwt-auto-roles

Repository files navigation

vault-plugin-auth-jwt-auto-roles

A Vault plugin to automatically authenticate with all roles matching a JWT (or OIDC) token, and grant access to the union of matching roles' policies.

Problem: The builtin jwt auth plugin requires a role-name to be specified during authentication. When authenticated, access is only granted based on the policies of that single role. Even though the JWT satisfies multiple roles' bound claims. Thus, multiple logins with different role names are required when policies are split across multiple roles, resulting in multiple tokens which cannot be used interchangeably.

Solution: The jwt-auto-roles plugin automatically determines which roles' bound claims a JWT matches. It grants access to the union of all the matching roles' policies. Thus a single login is sufficient to get a token with combined access, with the JWT as the sole login parameter.

Working Details

The plugin currently relies on the builtin jwt plugin for JWT verification and policy configuration. It simply determines the roles matching an incoming JWT's claims, tries to login to a mount of the builtin jwt plugin for each role, and grants access to the union of policies returned by the builtin jwt plugin mount.

Usage

Download and unzip a release of the plugin and place it in the plugin directory.

Register the plugin:

vault plugin register -sha256=<binary sha> auth vault-plugin-auth-jwt-auto-roles

Enable the plugin at a specific mount path (e.g. jwt-auto-roles):

vault auth enable -path=jwt-auto-roles vault-plugin-auth-jwt-auto-roles

For the plugin to be able to determine matching roles, it must be configured with the host name and mount point of a builtin jwt plugin mount, along with all its roles and their bound claims:

vault write auth/jwt-auto-roles/config @config.json

// config.json
{
  "jwt_auth_host": "https://vault.org.com",
  "jwt_auth_path": "jwt",
  "user_claim": "user_email", // optional, generated based on policies and namespace otherwise
  "roles": {
    "role-a": {
      "project_path": ["foo/bar"]
    },
    "role-b": {
      "branch": ["main", "master"]
    }
  }
}

Then login as with the builtin jwt auth, although without the role parameter:

vault write auth/jwt-auto-roles/login jwt=$jwt

Future work

The plugin could be configured with policies directly, instead of role names, and not rely on the builtin jwt plugin for token verification. Although simpler to configure, security guarantees will no longer be delegated to HashiCorp.

There is a also an upstream issue to get this implemented in the official jwt plugin, obsoleting this plugin.