user638145
user638145

Reputation: 57

How to get a secret from HashiCorp's Vault HTTP API into a docker container?

Trying to get a secret from HashiCorps Vault into an environment variable inside a dockerfile using the HTTP API. Need the secret to download a file from a private git repository.

Dockerfile relevant portion

FROM debian:jessie

ENV REPOSITORY_LOCAL_IP 192.168.1.x
ENV REPOSITORY_PORT 20080
ENV REPOSITORY_USER root

ENV PRIVATE_TOKEN "$(curl -s -H "X-Vault-Token: xxx" -X GET http://192.168.1.x:8200/v1/secret/private-token | jq -r '.data.value')"

RUN apt install curl jq -y && \
    wget http://"$REPOSITORY_LOCAL_IP":"$REPOSITORY_PORT"/"$REPOSITORY_USER"/repository/blob/master/files/file.conf?private_token="$PRIVATE_TOKEN"

docker-compose.yml relevant portion

version: '2'
services:
  hhvm_dev:
    build:
      dockerfile: image.df
      context: ./images/.
    user: user
    restart: always
    stdin_open: true
    tty: true
    working_dir: /etc/image
    ports:
      - "80"

Running with docker-compose build returns the following output:

converted 'http://192.168.1.x:20080/root/repository/blob/master/files/file.conf?private_token=$(curl -s -H X-Vault-Token: xxx-token-xxx -X GET http://192.168.1.x:8200/v1/secret/private-token | jq -r '.data.value')' (ANSI_X3.4-1968) -> 'http://192.168.1.x:20080/root/repository/blob/master/files/file.conf?private_token=$(curl -s -H X-Vault-Token: xxx-token-xxx -X GET http://192.168.1.x:8200/v1/secret/private-token | jq -r '.data.value')' (UTF-8)
--2016-11-02 12:07:41--  http://192.168.1.x:20080/root/repository/blob/master/files/file.conf?private_token=$(curl%20-s%20-H%20X-Vault-Token:%xxx-token-xxx%20-X%20GET%20http://192.168.1.x:8200/v1/secret/private-token%20%7C%20jq%20-r%20'.data.value')
Connecting to 192.168.1.x:20080... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://192.168.1.x:20080/users/sign_in [following]
converted 'http://192.168.1.x:20080/users/sign_in' (ANSI_X3.4-1968) -> 'http://192.168.1.x:20080/users/sign_in' (UTF-8)
--2016-11-02 12:07:41--  http://192.168.1.x:20080/users/sign_in
Reusing existing connection to 192.168.1.x:20080.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: '/scripts/file.sh'

     0K ........                                               6.17M=0.001s

2016-11-02 12:07:42 (6.17 MB/s) - '/scripts/file.sh' saved [8270]

It looks like the PRIVATE_TOKEN is not being set at the specified location. It just downloads the login page from the private repository.

Upvotes: 1

Views: 3892

Answers (1)

BMitch
BMitch

Reputation: 263469

Docker doesn't interpret the "ENV" with a shell, it's just setting the literal string with some parsing for any docker args you may have included. While in the RUN command, the environment variable is expanded to the string, but not evaluated a second time to run the command it contains. Put your curl for the PRIVATE_TOKEN inside your RUN command, something like this untested code:

RUN export PRIVATE_TOKEN=$(curl -s -H "X-Vault-Token: xxx" -X GET http://192.168.1.x:8200/v1/secret/private-token | jq -r '.data.value') \
 && apt install curl jq -y \
 && wget http://"$REPOSITORY_LOCAL_IP":"$REPOSITORY_PORT"/"$REPOSITORY_USER"/repository/blob/master/files/file.conf?private_token="$PRIVATE_TOKEN"

Note that with this design, the PRIVATE_TOKEN will only exist in your one RUN command, so you won't be able to reuse it later.

Upvotes: 1

Related Questions