Get a Root Token for HashiCorp Vault
Tags: hashicorpvault, api, vault
Published: 2019-07-19 01:10:26

---
title: Get a Root Token for HashiCorp Vault
published: true
description: How to get a Root Token for HashiCorp Vault Quickly
tags: hashicorpvault, api, vault
---

Sometimes, in an emergency (or, more likely in my case, I forgot something important) I'll need to generate a Vault Root Token, as a sort of "break glass" procedure.


Both https://www.vaultproject.io/docs/commands/operator/generate-root.html and https://learn.hashicorp.com/vault/operations/ops-generate-root seem to either be missing steps or doubling steps, respectively.

So, to add to the confusion, I've decided to write my own "guide", hastily copied from my favorite documentation generation tool, 
`history | grep vault >> post-this-somewhere.md`.

NOTE: This assumes you already have a test Vault running and unsealed, 
and that it uses a **single** Unseal key. Using a **single** Unseal key is unsafe and, frankly, a bit embarrassing. Don't let your mother or your lead SysAdmin watch you doing this. If you are the lead SysAdmin, just close your eyes for the entirety of this exercise. 

##  Make a Test Vault if you don't have one already

### File Backend with Open Source Vault

Create a `test-vault.hcl` config file to work with.

    mkdir test
    cd test
    vi test-vault.hcl

Contents of `test-vault.hcl` should be: 

```
storage "file" {
  path = "./test-vault/data"
}


disable_mlock = true

listener "tcp" {
  address = "127.0.0.1:8200"
  tls_disable = true
}

ui = true
```

Run a Test Vault from the above configuration file: 

    wget 'https://releases.hashicorp.com/vault/1.1.2/vault_1.1.2_linux_amd64.zip'
    unzip vault_1.1.2_linux_amd64.zip
    ./vault server -config-file=test-vault.hcl
    cd ../
    export VAULT_ADDR=http://127.0.0.1:8200

##  Get the Vault Help for Generating Vault Root Tokens

    generate-root-test1$ vault operator generate-root --help
    Usage: vault operator generate-root [options] [KEY]
    
      Generates a new root token by combining a quorum of share holders. One of
      the following must be provided to start the root token generation:
    
        - A base64-encoded one-time-password (OTP) provided via the "-otp" flag.
          Use the "-generate-otp" flag to generate a usable value. The resulting
          token is XORed with this value when it is returned. Use the "-decode"
          flag to output the final value.
    
        - A file containing a PGP key or a keybase username in the "-pgp-key"
          flag. The resulting token is encrypted with this public key.
    
      An unseal key may be provided directly on the command line as an argument to
      the command. If key is specified as "-", the command will read from stdin. If
      a TTY is available, the command will prompt for text.
    
      Generate an OTP code for the final token:
    
          $ vault operator generate-root -generate-otp
    
      Start a root token generation:
    
          $ vault operator generate-root -init -otp="..."
          $ vault operator generate-root -init -pgp-key="..."
    
      Enter an unseal key to progress root token generation:
    
          $ vault operator generate-root -otp="..."
    
    HTTP Options:
    
      -address=<string>
          Address of the Vault server. The default is https://127.0.0.1:8200. This
          can also be specified via the VAULT_ADDR environment variable.
    
      -agent-address=<string>
          Address of the Agent. This can also be specified via the
          VAULT_AGENT_ADDR environment variable.
    
      -ca-cert=<string>
          Path on the local disk to a single PEM-encoded CA certificate to verify
          the Vault server's SSL certificate. This takes precedence over -ca-path.
          This can also be specified via the VAULT_CACERT environment variable.
    
      -ca-path=<string>
          Path on the local disk to a directory of PEM-encoded CA certificates to
          verify the Vault server's SSL certificate. This can also be specified
          via the VAULT_CAPATH environment variable.
    
      -client-cert=<string>
          Path on the local disk to a single PEM-encoded CA certificate to use
          for TLS authentication to the Vault server. If this flag is specified,
          -client-key is also required. This can also be specified via the
          VAULT_CLIENT_CERT environment variable.
    
      -client-key=<string>
          Path on the local disk to a single PEM-encoded private key matching the
          client certificate from -client-cert. This can also be specified via the
          VAULT_CLIENT_KEY environment variable.
    
      -mfa=<string>
          Supply MFA credentials as part of X-Vault-MFA header. This can also be
          specified via the VAULT_MFA environment variable.
    
      -namespace=<string>
          The namespace to use for the command. Setting this is not necessary
          but allows using relative paths. -ns can be used as shortcut. The
          default is (not set). This can also be specified via the VAULT_NAMESPACE
          environment variable.
    
      -output-curl-string
          Instead of executing the request, print an equivalent cURL command
          string and exit. The default is false.
    
      -policy-override
          Override a Sentinel policy that has a soft-mandatory enforcement_level
          specified The default is false.
    
      -tls-server-name=<string>
          Name to use as the SNI host when connecting to the Vault server via TLS.
          This can also be specified via the VAULT_TLS_SERVER_NAME environment
          variable.
    
      -tls-skip-verify
          Disable verification of TLS certificates. Using this option is highly
          discouraged as it decreases the security of data transmissions to and
          from the Vault server. The default is false. This can also be specified
          via the VAULT_SKIP_VERIFY environment variable.
    
      -wrap-ttl=<duration>
          Wraps the response in a cubbyhole token with the requested TTL. The
          response is available via the "vault unwrap" command. The TTL is
          specified as a numeric string with suffix like "30s" or "5m". This can
          also be specified via the VAULT_WRAP_TTL environment variable.
    
    Output Options:
    
      -format=<string>
          Print the output in the given format. Valid formats are "table", "json",
          or "yaml". The default is table. This can also be specified via the
          VAULT_FORMAT environment variable.
    
    Command Options:
    
      -cancel
          Reset the root token generation progress. This will discard any
          submitted unseal keys or configuration. The default is false.
    
      -decode=<string>
          The value to decode; setting this triggers a decode operation.
    
      -dr-token
          Set this flag to do generate root operations on DR Operational tokens.
          The default is false.
    
      -generate-otp
          Generate and print a high-entropy one-time-password (OTP) suitable for
          use with the "-init" flag. The default is false.
    
      -init
          Start a root token generation. This can only be done if there is not
          currently one in progress. The default is false.
    
      -nonce=<string>
          Nonce value provided at initialization. The same nonce value must be
          provided with each unseal key.
    
      -otp=<string>
          OTP code to use with "-decode" or "-init".
    
      -pgp-key=<keybase:user>
          Path to a file on disk containing a binary or base64-encoded public GPG
          key. This can also be specified as a Keybase username using the format
          "keybase:<username>". When supplied, the generated root token will be
          encrypted and base64-encoded with the given public key.
    
      -status
          Print the status of the current attempt without providing an unseal key.
          The default is false.
    generate-root-test$

