/poc-hashicorp-vault

This is a proof of concept (POC) using Hashicorp Vault (https://www.vaultproject.io)

Primary LanguageJavaApache License 2.0Apache-2.0

Overview

This is a proof of concept (POC) using Hashicorp Vault

What is Hashicorp Vault?

Vault is a tool for securely accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more. Vault provides a unified interface to any secret, while providing tight access control and recording a detailed audit log.

A modern system requires access to a multitude of secrets: database credentials, API keys for external services, credentials for service-oriented architecture communication, etc. Understanding who is accessing what secrets is already very difficult and platform-specific. Adding on key rolling, secure storage, and detailed audit logs is almost impossible without a custom solution. This is where Vault steps in.

The key features of Vault are:

The Challenge

Secrets for applications and systems need to be centralized and static IP-based solutions don't scale in dynamic environments with frequently changing applications and machines

The Solution

Vault centrally manages and enforces access to secrets and systems based on trusted sources of application and user identity

The Challenge

All application data should be encrypted, but deploying a cryptography and key management infrastructure is expensive, hard to develop against, and not cloud or multi-datacenter friendly

The Solution

Vault provides encryption as a service with centralized key management to simplify encrypting data in transit and at rest across clouds and data centers

The Challenge

With the proliferation of different clouds, services, and systems all with their own identity providers, organizations need a way to manage identity sprawl

The Solution

Vault merges identities across providers and uses a unified ACL system to broker access to systems and secrets

1º Add the hashicorp key

sudo curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -

2º Add the hashicorp repository

sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"

3º Update and install vault

sudo apt-get update && sudo apt-get install vault

Testing the installation

To test the installation run the command vault and will appear some options!

$ vault 

Usage: vault <command> [args]

Common commands:
    read        Read data and retrieves secrets
    write       Write data, configuration, and secrets
    delete      Delete secrets and configuration
    list        List data or secrets
    login       Authenticate locally
    agent       Start a Vault agent
    server      Start a Vault server
    status      Print seal and HA status
    unwrap      Unwrap a wrapped secret

Other commands:
    audit          Interact with audit devices
    auth           Interact with auth methods
    debug          Runs the debug command
    kv             Interact with Vault's Key-Value storage
    lease          Interact with leases
    monitor        Stream log messages from a Vault server
    namespace      Interact with namespaces
    operator       Perform operator-specific tasks
    path-help      Retrieve API help for paths
    plugin         Interact with Vault plugins and catalog
    policy         Interact with policies
    print          Prints runtime configurations
    secrets        Interact with secrets engines
    ssh            Initiate an SSH session
    token          Interact with tokens

Command Completion

Use the vault command to install command-line completions like this.

vault -autocomplete-install

Once you have installed the completions, you should restart your terminal session or reload the shell script to begin using them.

source ~/.bashrc

Starting the Server

First, start a Vault dev server. The dev server is a built-in, pre-configured server that is not very secure but useful for playing with Vault locally.

vault server -dev

Now that we start the dev server, launch a new terminal session.

export VAULT_ADDR='http://127.0.0.1:8200'

Save the unseal key somewhere. Don't worry about how to save this securely. For now, just save it anywhere.

export VAULT_TOKEN="<YOUR ROOT TOKEN HERE>"

Now we need to verify the Server is Running

$ vault status

Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.5.0
Cluster Name    vault-cluster-4d862b44
Cluster ID      92143a5a-0566-be89-f229-5a9f9c47fb1a
HA Enabled      false

Warning

Do not run dev server in production!

Let's start by writing a secret. This is done very simply with the vault kv command, as shown below:

$ vault kv put secret/hello foo=world

Key              Value
---              -----
created_time     2019-02-04T19:53:22.730733Z
deletion_time    n/a
destroyed        false
version          1

This writes the pair foo=world to the path secret/hello!

You can even write multiple pieces of data, as shown below:

$ vault kv put secret/hello foo=world excited=yes

Key              Value
---              -----
created_time     2019-02-04T19:54:03.250328Z
deletion_time    n/a
destroyed        false
version          2

Warning

The examples in this guide use the <key>=<value> input to send secrets to Vault. However, sending data as a part of the CLI command often end up in the shell script history unencrypted. To avoid this, refer to the documentation or [Static Secrets: Key/Value Secrets Engine guide](https://learn.hashicorp.com/tutorials/vault/static-secrets#q-how-do-i-enter-my-secrets-without-exposing-the-secret-in-my-shell script-s-history) to learn different approaches.

As you might expect, secrets can be retrieved with vault kv get:

$ vault kv get secret/hello

====== Metadata ======
Key              Value
---              -----
created_time     2019-02-04T19:54:03.250328Z
deletion_time    n/a
destroyed        false
version          2

===== Data =====
Key        Value
---        -----
excited    yes
foo        world

Vault gets the data from storage and decrypts it. The output format is purposefully whitespace separated to make it easy to pipe into a tool like awk.

Now that you've learned how to read and write a secret, let's go ahead and delete it. You can do so using the vault kv delete command.

$ vault kv delete secret/hello

Success! Data deleted (if it existed) at: secret/hello

Token authentication is automatically enabled. When you started the dev server, the output displayed a root token. The Vault CLI read the root token from the $VAULT_TOKEN environment variable. This root token can perform any operation within Vault because it is assigned the root policy. One capability is to create new tokens.

$ vault token create

Key                  Value
---                  -----
token                s.iyNUhq8Ov4hIAx6snw5mB2nL
token_accessor       maMfHsZfwLB6fi18Zenj3qh6
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

The token is created and displayed here as s.iyNUhq8Ov4hIAx6snw5mB2nL. Each token that Vault creates is unique.

When a token is no longer needed it can be revoked.

Revoke the first token you created.

$ vault token revoke s.iyNUhq8Ov4hIAx6snw5mB2nL

Success! Revoked token (if it existed)

Attempt to login with the last token you created.

$ vault login s.iyNUhq8Ov4hIAx6snw5mB2nL

Error authenticating: error looking up token: Error making API request.

URL: GET http://127.0.0.1:8200/v1/auth/token/lookup-self
Code: 403. Errors:

* permission denied

Login with the root token.

$ vault login $VAULT_TOKEN

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                s.yFgycysoWKJTi9Dw4WcscWiO
token_accessor       qOWOm47ZHomnpr5klg4vGEEP
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

Policies in Vault control what a user can access. For authentication Vault has multiple options or methods that can be enabled and used. Vault always uses the same format for both authorization and policies. All auth methods map identities back to the core policies that are configured with Vault.

There are some built-in policies that cannot be removed. For example, the root and default policies are required policies and cannot be deleted. The default policy provides a common set of permissions and is included on all tokens by default. The root policy gives a token super admin permissions, similar to a root user on a linux machine.

$ vault policy list

default
root

Policies are authored in HCL, but are JSON compatible. Here is an example policy:

# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}

Let's create the my-policy.hcl file, as shown below:

# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}

Now that the file is create, write the policy:

$ vault policy write my-policy my-policy.hcl

Success! Uploaded policy: my-policy

To see the list of policies, execute the following command.

$ vault policy list

default
root
my-policy

To view the contents of a policy, execute the vault policy read command.

$ vault policy read my-policy

# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}

First, check to verify that KV v2 secrets engine has not been enabled at secret/.

$ vault secrets list

Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_b81986c7    per-token private secret storage
identity/     identity     identity_33dc5c7d     identity store
sys/          system       system_ad432442       system endpoints used for control, policy and debugging

If secret/ is not listed, enable it before proceeding.

vault secrets enable -path=secret/ kv-v2

To use the policy, create a token and assign it to that policy.

$ vault token create -policy=my-policy

Key                  Value
---                  -----
token                s.C0FxR0eDCf1mkb0NzzRuWDO7
token_accessor       0B68xBxuxwSMTp1UbxxJEWjf
token_duration       768h
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

Copy the generated token value and authenticate with Vault.

$ vault login s.C0FxR0eDCf1mkb0NzzRuWDO7

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                s.C0FxR0eDCf1mkb0NzzRuWDO7
token_accessor       0B68xBxuxwSMTp1UbxxJEWjf
token_duration       767h59m30s
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

Verify that you can write any data to secret/data/.

$ vault kv put secret/creds password="my-long-password"

Key              Value
---              -----
created_time     2020-08-31T11:46:45.186427422Z
deletion_time    n/a
destroyed        false
version          1

Since my-policy only permits read from the secret/data/foo path, any attempt to write fails with "permission denied" error.

$ vault kv put secret/foo robot=beepboop

Error writing data to secret/data/foo: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/secret/data/foo
Code: 403. Errors:

* permission denied

Be Happy