Sign inSign up

lj020326/openbao-ansible

By lj020326

•Updated 3 months ago

This Docker image extends openbao using Ansible Vault to encrypt/decrypt tokens.

Image
Security
Integration & delivery
API management
0

10K+

lj020326/openbao-ansible repository overview

Docker images build

⁠OpenBao Enhanced Docker Image with Ansible Vault

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.

⁠Features

  • Automated Initialization and Unsealing: Initializes the OpenBao vault on first run and auto-unseals it using stored keys. On restarts, detects an initialized vault and unseals without reinitialization.
  • Ansible Vault Integration: Encrypts the initialization output (init.txt) containing unseal keys and the root token using ansible-vault, with the password sourced from a secure file or environment variable.
  • Non-Root Execution: Runs as the openbao user, eliminating the need for root privileges or chown operations.
  • Robust Health Check: Includes a Docker Compose health check to verify the vault is unsealed (Sealed: false).
  • Debug Logging: Comprehensive debug logs for troubleshooting, with sensitive data (unseal keys, tokens) redacted or not logged.
  • Custom Configuration: Supports custom OpenBao configuration via /vault/custom_config/local.json.
  • Non-root Compliant: Does not (1) chown, (2) chmod, (3) su-exec or run any root required commands.
  • Variable level logging: The image now includes a robust logging mechanism with levels (ERROR, WARNING, INFO, DEBUG, TRACE) controlled by the ENTRYPOINT_LOG_LEVEL environment variable. This allows you to tailor the verbosity of the entrypoint script's output without modifying the script itself.
  • Encrypt/Decrypt JSON Storage for Root Token and Unseal Keys:
    • OpenBao initialization now saves the unseal keys and the root token into a single init.json file.
    • This init.json file is then immediately encrypted using ansible-vault into init.json.enc, as long as ANSIBLE_VAULT_PASSWORD is set.
    • The auto_unseal function now decrypts this init.json.enc file (if it exists) to retrieve the keys for unsealing.
  • Utility Script "openbao_info": This script is enhanced to decrypt init.json.enc and provide two distinct functionalities:
    • --content: Displays the full content of the decrypted init.json, showing both unseal keys and the root token.
    • --root-token: Directly outputs only the root_token value, making it suitable for scripting (e.g., ROOT_TOKEN=$(docker exec ... openbao_info --root-token)). All debug output from the script is sent to stderr to keep stdout clean for the token.

⁠Prerequisites

  • Docker: Version 20.10 or later.
  • Docker Compose: Version 2.0 or later.
  • Host Setup:
    • A host non-root docker/container user: E.g., container-user user (UID=1102, GID=1102).
    • Host directories for /vault/file, /vault/logs, /vault/custom_config, and /run/secrets owned by the host docker user.
  • Ansible Vault Password: A secure password stored in /home/container-user/docker/openbao/secrets/ansible_vault_password or set via the ANSIBLE_VAULT_PASSWORD environment variable.

⁠Status

GitHub issues GitHub stars Docker Pulls - lj020326/openbao-ansible

⁠Setup

⁠1. Clone or Create Project Directory
mkdir openbao-ansible
cd openbao-ansible
⁠2. Set Up Host Directories and Configuration

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

⁠Optional: Build and Push the Image to internal registry

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

⁠Usage

⁠Start the OpenBao Container
docker compose -f docker-compose.yml up -d openbao
⁠Check Container Status

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
⁠View Logs

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
⁠Retrieve Root Token

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.

⁠Create an Admin Token

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.

⁠Next Steps

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.

⁠Test Vault Access

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

⁠Security Considerations

  • Root Token: Avoid using the root token for regular operations. Create an admin token with limited privileges and consider revoking the root token after setup:
    docker compose exec openbao vault token revoke <root-token>
    
    Warning: Only revoke the root token if all necessary policies and tokens are configured, as it’s required for critical operations like rekeying.
  • Ansible Vault Password: Ensure the 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
    
  • File Permissions: Ensure host directories (/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).
  • Logs: The 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
    

⁠Troubleshooting

  • Container Not Healthy:
    • Check health check output:
      docker compose exec openbao cat /vault/logs/healthcheck_output
      
    • If 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
      
  • Initialization or Unsealing Fails:
    • Check logs:
      docker logs docker-openbao-1
      
    • Verify 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
      
  • Permission Errors:
    • Verify host directory permissions:
      ls -ld /home/container-user/docker/openbao/home/{file,logs,custom_config}
      ls -l /home/container-user/docker/openbao/secrets/ansible_vault_password
      
    • Fix if needed:
      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
      
⁠🚀 How to Use the Logging

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

⁠Contributing

Contributions are welcome! Please submit pull requests or issues to the repository hosting this image.

⁠License

This project is licensed under the MIT License.

Tag summary

Content type

Image

Digest

sha256:b3be3337a…

Size

175.4 MB

Last updated

3 months ago

docker pull lj020326/openbao-ansible