{"id":31103632,"url":"https://github.com/lj020326/docker-openbao-ansible","last_synced_at":"2026-05-17T00:38:59.314Z","repository":{"id":311967229,"uuid":"1045761723","full_name":"lj020326/docker-openbao-ansible","owner":"lj020326","description":"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.","archived":false,"fork":false,"pushed_at":"2025-09-14T20:24:28.000Z","size":56,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-14T22:17:50.044Z","etag":null,"topics":["ansible","openbao"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/repository/docker/lj020326/openbao-ansible","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lj020326.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-27T17:14:06.000Z","updated_at":"2025-09-14T20:24:32.000Z","dependencies_parsed_at":"2025-09-14T22:10:49.788Z","dependency_job_id":"191c4d94-ac05-48a3-8403-51dc1c95a84f","html_url":"https://github.com/lj020326/docker-openbao-ansible","commit_stats":null,"previous_names":["lj020326/docker-openbao-ansible"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lj020326/docker-openbao-ansible","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lj020326%2Fdocker-openbao-ansible","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lj020326%2Fdocker-openbao-ansible/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lj020326%2Fdocker-openbao-ansible/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lj020326%2Fdocker-openbao-ansible/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lj020326","download_url":"https://codeload.github.com/lj020326/docker-openbao-ansible/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lj020326%2Fdocker-openbao-ansible/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275526060,"owners_count":25480458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","openbao"],"created_at":"2025-09-17T02:46:05.263Z","updated_at":"2026-05-17T00:38:59.297Z","avatar_url":"https://github.com/lj020326.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Docker images build](https://github.com/lj020326/docker-openbao-ansible/actions/workflows/build-test-push.yml/badge.svg)](https://github.com/lj020326/docker-openbao-ansible/actions/workflows/build-test-push.yml)\n\n# OpenBao Enhanced Docker Image with Ansible Vault\n\nThis Docker image extends the official `openbao/openbao` 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.\n\n## Features\n- **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.\n- **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.\n- **Non-Root Execution**: Runs as the `openbao` user, eliminating the need for root privileges or `chown` operations.\n- **Robust Health Check**: Includes a Docker Compose health check to verify the vault is unsealed (`Sealed: false`).\n- **Debug Logging**: Comprehensive debug logs for troubleshooting, with sensitive data (unseal keys, tokens) redacted or not logged.\n- **Custom Configuration**: Supports custom OpenBao configuration via `/vault/custom_config/local.json`.\n- **Non-root Compliant**: Does not (1) chown, (2) chmod, (3) su-exec or run any root required commands.\n- **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.\n- **Encrypt/Decrypt JSON Storage for Root Token and Unseal Keys**:\n  - OpenBao initialization now saves the unseal keys and the root token into a single init.json file.\n  - This init.json file is then immediately encrypted using ansible-vault into init.json.enc, as long as ANSIBLE_VAULT_PASSWORD is set.\n  - The auto_unseal function now decrypts this init.json.enc file (if it exists) to retrieve the keys for unsealing. \n- **Utility Script \"openbao_info\"**: This script is enhanced to decrypt init.json.enc and provide two distinct functionalities:\n  - --content: Displays the full content of the decrypted init.json, showing both unseal keys and the root token.\n  - --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.\n\n## Prerequisites\n- **Docker**: Version 20.10 or later.\n- **Docker Compose**: Version 2.0 or later.\n- **Host Setup**:\n  - A host non-root docker/container user: E.g., `container-user` user (UID=1102, GID=1102).\n  - Host directories for `/vault/file`, `/vault/logs`, `/vault/custom_config`, and `/run/secrets` owned by the host docker user.\n- **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.\n\n## Status\n\n[![GitHub issues](https://img.shields.io/github/issues/lj020326/docker-openbao-ansible.svg?style=flat)](https://github.com/lj020326/docker-openbao-ansible/issues)\n[![GitHub stars](https://img.shields.io/github/stars/lj020326/docker-openbao-ansible.svg?style=flat)](https://github.com/lj020326/docker-openbao-ansible/stargazers)\n[![Docker Pulls - lj020326/openbao-ansible](https://img.shields.io/docker/pulls/lj020326/openbao-ansible.svg?style=flat)](https://hub.docker.com/repository/docker/lj020326/openbao-ansible/)\n\n## Setup\n\n### 1. Clone or Create Project Directory\n```bash\nmkdir openbao-ansible\ncd openbao-ansible\n```\n\n### 2. Set Up Host Directories and Configuration\n\nThis section highlights the steps necessary to properly set up the container runtime environment for the non-root `openbao` container.\n\nIn summary, the following steps are used to map the host docker user to the container `openbao` user.\n\nThe following example uses a host `user:group` of `container-user:container-user` with corresponding `uid:gid` of `1102:1102`.\nThis can be set to an alternate `UID:GID` based on the specific host docker UID/GID in the environment.\n\n**Identify the `UID:GID` for the host runtime docker user used to run the docker stack in your environment.**\n\nExample: Given a host runtime docker user `container-user`:\n```bash\n# find out the UID/GID for the container user used to run the docker stack\n$ id container-user\nuid=1102(container-user) gid=1102(container-user) groups=4(adm),24(cdrom),30(dip),46(plugdev),998(docker),1102(container-user)\n```\n\n**Create Docker Compose File**\n\nCreate a `docker-compose.yml` file:\n```yaml\nservices:\n\n  openbao:\n    image: lj020326/openbao-ansible:latest\n    container_name: docker-openbao-1\n    user: \"1102:1102\"\n    environment:\n      - VAULT_ADDR=http://127.0.0.1:8200\n      - ANSIBLE_VAULT_PASSWORD=/run/secrets/ansible_vault_password\n    ports:\n      - \"8200:8200\"\n    volumes:\n      - /etc/passwd:/etc/passwd:ro\n      - /etc/groups:/etc/groups:ro\n      - /home/container-user/docker/openbao/secrets:/run/secrets\n      - /home/container-user/docker/openbao/home:/vault\n    healthcheck:\n      test: [\"CMD-SHELL\", \"vault status \u003e /vault/logs/healthcheck_output 2\u003e\u00261 \u0026\u0026 grep -q 'Sealed.*false' /vault/logs/healthcheck_output\"]\n      interval: 30s\n      timeout: 10s\n      retries: 5\n      start_period: 300s\n    networks:\n      - docker_net\nnetworks:\n  docker_net:\n    driver: bridge\n```\n\n**Make sure the compose `user` key is set to the host docker user `UID:GID`.**\n\n```bash\n$ grep \"user:\" docker-compose.yml\n    user: \"1102:1102\"\n```\n\n**Set the `openbao` user and group to map to the host container user in `/etc/passwd` and `/etc/groups`**\n\nThe docker-compose.yml already specifies the mounts on `/etc/passwd` and `/etc/groups` used to map the container user to the host docker user.\n\n```bash\n# the host user is mapped to the container user:group `openbao`\n$ cat openbao/passwd\nopenbao:x:1102:1102:openbao user:/vault:/bin/bash\n$ cat openbao/group\nopenbao:x:1102:\n```\n\n**Set ownership for the `openbao` base directory (adjust path as needed) to match the `docker-compose.yml`**\n\n```bash\n$ mkdir -p /home/container-user/docker/openbao/home/{file,logs,custom_config}\n$ chown -R 1102:1102 /home/container-user/docker/openbao/home\n$ chmod -R u+rwX /home/container-user/docker/openbao/home\n$ chmod 600 /home/container-user/docker/openbao/secrets/ansible_vault_password\n```\n\n**Replace `\u003csecure-ansible-vault-password\u003e` with a strong password** (e.g., generated via `openssl rand -base64 32`).\n\n```bash\n$ mkdir -p /home/container-user/docker/openbao/secrets\n$ echo \"\u003csecure-ansible-vault-password\u003e\" \u003e /home/container-user/docker/openbao/secrets/ansible_vault_password\n$ chown 1102:1102 /home/container-user/docker/openbao/secrets/ansible_vault_password\n```\n\n## Optional: Build and Push the Image to internal registry\nCopy the `docker-entrypoint.sh` and `env_secrets_expand.sh` scripts into the project directory, then build and push:\n```bash\ndocker build -t openbao-ansible:latest -f Dockerfile .\ndocker tag openbao-ansible:latest registry.example.int:5000/openbao-ansible:latest\ndocker push registry.example.int:5000/openbao-ansible:latest\n```\n\n## Usage\n\n### Start the OpenBao Container\n```bash\ndocker compose -f docker-compose.yml up -d openbao\n```\n\n### Check Container Status\nVerify the container is running and healthy:\n```bash\ndocker compose ps -a\n```\n\nExpected output:\n```\nNAME               IMAGE                                            COMMAND                  SERVICE   CREATED         STATUS                    PORTS\ndocker-openbao-1   lj020326/openbao-ansible:latest   \"/usr/local/bin/dock…\"   openbao   2 minutes ago   Up 2 minutes (healthy)    0.0.0.0:8200-\u003e8200/tcp\n```\n\n### View Logs\nCheck the logs for initialization and unsealing status:\n```bash\n$ docker logs -f docker-openbao-1\n$ ## or \n$ CONTAINER_ID=$(docker ps --filter \"name=docker_stack_openbao\" --format \"{{.ID}}\")\n$ docker logs -n 10 -f \"${CONTAINER_ID}\"\n$ docker exec -it \"${CONTAINER_ID}\" openbao_info --content\n```\n\n### Retrieve Root Token\nThe root token and unseal keys are stored in `/vault/custom_config/init.txt` (encrypted with Ansible Vault). To retrieve:\n```bash\n$ docker compose exec openbao sh\n$ 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\n$ cat /vault/logs/init.txt.decrypted\n$ rm /vault/logs/init.txt.decrypted\n$ exit\n```\nExample output:\n```\nUnseal Key 1: \u003ckey1\u003e\nUnseal Key 2: \u003ckey2\u003e\nUnseal Key 3: \u003ckey3\u003e\nUnseal Key 4: \u003ckey4\u003e\nUnseal Key 5: \u003ckey5\u003e\nInitial Root Token: \u003croot-token\u003e\n```\nStore the root token securely (e.g., in a password manager) and avoid reusing it for regular operations.\n\n### Create an Admin Token\nTo avoid using the root token, create an admin token with a policy:\n```bash\ndocker compose exec openbao vault login \u003croot-token\u003e\ndocker compose exec openbao vault policy write admin - \u003c\u003cEOF\npath \"*\" {\n  capabilities = [\"create\", \"read\", \"update\", \"delete\", \"list\", \"sudo\"]\n}\nEOF\ndocker compose exec openbao vault token create -policy=admin\n```\nUse the generated admin token for regular operations.\n\n## Idempotent Configuration\n\nThe image now supports idempotent setup via `openbao_config.yml` (mounted at `/vault/config/openbao_config.yml`). On startup, `openbao_setup.sh` invokes `openbao_idempotent_setup.py` to:\n\n- Ensure policies from YAML `policies` dict (HCL content).\n- Create/update users in `userpass` auth (check vaulted JSON/API; recreate if needed, store password).\n- Create token roles (check vaulted JSON/API; recreate if invalid, store by policy key).\n\nExample `openbao_config.yml` (see repo).\n\nVaulted JSON now includes `\"users\": {\"display_name\": \"password\"}` and `\"tokens\": {\"policy\": \"token\"}`.\n\nMount in docker-compose.yml:\n```yaml\nvolumes:\n  - ./openbao_config.yml:/vault/config/openbao_config.yml:ro\n```\n\n## Updated Tests\n\nExisting tests unchanged (no regressions).\nNew: Idempotent startup, removal/restart recreation, modification/enforcement.\n\n### Next Steps\nNow that your OpenBao instance is up, unsealed, and securely accessible, you can start leveraging its power! Here are some common next steps:\n\nEnable 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:\n\n```shell\ncurl -s \"https://localhost/v1/sys/health\" | jq\n{\n  \"initialized\": true,\n  \"sealed\": false,\n  \"standby\": false,\n  \"performance_standby\": false,\n  \"replication_performance_mode\": \"disabled\",\n  \"replication_dr_mode\": \"disabled\",\n  \"server_time_utc\": 1756473816,\n  \"version\": \"2.3.2\",\n  \"cluster_name\": \"vault-cluster-1de8d78f\",\n  \"cluster_id\": \"ad1cfea7-88ff-7bbd-a4d3-b915a98ee861\"\n}\n\nCONTAINER_ID=$(docker ps --filter \"name=docker_stack_openbao\" --format \"{{.ID}}\")\n\ncurl -s -H \"X-Vault-Token: ${ROOT_TOKEN}\" \\\n--request POST \\\n--data '{\"type\": \"kv\"}' \\\n\"http://localhost/v1/sys/mounts/secret\" | jq\n\n## debugging\ncurl -v -k -H \"X-Vault-Token: ${ROOT_TOKEN}\" \\\n--request POST \\\n--data '{\"type\": \"kv\"}' \\\n\"http://localhost/v1/sys/mounts/secret\"\n```\n\nConfigure Auth Methods: Beyond token roles, you'll want to configure authentication methods for your users and applications. Common ones include Username/Password, LDAP, GitHub, or Kubernetes.\n\nWrite Policies: Define access control policies to determine what users and applications can do within OpenBao (e.g., read specific secrets, manage certain paths).\n\nIntegrate with Applications: Start integrating your applications to fetch secrets from OpenBao dynamically, rather than hardcoding them.\n\n### Test Vault Access\nVerify the vault is operational:\n```bash\ndocker compose exec openbao vault login \u003cadmin-token\u003e\ndocker compose exec openbao vault kv put secret/test key=value\ndocker compose exec openbao vault kv get secret/test\n```\n\n## Security Considerations\n- **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:\n  ```bash\n  docker compose exec openbao vault token revoke \u003croot-token\u003e\n  ```\n  **Warning**: Only revoke the root token if all necessary policies and tokens are configured, as it’s required for critical operations like rekeying.\n- **Ansible Vault Password**: Ensure the `ANSIBLE_VAULT_PASSWORD` (stored in `/run/secrets/ansible_vault_password`) is strong and rotated periodically. To rotate:\n  ```bash\n  NEW_PASSWORD=$(openssl rand -base64 32)\n  echo \"$NEW_PASSWORD\" \u003e /home/container-user/docker/openbao/secrets/ansible_vault_password\n  docker compose exec openbao sh\n  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\n  echo \"$NEW_PASSWORD\" | ansible-vault encrypt /vault/logs/init.txt.decrypted --output=/vault/custom_config/init.txt --vault-password-file=/dev/stdin\n  rm /vault/logs/init.txt.decrypted\n  exit\n  chown 1102:1102 /home/container-user/docker/openbao/secrets/ansible_vault_password\n  chmod 600 /home/container-user/docker/openbao/secrets/ansible_vault_password\n  ```\n- **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).\n- **Logs**: The `docker-entrypoint.sh` script redacts unseal keys and does not log the root token. Verify logs for sensitive data:\n  ```bash\n  docker compose exec openbao cat /vault/logs/bao_server_output\n  docker compose exec openbao cat /vault/logs/init_output\n  ```\n\n## Troubleshooting\n- **Container Not Healthy**:\n  - Check health check output:\n    ```bash\n    docker compose exec openbao cat /vault/logs/healthcheck_output\n    ```\n  - If `Sealed: true`, increase `start_period` in `docker-compose.yml` to `360s` and restart:\n    ```bash\n    docker compose -f docker-compose.yml down\n    docker compose -f docker-compose.yml up -d openbao\n    ```\n- **Initialization or Unsealing Fails**:\n  - Check logs:\n    ```bash\n    docker logs docker-openbao-1\n    ```\n  - Verify `init.txt` contents:\n    ```bash\n    docker compose exec openbao sh\n    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\n    cat /vault/logs/init.txt.decrypted\n    rm /vault/logs/init.txt.decrypted\n    exit\n    ```\n- **Permission Errors**:\n  - Verify host directory permissions:\n    ```bash\n    ls -ld /home/container-user/docker/openbao/home/{file,logs,custom_config}\n    ls -l /home/container-user/docker/openbao/secrets/ansible_vault_password\n    ```\n  - Fix if needed:\n    ```bash\n    chown -R 1102:1102 /home/container-user/docker/openbao/home\n    chown 1102:1102 /home/container-user/docker/openbao/secrets/ansible_vault_password\n    chmod -R u+rwX /home/container-user/docker/openbao/home\n    chmod 600 /home/container-user/docker/openbao/secrets/ansible_vault_password\n    ```\n\n### 🚀 How to Use the Logging \n\n**To change the log level:**\n\nBy 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.\n\nFor example, to get more detailed `DEBUG` output:\n\n```yaml\nservices:\n  openbao:\n    image: your_image_name:latest\n    environment:\n      - ENTRYPOINT_LOG_LEVEL=DEBUG # Or TRACE for even more detail\n      # ... other environment variables\n```\n\n## Contributing\nContributions are welcome! Please submit pull requests or issues to the repository hosting this image.\n\n## License\nThis project is licensed under the MIT License.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flj020326%2Fdocker-openbao-ansible","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flj020326%2Fdocker-openbao-ansible","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flj020326%2Fdocker-openbao-ansible/lists"}