How to set up your Hashicorp Vault with Google authentication?

Hashicorp Vault is a tool that allows you secure, store, and control access to different types of secrets, like credentials, certificates, tokens, etc. It could be used to share secrets within teams as well as be incorporated into CI/CD pipelines.

Installing Hashicorp Vault

The first step is to add official HashiCorp repo to apt sources:

apt-get update
apt-get install gpg wget
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null;
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint;
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list;

Now we can install Vault itself:

apt-get update
apt-get install vault

Configure Vault for the first startup

Once Vault is installed go to /etc/vault.d/ directory and edit the vault.hcl file. Replace it with the example below. As a part of general practice, we set Vault to listen to the internal IP address and will expose it to the outside world using Nginx later.

ui = truedisable_mlock = truestorage "file" {
path = "/opt/vault/data"
}api_addr = "http://{ PRIVATE_SERVER_IP }:8200"listener "tcp" {
address = "{ PRIVATE_SERVER_IP }:8200"
tls_disable = "false"
}

Once it’s done, run the command below to check that the config is fine.

vault server -config=/etc/vault.d/vault.hcl

If everything is fine, execute the next command to run Vault as a service and check its status. Please note that these commands might vary depending on Linux distribution you use and what process management software is installed.

systemctl start vault
systemctl status vault

After this, you MUST init Vault server with the command below. This command will respond with seal keys and an initial root token. Ensure you keep them in a safe and secure place. These credentials would require to access Vault in order to configure OIDC authentication and further setup.

vault operator init

Configure Nginx proxy

As it was mentioned before we use Nginx as a proxy before Vault server. Let’s install it first:

apt-get update
apt-get install nginx

And configure it using the template below. You can use cert-manager to generate valid SSL certificates.

upstream vaultui{
server { PRIVATE_SERVER_IP }:8200;
}server {
listen 80;server_name { VAULT_URL };location ~ "^/\.well-known/acme-challenge/(.*)$" {
default_type text/plain;
return 200 "$1.{SSL ACME challenge response}";
}
return 301 https://$host$request_uri;
}server {
listen 443 ssl http2;
server_name { VAULT_URL };ssl_certificate /etc/letsencrypt/live/{vault url}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{vault url}/privkey.pem;location / {
proxy_pass http://vaultui;
}location @fallback {
proxy_pass http://vaultui;
}
}

Configure OIDC (Google)

Next step is to enable login methods. The main login method will be “Login with Google“. We will need to create a default role, default policy and configure OIDC auth.

The first is policy. It set the minimum required permissions for users.

# Allow tokens to look up their own properties
path "auth/token/lookup-self" {
capabilities = ["read"]
}# Allow tokens to renew themselves
path "auth/token/renew-self" {
capabilities = ["update"]
}# Allow tokens to revoke themselves
path "auth/token/revoke-self" {
capabilities = ["update"]
}# Allow a token to look up its own capabilities on a path
path "sys/capabilities-self" {
capabilities = ["update"]
}# Allow a token to look up its own entity by id or name
path "identity/entity/id/{{identity.entity.id}}" {
capabilities = ["read"]
}
path "identity/entity/name/{{identity.entity.name}}" {
capabilities = ["read"]
}# Allow a token to look up its resultant ACL from all policies. This is useful
# for UIs. It is an internal path because the format may change at any time
# based on how the internal ACL features and capabilities change.
path "sys/internal/ui/resultant-acl" {
capabilities = ["read"]
}# Allow a token to renew a lease via lease_id in the request body; old path for
# old clients, new path for newer
path "sys/renew" {
capabilities = ["update"]
}
path "sys/leases/renew" {
capabilities = ["update"]
}# Allow looking up lease properties. This requires knowing the lease ID ahead
# of time and does not divulge any sensitive information.
path "sys/leases/lookup" {
capabilities = ["update"]
}# Allow a token to manage its own cubbyhole
path "cubbyhole/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}# Allow a token to wrap arbitrary values in a response-wrapping token
path "sys/wrapping/wrap" {
capabilities = ["update"]
}# Allow a token to look up the creation time and TTL of a given
# response-wrapping token
path "sys/wrapping/lookup" {
capabilities = ["update"]
}# Allow a token to unwrap a response-wrapping token. This is a convenience to
# avoid client token swapping since this is also part of the response wrapping
# policy.
path "sys/wrapping/unwrap" {
capabilities = ["update"]
}# Allow general purpose tools
path "sys/tools/hash" {
capabilities = ["update"]
}
path "sys/tools/hash/*" {
capabilities = ["update"]
}# Allow checking the status of a Control Group request if the user has the
# accessor
path "sys/control-group/request" {
capabilities = ["update"]
}# Allow a token to make requests to the Authorization Endpoint for OIDC providers.
path "identity/oidc/provider/+/authorize" {
capabilities = ["read", "update"]
}

Next step — create a role. The example below will get user emails and set them as alias in Vault. Also we set additional mappings for claims like name, email and sub as alias metadata to get more info about user.

vault write auth/oidc/role/{role name} \
user_claim="email" \
claim_mappings="name"="name" \
claim_mappings="email"="email" \
claim_mappings="sub"="sub" \
group_claim="groups" \
bound_audiences={OIDC Client ID} \
allowed_redirect_uris={Callback URL} \
policies=default \
oidc_scopes="email,openid,profile" \
max_age=0 \
ttl=1h

Finally — create an OIDC config. We use Google as OIDC provider, please refer to this page to get more information.

vault write auth/oidc/config -<<EOF
{
"oidc_discovery_url": "https://accounts.google.com",
"oidc_client_id": "{OIDC Client ID}",
"oidc_client_secret": "{OIDC Client secret}",
"default_role": "{role name}"
}
EOF

That’s all — your Vault installation is ready to use.