##  Generate a Generic OTP for Root Token Generation

    generate-root-test1$ vault operator generate-root -generate-otp > otp.txt

##  Start the Root Token Geneneration

Yeah, it takes multiple steps. Deal. 

    generate-root-test1$ vault operator generate-root -init -otp=$(cat otp.txt)
    Nonce         8c386f85-ba37-c74b-4ebc-436ec341dbca
    Started       true
    Progress      0/1
    Complete      false
    OTP Length    26
    generate-root-test$ 
    
##  Generate Root Token incorrectly

    generate-root-test$ vault operator generate-root
    Operation nonce: 8c386f85-ba37-c74b-4ebc-436ec341dbca
    Unseal Key (will be hidden): 
    Error posting unseal key: Error making API request.
    
    URL: PUT http://127.0.0.1:8200/v1/sys/generate-root/update
    Code: 400. Errors:
    
    * 'key' must be a valid hex or base64 string
    
    NOTE: Turns out I copied the unseal key incorrectly

##  Get an Encoded Token Correctly this time
    
    generate-root-test1$ vault operator generate-root
    Operation nonce: 8c386f85-ba37-c74b-4ebc-436ec341dbca
    Unseal Key (will be hidden): 
    Nonce            8c386f85-ba37-c74b-4ebc-436ec341dbca
    Started          true
    Progress         1/1
    Complete         true
    Encoded Token    K3okGaAYO2w4nATeFawgA0T9LQM7zZioNWw
    
