This Docker image extends openbao using Ansible Vault to encrypt/decrypt tokens.
6.6K
This Docker image extends the official openbao/openbao:2.3.2 image to provide a secure, automated setup for running an OpenBao server with initialization and auto-unsealing, using Ansible Vault to encrypt sensitive initialization data. The image is designed to run as a non-root user (openbao, UID=1102, GID=1102) and avoids requiring chown or root privileges at runtime, adhering to Docker security best practices.
init.txt) containing unseal keys and the root token using ansible-vault, with the password sourced from a secure file or environment variable.openbao user, eliminating the need for root privileges or chown operations.Sealed: false)./vault/custom_config/local.json.container-user user (UID=1102, GID=1102)./vault/file, /vault/logs, /vault/custom_config, and /run/secrets owned by the host docker user./home/container-user/docker/openbao/secrets/ansible_vault_password or set via the ANSIBLE_VAULT_PASSWORD environment variable.mkdir openbao-ansible
cd openbao-ansible
This section highlights the steps necessary to properly set up the container runtime environment for the non-root openbao container.
In summary, the following steps are used to map the host docker user to the container openbao user.
The following example uses a host user:group of container-user:container-user with corresponding uid:gid of 1102:1102.
This can be set to an alternate UID:GID based on the specific host docker UID/GID in the environment.
Identify the UID:GID for the host runtime docker user used to run the docker stack in your environment.
Example: Given a host runtime docker user container-user:
# find out the UID/GID for the container user used to run the docker stack
$ id container-user
uid=1102(container-user) gid=1102(container-user) groups=4(adm),24(cdrom),30(dip),46(plugdev),998(docker),1102(container-user)
Create Docker Compose File
Create a docker-compose.yml file:
services:
openbao:
image: lj020326/openbao-ansible:latest
container_name: docker-openbao-1
user: "1102:1102"
environment:
- VAULT_ADDR=http://127.0.0.1:8200
- ANSIBLE_VAULT_PASSWORD=/run/secrets/ansible_vault_password
ports:
- "8200:8200"
volumes:
- /etc/passwd:/etc/passwd:ro
- /etc/groups:/etc/groups:ro
- /home/container-user/docker/openbao/secrets:/run/secrets
- /home/container-user/docker/openbao/home:/vault
healthcheck:
test: ["CMD-SHELL", "vault status > /vault/logs/healthcheck_output 2>&1 && grep -q 'Sealed.*false' /vault/logs/healthcheck_output"]
interval: 30s
timeout: 10s
retries: 5
start_period: 300s
networks:
- docker_net
networks:
docker_net:
driver: bridge
Make sure the compose user key is set to the host docker user UID:GID.
$ grep "user:" docker-compose.yml
user: "1102:1102"
Set the openbao user and group to map to the host container user in /etc/passwd and /etc/groups
The docker-compose.yml already specifies the mounts on /etc/passwd and /etc/groups used to map the container user to the host docker user.
# the host user is mapped to the container user:group `openbao`
$ cat openbao/passwd
openbao:x:1102:1102:openbao user:/vault:/bin/bash
$ cat openbao/group
openbao:x:1102:
Set ownership for the openbao base directory (adjust path as needed) to match the docker-compose.yml
$ mkdir -p /home/container-user/docker/openbao/home/{file,logs,custom_config}
$ chown -R 1102:1102 /home/container-user/docker/openbao/home
$ chmod -R u+rwX /home/container-user/docker/openbao/home
$ chmod 600 /home/container-user/docker/openbao/secrets/ansible_vault_password
Replace <secure-ansible-vault-password> with a strong password (e.g., generated via openssl rand -base64 32).
$ mkdir -p /home/container-user/docker/openbao/secrets
$ echo "<secure-ansible-vault-password>" > /home/container-user/docker/openbao/secrets/ansible_vault_password
$ chown 1102:1102 /home/container-user/docker/openbao/secrets/ansible_vault_password
Copy the docker-entrypoint.sh and env_secrets_expand.sh scripts into the project directory, then build and push:
docker build -t openbao-ansible:latest -f Dockerfile .
docker tag openbao-ansible:latest registry.example.int:5000/openbao-ansible:latest
docker push registry.example.int:5000/openbao-ansible:latest
docker compose -f docker-compose.yml up -d openbao
Verify the container is running and healthy:
docker compose ps -a
Expected output:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
docker-openbao-1 lj020326/openbao-ansible:latest "/usr/local/bin/dock…" openbao 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:8200->8200/tcp
Check the logs for initialization and unsealing status:
$ docker logs -f docker-openbao-1
$ ## or
$ CONTAINER_ID=$(docker ps --filter "name=docker_stack_openbao" --format "{{.ID}}")
$ docker logs -n 10 -f "${CONTAINER_ID}"
$ docker exec -it "${CONTAINER_ID}" openbao_info --content
The root token and unseal keys are stored in /vault/custom_config/init.txt (encrypted with Ansible Vault). To retrieve:
$ docker compose exec openbao sh
$ cat /run/secrets/ansible_vault_password | ansible-vault decrypt /vault/custom_config/init.txt --output=/vault/logs/init.txt.decrypted --vault-password-file=/dev/stdin
$ cat /vault/logs/init.txt.decrypted
$ rm /vault/logs/init.txt.decrypted
$ exit
Example output:
Unseal Key 1: <key1>
Unseal Key 2: <key2>
Unseal Key 3: <key3>
Unseal Key 4: <key4>
Unseal Key 5: <key5>
Initial Root Token: <root-token>
Store the root token securely (e.g., in a password manager) and avoid reusing it for regular operations.
To avoid using the root token, create an admin token with a policy:
docker compose exec openbao vault login <root-token>
docker compose exec openbao vault policy write admin - <<EOF
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOF
docker compose exec openbao vault token create -policy=admin
Use the generated admin token for regular operations.
Now that your OpenBao instance is up, unsealed, and securely accessible, you can start leveraging its power! Here are some common next steps:
Enable Additional Secret Engines: You'll likely want to enable other secret engines, such as Key/Value (KV) stores for generic secrets, or database secret engines to generate dynamic credentials. For example, to enable a KV secret engine:
curl -s "https://localhost/v1/sys/health" | jq
{
"initialized": true,
"sealed": false,
"standby": false,
"performance_standby": false,
"replication_performance_mode": "disabled",
"replication_dr_mode": "disabled",
"server_time_utc": 1756473816,
"version": "2.3.2",
"cluster_name": "vault-cluster-1de8d78f",
"cluster_id": "ad1cfea7-88ff-7bbd-a4d3-b915a98ee861"
}
CONTAINER_ID=$(docker ps --filter "name=docker_stack_openbao" --format "{{.ID}}")
curl -s -H "X-Vault-Token: ${ROOT_TOKEN}" \
--request POST \
--data '{"type": "kv"}' \
"http://localhost/v1/sys/mounts/secret" | jq
## debugging
curl -v -k -H "X-Vault-Token: ${ROOT_TOKEN}" \
--request POST \
--data '{"type": "kv"}' \
"http://localhost/v1/sys/mounts/secret"
Configure Auth Methods: Beyond tokens, you'll want to configure authentication methods for your users and applications. Common ones include Username/Password, LDAP, GitHub, or Kubernetes.
Write Policies: Define access control policies to determine what users and applications can do within OpenBao (e.g., read specific secrets, manage certain paths).
Integrate with Applications: Start integrating your applications to fetch secrets from OpenBao dynamically, rather than hardcoding them.
Verify the vault is operational:
docker compose exec openbao vault login <admin-token>
docker compose exec openbao vault kv put secret/test key=value
docker compose exec openbao vault kv get secret/test
docker compose exec openbao vault token revoke <root-token>
ANSIBLE_VAULT_PASSWORD (stored in /run/secrets/ansible_vault_password) is strong and rotated periodically. To rotate:
NEW_PASSWORD=$(openssl rand -base64 32)
echo "$NEW_PASSWORD" > /home/container-user/docker/openbao/secrets/ansible_vault_password
docker compose exec openbao sh
cat /run/secrets/ansible_vault_password | ansible-vault decrypt /vault/custom_config/init.txt --output=/vault/logs/init.txt.decrypted --vault-password-file=/dev/stdin
echo "$NEW_PASSWORD" | ansible-vault encrypt /vault/logs/init.txt.decrypted --output=/vault/custom_config/init.txt --vault-password-file=/dev/stdin
rm /vault/logs/init.txt.decrypted
exit
chown 1102:1102 /home/container-user/docker/openbao/secrets/ansible_vault_password
chmod 600 /home/container-user/docker/openbao/secrets/ansible_vault_password
/home/container-user/docker/openbao/home/* and /home/container-user/docker/openbao/secrets/*) are owned by openbao (1102:1102) with restricted permissions (chmod 600 for secrets).docker-entrypoint.sh script redacts unseal keys and does not log the root token. Verify logs for sensitive data:
docker compose exec openbao cat /vault/logs/bao_server_output
docker compose exec openbao cat /vault/logs/init_output
docker compose exec openbao cat /vault/logs/healthcheck_output
Sealed: true, increase start_period in docker-compose.yml to 360s and restart:
docker compose -f docker-compose.yml down
docker compose -f docker-compose.yml up -d openbao
docker logs docker-openbao-1
init.txt contents:
docker compose exec openbao sh
cat /run/secrets/ansible_vault_password | ansible-vault decrypt /vault/custom_config/init.txt --output=/vault/logs/init.txt.decrypted --vault-password-file=/dev/stdin
cat /vault/logs/init.txt.decrypted
rm /vault/logs/init.txt.decrypted
exit
ls -ld /home/container-user/docker/openbao/home/{file,logs,custom_config}
ls -l /home/container-user/docker/openbao/secrets/ansible_vault_password
chown -R 1102:1102 /home/container-user/docker/openbao/home
chown 1102:1102 /home/container-user/docker/openbao/secrets/ansible_vault_password
chmod -R u+rwX /home/container-user/docker/openbao/home
chmod 600 /home/container-user/docker/openbao/secrets/ansible_vault_password
To change the log level:
By default, the ENTRYPOINT_LOG_LEVEL is set to INFO. To increase or decrease the verbosity, you can set this environment variable in your docker-compose.yml file under the environment section for your OpenBao service.
For example, to get more detailed DEBUG output:
services:
openbao:
image: your_image_name:latest
environment:
- ENTRYPOINT_LOG_LEVEL=DEBUG # Or TRACE for even more detail
# ... other environment variables
Contributions are welcome! Please submit pull requests or issues to the repository hosting this image.
This project is licensed under the MIT License.
Content type
Image
Digest
sha256:0c638517b…
Size
181.9 MB
Last updated
22 days ago
docker pull lj020326/openbao-ansible:20260629