Vault: Connecting entities, auth backends, groups, and policies OH MY

While working on my osquery-file-carve-server project I determined my application needed authentication. However, I didn’t want to pigeon hole my application to a single platform/service for authentication. After some research, I decided to implement support for Vault into my application because it provides the ability for users to authenticate using various methods. However, during my research, I had a hard time understanding how the various Vault components connected to create this functionality.

This blog post will provide an understanding of the Vault components used to implement this functionality. In addition, it will demonstrate the relationship between the various Vault components: authentication backends, entities, groups, and policies. The final result of combining these Vault components is a system that can authenticate a single user using different authentication services.

DISCLAIMER

This blog post is a proof of concept (POC) for a homelab and does NOT implement best practices for an enterprise environment. Please review the Hashicorp Vault documentation for best practices.

DISCLAIMER

Goals

  • Setup Vault to use Auth0 and Github as auth backends
  • Use Auth0 OR Github to generate a Vault token
  • Understand the relationship between auth backends, policies, groups, and entities

Background

Vault components?

  • Policies – Defines what an entity can do – create, read, modify, delete
  • Auth backend – A service that can authenticate users
  • Entities – An entity ties different user accounts from different auth backends to a single entity. For example, my Auth0 username is “bbornholm” but my Github username is “CptOfEvilMinions”. In either case, the account is still ME, just a different platform and/or username. Entities tie of all these different auth services and usernames together as a single object.
  • Groups – A group makes all this magic come together. Not only is a group a collection of entities ( users and auth backends) but an assignment of policies that defines what each entity can perform.

Diagram of relationships

The diagram above shows the relationships between policies, groups, entities, and authentication backends. At first, none of this made sense until I was able to map these relationships. In this blog post, I have three user accounts on three separate authentication backends which are Auth0, Github, and LDAP. All of these accounts are ME but I have three different usernames on three different platforms. An entity provides a layer of abstraction that says this entity can be associated with the following user account on its respective platform.

By default, the default policy on Vault provides common permissions – if a policy does not contain a rule to allow an action, the default action is to DENY. In order to allow a user to perform an action such as reading a secret, a policy must be created explicitly allowing that action.  Next, a group is created which is a collection of entities and policies. The group provides a union of policies and entities, allowing the entities within the group to perform predefined actions within the policies on the Vault platform.

In this blog post scenario, we are going to create an entity with a friendly name of “bbornholm”. The entity “bbornholm” can utilize the following user accounts: the “thunderwagon” account from Auth0, the “CptOfEvilMinions” account from Github, or the “bbornholm2194” account via LDAP to login. Next, we will create a policy named “test-read-only” that contains a set of rules to allow READing and LISTing all secrets from the following path secrets/hello.

By default since the policy does not explicitly allow DELETE, UPDATE, or, CREATE; therefore, these actions are blocked by default. Lastly, the entity “bbornholm” and our policy “test-read-only” will be applied to a group named “test-group”. This step connects policies and entities together to allow entities to perform the actions set by the policies.

Setup/Configure Vault

Step 0: Spin up Vault with Docker

This blog post assumes you have Vault setup, if you do not, take a look at my blog post: Install/Setup Vault for PKI + NGINX + Docker – Becoming your own CA.

  1. git clone https://github.com/CptOfEvilMinions/BlogProjects
  2. cd BlogProjects/vault-entities-groups-auths

Step 1: Create some SUPER DUPER secrets

  1. export VAULT_ADDR=https://<Vault hostname>:<port>
  2. vault login
    1. Login as root
  3. vault secrets enable -path=secrets kv
    1. Enable KV secrets engine
  4. vault kv put secrets/hello target=world
    1. Create a secret
  5. vault kv get secrets/hello
    1. Query secret

Step 2: Create policies

  1. vault policy write <POLICY_NAME> <POLICY_FILE>
    1. Create a read-only policy
  2.  vault policy write <POLICY_NAME> <POLICY_FILE>
    1. Create an admin policy
  3. vault policy list
    1. Lists policies
  4. vault policy read <POLICY_NAME>

Step 2: Setup Github for auth backend

  1. vault auth enable github
  2. vault write auth/github/config organization=<ORG_NAME>
    1. Enable Github auth for the specified Github org

Step 3: Setup FreeIPA(LDAP) for auth backend

  1. vault auth enable ldap
  2. vault write auth/ldap/config \
    url="ldap[s]://ldap.example.com" \
    userdn="cn=users,cn=accounts,dc=example,dc=com" \
    userattr="uid" \
    insecure_tls=<true/false> \
    starttls=<true/false> \
    groupdn="cn=groups,cn=accounts,dc=example,dc=com" \
    groupattr="cn" \
    binddn="uid=<BIND_USERNAME>,cn=sysaccounts,cn=etc,dc=example,dc=com" \
    bindpass="<BIND_PASSWORD>"

Step 3: Create/Setup Auth0 for auth backend