##  Attempt to Decode the Encoded Token Incorrectly
    
    generate-root-test1$ vault operator generate-root -decode=K3okGaAYO2w4nATeFawgA0T9LQM7zZioNWw  ##  Forgot to supply OTP
    
    generate-root-test1$ vault operator generate-root -decode=K3okGaAYO2w4nATeFawgA0T9LQM7zZioNWw -otp=8c386f85-ba37-c74b-4ebc-436ec341dbca  ## Supplied nonce instead of otp
    
    
    generate-root-test1$ vault operator generate-root --help
    
    generate-root-test1$ vault operator generate-root --help
    Usage: vault operator generate-root [options] [KEY]
    
      Generates a new root token by combining a quorum of share holders. One of
      the following must be provided to start the root token generation:
    
        - A base64-encoded one-time-password (OTP) provided via the "-otp" flag.
          Use the "-generate-otp" flag to generate a usable value. The resulting
          token is XORed with this value when it is returned. Use the "-decode"
          flag to output the final value.
    
        - A file containing a PGP key or a keybase username in the "-pgp-key"
          flag. The resulting token is encrypted with this public key.
    
      An unseal key may be provided directly on the command line as an argument to
      the command. If key is specified as "-", the command will read from stdin. If
      a TTY is available, the command will prompt for text.
    
      Generate an OTP code for the final token:
    
          $ vault operator generate-root -generate-otp
    
      Start a root token generation:
    
          $ vault operator generate-root -init -otp="..."
          $ vault operator generate-root -init -pgp-key="..."
    
      Enter an unseal key to progress root token generation:
    
          $ vault operator generate-root -otp="..."
    
    HTTP Options:
    
      -address=<string>
          Address of the Vault server. The default is https://127.0.0.1:8200. This
          can also be specified via the VAULT_ADDR environment variable.
    
      -agent-address=<string>
          Address of the Agent. This can also be specified via the
          VAULT_AGENT_ADDR environment variable.
    
      -ca-cert=<string>
          Path on the local disk to a single PEM-encoded CA certificate to verify
          the Vault server's SSL certificate. This takes precedence over -ca-path.
          This can also be specified via the VAULT_CACERT environment variable.
    
      -ca-path=<string>
          Path on the local disk to a directory of PEM-encoded CA certificates to
          verify the Vault server's SSL certificate. This can also be specified
          via the VAULT_CAPATH environment variable.
    
      -client-cert=<string>
          Path on the local disk to a single PEM-encoded CA certificate to use
          for TLS authentication to the Vault server. If this flag is specified,
          -client-key is also required. This can also be specified via the
          VAULT_CLIENT_CERT environment variable.
    
      -client-key=<string>
          Path on the local disk to a single PEM-encoded private key matching the
          client certificate from -client-cert. This can also be specified via the
          VAULT_CLIENT_KEY environment variable.
    
      -mfa=<string>
          Supply MFA credentials as part of X-Vault-MFA header. This can also be
          specified via the VAULT_MFA environment variable.
    
      -namespace=<string>
          The namespace to use for the command. Setting this is not necessary
          but allows using relative paths. -ns can be used as shortcut. The
          default is (not set). This can also be specified via the VAULT_NAMESPACE
          environment variable.
    
      -output-curl-string
          Instead of executing the request, print an equivalent cURL command
          string and exit. The default is false.
    
      -policy-override
          Override a Sentinel policy that has a soft-mandatory enforcement_level
          specified The default is false.
    
      -tls-server-name=<string>
          Name to use as the SNI host when connecting to the Vault server via TLS.
          This can also be specified via the VAULT_TLS_SERVER_NAME environment
          variable.
    
      -tls-skip-verify
          Disable verification of TLS certificates. Using this option is highly
          discouraged as it decreases the security of data transmissions to and
          from the Vault server. The default is false. This can also be specified
          via the VAULT_SKIP_VERIFY environment variable.
    
      -wrap-ttl=<duration>
          Wraps the response in a cubbyhole token with the requested TTL. The
          response is available via the "vault unwrap" command. The TTL is
          specified as a numeric string with suffix like "30s" or "5m". This can
          also be specified via the VAULT_WRAP_TTL environment variable.
    
    Output Options:
    
      -format=<string>
          Print the output in the given format. Valid formats are "table", "json",
          or "yaml". The default is table. This can also be specified via the
          VAULT_FORMAT environment variable.
    
    Command Options:
    
      -cancel
          Reset the root token generation progress. This will discard any
          submitted unseal keys or configuration. The default is false.
    
      -decode=<string>
          The value to decode; setting this triggers a decode operation.
    
      -dr-token
          Set this flag to do generate root operations on DR Operational tokens.
          The default is false.
    
      -generate-otp
          Generate and print a high-entropy one-time-password (OTP) suitable for
          use with the "-init" flag. The default is false.
    
      -init
          Start a root token generation. This can only be done if there is not
          currently one in progress. The default is false.
    
      -nonce=<string>
          Nonce value provided at initialization. The same nonce value must be
          provided with each unseal key.
    
      -otp=<string>
          OTP code to use with "-decode" or "-init".
    
      -pgp-key=<keybase:user>
          Path to a file on disk containing a binary or base64-encoded public GPG
          key. This can also be specified as a Keybase username using the format
          "keybase:<username>". When supplied, the generated root token will be
          encrypted and base64-encoded with the given public key.
    
      -status
          Print the status of the current attempt without providing an unseal key.
          The default is false.
    generate-root-test$
 

    
##  Correctly Decode the Encoded Token


    vault operator generate-root -decode=K3okGkAYO2w4BwEPFywJA0M9LQM7DzZNQWw -otp=$(cat otp.txt)  ##  Finally used it correctly.
    s.Tt2ya8Yo56YitsN0tbuTTeRU

##  And, Finally, We're Done Here

    export VAULT_TOKEN=s.Tt2ya8Yo56YitsN0tbuTTeRU  ##  To be quickly replaced by a token with admin privileges

##  Now you can Use the Vault Token


    curl --header "X-Vault-Token: ${VAULT_TOKEN}" "$VAULT_ADDR/v1/sys/policies/acl"  ##  Get a list of the names of your Vault Policies

Questions? Hit the comments. This is mostly for my own reference, but if anyone finds it useful I can improve it.