Create Application

  1. Create an Auth0 account if you don’t already have one
  2. Login in to your Auth0 account as an admin
  3. Select “Applications” on the left
    1. Enter a name for the app
    2. Select “Native” for type
    3. Select “Create”
  4. Select the “Settings” tab
  5. Enter the following URLs below into the “Allowed Callback URLs” section
    1. https://<vault_server_address>:8200/ui/vault/auth/oidc/oidc/callback
    2. URLs must be separated by a comma
    3. https://<vault_server_address>:8250/oidc/callback
  6. Copy the domain value
  7. Copy the client ID value
  8. Select “Save changes”

Create a user (optional)

  1. Select “Users & Roles” on the right
  2. Select “Create user +”
    1. Enter e-mail for the user
    2. Enter password
    3. Select “Username-Password-Authentication” for Connection
    4. Select “Create”

Enable Auth0 on Vault

  1. export AUTH0_DOMAIN="<Auth0 domain>"
  2. export AUTH0_CLIENT_ID="<AUTH0_CLIENT_ID>"
  3. export AUTH0_CLIENT_SECRET="<AUTH0_CLIENT_SECRET>"
  4. vault auth enable oidc
  5. vault write auth/oidc/config oidc_discovery_url="https://<AUTH0_DOMAIN>/" oidc_client_id="<AUTH0_CLIENT_ID>" oidc_client_secret="<AUTH0_CLIENT_SECRET>" default_role="reader"
    1. The oidc_discovery_url value needs a trailing “/”
  6. vault write auth/oidc/role/reader bound_audiences="<AUTH0_CLIENT_ID>" allowed_redirect_uris="http://<VAULT_HOSTNAME>:<VAULT_PORT>/ui/vault/auth/oidc/oidc/callback"
    user_claim="sub" policies="reader"

Step 5: Create an entity

  1. vault auth list
    1. Get accessor IDs for each auth backend
    2. Copy Accessor IDs for each auth backend
  2. vault write identity/entity name="<entity username>" policies="<POICY_NAME>" metadata=organization="<ORG_NAME>" metadata=team="<TEAM_NAME>"
    1. Create an entity with metadata contain org name and team name
  3. vault write identity/entity-alias name="<LDAP USERNAME>" canonical_id="<ENTITY_ID>" mount_accessor="<LDAP access ID>"
    1. Add the LDAP user account to the entity as an alias
  4. vault write identity/entity-alias name="<GITHUB_USERNAME>" canonical_id=<ENTITY_ID> mount_accessor=<GITHUB_ACCESSOR_ID>
    1. Add the Github user account to the entity as an alias
  5. vault write identity/entity-alias name="<AUTH0_USERNAME>" canonical_id=<ENTITY_ID> mount_accessor=<AUTH0_ACCESSOR_ID>
    1. Add the Auth0 user account to the entity as an alias
  6. vault read identity/entity/id/<entity_id>
    1. The output should include the entity aliases, metadata (organization, and team), and base policy

Step 6: Create an internal group

It is common for organizations to enable auth methods such as LDAP, Auht0, and perhaps GitHub to handle the Vault user authentication, and individual user’s group memberships are defined within those identity providers. In order to manage the group-level authorization, you can create an external group to link Vault with the external identity provider (auth provider) and attach appropriate policies to the group.

  1. vault write identity/group name="test-group" policies="test-read-only" member_entity_ids=<entity_id> metadata=team="Engineering" metadata=region="North America"

Test access

Use LDAP to access secret

  1. vault login -method=ldap username=<LDAP username>
  2. vault kv get kv/hello

Use Auth0 to access secret

  1. vault login -method=oidc role="reader"
    1. A browser should open and direct you to the Auth0 login portal
  2. vault kv get kv/hello

Use Github to access secret

Generate Github app token

  1. Login into Github as an org admin
  2. In the upper-right corner of any page, click your profile photo, then click Settings
  3. In the left sidebar, click Developer settings
  4. In the left sidebar, click Personal access tokens
  5. Select “Generate new token”
    1. Enter “<app name>”
    2. Check “read:org” permission
    3. Select “Generate token”
  6. Copy token

Login with token

  1. vault login -method=github
    1. Enter GitHub Personal Access Token
  2. vault kv get kv/hello

Lessons learned

I am currently reading a book called “Cracking the Coding Interview” and it is a great book. One interesting part of the book is their matrix to describe projects you worked on and the matrix contains the following sections which are: challenges, mistakes/failures, enjoyed, leadership, conflicts, and what would you do differently. I am going to try and use this model at the end of my blog posts to summarize and reflect on the things I learn. I don’t blog to post things that I know, I blog to learn new things and to share the knowledge of my security research.

New skills/knowledge

  • Improved my understanding of Hashicorp Vault
  • Learned how to create Vault policies
  • Learned how to use Vault to support multiple authentication backends for a single entity
  • Used the following new service Auth0

Challenges

  • Finding documentation to setup auth backends with Vault in a secure manner

What You’d Do Differently

  • This blog post was a proof-of-concept (PoC) for using Vault with various auth backends. However, I wish I had time to research OIDC to implement the authentication backend in a more secure manner.

References

Leave a Reply

Your email address will not be published. Required fields are marked *