Secrets Management Guide

    Deploying OpenBao

    OpenBao is an open-source, community-driven fork of HashiCorp Vault governed by the Linux Foundation. It provides identity-based secrets and encryption management — securely store API keys, passwords, certificates, and encryption keys on RamNode's reliable VPS hosting.

    AES-256 Encryption
    Dynamic Secrets
    ACL Policies
    Audit Logging
    1

    Introduction & What is OpenBao

    OpenBao is an open-source, community-driven fork of HashiCorp Vault, governed by the Linux Foundation and the Open Source Security Foundation (OpenSSF). Following HashiCorp's switch to a Business Source License (BSL), OpenBao emerged as the truly open-source alternative under the MPL 2.0 license — offering the same battle-tested architecture with no vendor lock-in.

    Why OpenBao on RamNode?

    • Full control over your secrets infrastructure on dedicated VPS resources
    • No per-secret or per-request pricing — flat VPS cost regardless of usage
    • Low-latency access from RamNode's high-performance network
    • Ideal for self-hosters, small teams, and budget-conscious developers
    • Perfect complement to existing self-hosted infrastructure

    Key Features

    FeatureDescription
    Secret StorageEncrypted at rest with AES-256-GCM; KV, database credentials, SSH keys, and more
    Dynamic SecretsGenerate short-lived credentials on demand for databases and services
    Encryption as a ServiceCentralized transit encryption without exposing keys to applications
    Access ControlFine-grained ACL policies with LDAP, OIDC, AppRole authentication
    Audit LoggingComprehensive audit trail of every secret access and operation
    Web UIBuilt-in web interface for visual secret management
    NamespacesMulti-tenant isolation for teams and environments
    PKI/CertificatesBuilt-in Certificate Authority with ACME support
    2

    Prerequisites

    • A RamNode VPS running Ubuntu 22.04 or 24.04 LTS
    • Root or sudo access to your server
    • A domain name pointed to your server's IP address (recommended for TLS)
    • Basic familiarity with the Linux command line
    • SSH access configured with key-based authentication

    Note: This guide assumes intermediate Linux administration experience. If you're new to secrets management, the Docker deployment method (Method A) provides the quickest path to a working setup.

    3

    RamNode VPS Sizing Recommendations

    Use CasevCPUsRAMStorageNotes
    Dev/Testing11 GB20 GB SSDDev mode, single user
    Small Team22 GB40 GB SSDUp to 10 users, KV + basic auth
    Production2–44 GB+80 GB SSDDynamic secrets, PKI, audit logs
    High Availability4+8 GB+100 GB SSDRaft cluster, multiple nodes

    RamNode Tip: For most self-hosting use cases, a 2 GB RAM VPS provides excellent performance. OpenBao's integrated Raft storage eliminates the need for an external database, keeping your deployment simple and cost-effective.

    4

    Method A: Docker Deployment (Recommended)

    Docker provides the fastest path to a production-ready OpenBao deployment with easy upgrades and rollbacks.

    Step 1: Install Docker

    Install Docker Engine
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y ca-certificates curl gnupg
    
    # Add Docker's official GPG key
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
      | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg
    
    # Add the Docker repository
    echo "deb [arch=$(dpkg --print-architecture) \
      signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
      | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

    Step 2: Create Directory Structure

    Create directories
    sudo mkdir -p /opt/openbao/{config,data,logs}
    sudo chown -R 100:1000 /opt/openbao

    Step 3: Create Configuration File

    /opt/openbao/config/openbao.hcl
    cluster_name = "ramnode-openbao"
    
    ui = true
    
    storage "raft" {
      path    = "/openbao/file"
      node_id = "node1"
    }
    
    listener "tcp" {
      address     = "0.0.0.0:8200"
      tls_disable = true  # We will add TLS in Section 11
    }
    
    api_addr     = "http://YOUR_SERVER_IP:8200"
    cluster_addr = "http://YOUR_SERVER_IP:8201"
    
    default_lease_ttl = "168h"
    max_lease_ttl     = "720h"
    
    disable_mlock = true

    Important: Replace YOUR_SERVER_IP with your RamNode VPS public IP address. TLS will be configured later — do not expose port 8200 to the public internet without TLS in production.

    Step 4: Create Docker Compose File

    /opt/openbao/docker-compose.yml
    services:
      openbao:
        image: openbao/openbao:latest
        container_name: openbao
        restart: unless-stopped
        cap_add:
          - IPC_LOCK
        ports:
          - "8200:8200"
          - "8201:8201"
        volumes:
          - /opt/openbao/config:/openbao/config:ro
          - /opt/openbao/data:/openbao/file
          - /opt/openbao/logs:/openbao/logs
        environment:
          BAO_ADDR: "http://127.0.0.1:8200"
          BAO_API_ADDR: "http://YOUR_SERVER_IP:8200"
        command: server
        mem_swappiness: 0

    Step 5: Start OpenBao

    Launch the container
    cd /opt/openbao
    sudo docker compose up -d
    
    # Verify the container is running
    sudo docker compose logs -f openbao

    You should see output indicating the server has started and is listening on port 8200. The server will report that it is sealed and not yet initialized — this is expected.

    5

    Method B: Native Package Installation

    For those who prefer running OpenBao directly on the host without Docker.

    Step 1: Install OpenBao from Official Repository

    Install OpenBao
    # Install dependencies
    sudo apt update && sudo apt install -y gpg wget
    
    # Add the OpenBao GPG key and repository
    wget -O- https://pkg.openbao.org/gpg.key \
      | sudo gpg --dearmor -o /usr/share/keyrings/openbao-keyring.gpg
    
    echo "deb [signed-by=/usr/share/keyrings/openbao-keyring.gpg] \
      https://pkg.openbao.org/deb stable main" \
      | sudo tee /etc/apt/sources.list.d/openbao.list
    
    sudo apt update
    sudo apt install -y openbao

    Step 2: Verify Installation

    Check version
    bao version
    # Expected output: OpenBao v2.5.0 (...)

    Step 3: Configure OpenBao

    /etc/openbao/openbao.hcl
    cluster_name = "ramnode-openbao"
    
    ui = true
    
    storage "raft" {
      path    = "/var/lib/openbao/data"
      node_id = "node1"
    }
    
    listener "tcp" {
      address     = "0.0.0.0:8200"
      tls_disable = true
    }
    
    api_addr     = "http://YOUR_SERVER_IP:8200"
    cluster_addr = "http://YOUR_SERVER_IP:8201"
    
    default_lease_ttl = "168h"
    max_lease_ttl     = "720h"

    Step 4: Prepare Data Directory and Start

    Start the service
    sudo mkdir -p /var/lib/openbao/data
    sudo chown -R openbao:openbao /var/lib/openbao
    
    sudo systemctl enable openbao
    sudo systemctl start openbao
    sudo systemctl status openbao

    Step 5: Set Environment Variable

    Add to shell profile
    # Add to ~/.bashrc or ~/.profile
    export BAO_ADDR="http://127.0.0.1:8200"
    
    # Reload your shell
    source ~/.bashrc
    6

    Initializing & Unsealing OpenBao

    After starting OpenBao for the first time, you must initialize it to generate encryption keys and a root token. This is a one-time operation.

    Initialize the Server

    Initialize (choose your method)
    # Docker method:
    sudo docker exec openbao bao operator init
    
    # Native method:
    bao operator init

    This outputs 5 unseal keys and an Initial Root Token. By default, OpenBao uses Shamir's Secret Sharing with 5 key shares and a threshold of 3.

    Critical Security Step: Store each unseal key and the root token in separate, secure locations. Consider a password manager, HSM, or splitting keys among trusted team members. If you lose enough unseal keys, your secrets are permanently inaccessible.

    Unseal the Server

    Provide 3 of the 5 unseal keys. Repeat this command three times with different keys:

    Unseal (repeat 3 times)
    # Docker method:
    sudo docker exec -it openbao bao operator unseal
    
    # Native method:
    bao operator unseal

    Verify Status

    Check status
    # Docker method:
    sudo docker exec openbao bao status
    
    # Native method:
    bao status

    Authenticate with Root Token

    Login
    # Docker method:
    sudo docker exec -e BAO_TOKEN="YOUR_ROOT_TOKEN" \
      openbao bao token lookup
    
    # Native method:
    bao login YOUR_ROOT_TOKEN
    7

    Enabling the Web UI

    The web UI is enabled by the ui = true directive in your configuration file (already included in both methods above). Once OpenBao is initialized and unsealed, access the UI at:

    Access URL
    http://YOUR_SERVER_IP:8200

    Log in using your root token or any valid authentication token. The UI provides visual management for secrets engines, access policies, authentication methods, and audit devices.

    Pro Tip: For secure remote access without exposing the UI to the internet, use an SSH tunnel: ssh -L 8200:127.0.0.1:8200 user@your-ramnode-ip. Then access the UI at http://localhost:8200.

    8

    Configuring the KV Secrets Engine

    The Key/Value (KV) secrets engine is the most commonly used engine for storing arbitrary secrets.

    Enable KV v2 Secrets Engine

    Enable KV v2
    # Enable the KV v2 secrets engine at the 'secret' path
    bao secrets enable -path=secret kv-v2

    Store a Secret

    Write a secret
    bao kv put secret/myapp/config \
      db_host="db.example.com" \
      db_user="appuser" \
      db_password="s3cur3P@ssw0rd"

    Retrieve a Secret

    Read secrets
    # Read the secret
    bao kv get secret/myapp/config
    
    # Get a specific field
    bao kv get -field=db_password secret/myapp/config
    
    # Output as JSON (useful for scripts)
    bao kv get -format=json secret/myapp/config

    Version History

    KV v2 automatically versions secrets, allowing you to view previous values and roll back:

    Version management
    # View metadata and version history
    bao kv metadata get secret/myapp/config
    
    # Read a specific version
    bao kv get -version=1 secret/myapp/config
    9

    Setting Up Access Policies

    Policies define what paths a token can access and what operations are allowed. Never use the root token for regular operations — create scoped policies instead.

    Create an Application Policy

    myapp-policy.hcl
    # Allow read access to application secrets
    path "secret/data/myapp/*" {
      capabilities = ["read", "list"]
    }
    
    # Allow the app to renew its own token
    path "auth/token/renew-self" {
      capabilities = ["update"]
    }

    Apply the Policy

    Write and verify policy
    bao policy write myapp myapp-policy.hcl
    
    # Verify
    bao policy read myapp

    Create a Token with the Policy

    Create scoped token
    bao token create -policy=myapp -ttl=24h

    Enable AppRole Authentication (Recommended for Apps)

    Configure AppRole
    # Enable AppRole auth
    bao auth enable approle
    
    # Create a role for your application
    bao write auth/approle/role/myapp \
      token_policies=myapp \
      token_ttl=1h \
      token_max_ttl=4h \
      secret_id_ttl=10m
    
    # Get the Role ID
    bao read auth/approle/role/myapp/role-id
    
    # Generate a Secret ID
    bao write -f auth/approle/role/myapp/secret-id
    
    # Authenticate (from your application)
    bao write auth/approle/login \
      role_id=YOUR_ROLE_ID \
      secret_id=YOUR_SECRET_ID
    10

    Enabling Audit Logging

    Audit logging records every request and response to OpenBao, providing a comprehensive trail for compliance and security investigation.

    Enable File-Based Audit Log

    Enable audit device
    # For Docker deployments:
    bao audit enable file file_path=/openbao/logs/audit.log
    
    # For native deployments:
    bao audit enable file file_path=/var/log/openbao/audit.log

    Verify Audit Device

    Check audit devices
    bao audit list -detailed

    Log Rotation

    /etc/logrotate.d/openbao
    /var/log/openbao/audit.log {
      daily
      rotate 30
      compress
      missingok
      notifempty
      postrotate
        /bin/kill -HUP $(cat /var/run/openbao.pid 2>/dev/null) 2>/dev/null || true
      endscript
    }
    11

    TLS Configuration with Let's Encrypt

    Production deployments must use TLS to encrypt all communication with the OpenBao server.

    Option A: Reverse Proxy with Nginx (Recommended)

    Install Nginx and Certbot
    sudo apt install -y nginx certbot python3-certbot-nginx
    /etc/nginx/sites-available/openbao
    server {
        listen 443 ssl http2;
        server_name bao.yourdomain.com;
    
        ssl_certificate     /etc/letsencrypt/live/bao.yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/bao.yourdomain.com/privkey.pem;
    
        location / {
            proxy_pass          http://127.0.0.1:8200;
            proxy_set_header    Host $host;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto $scheme;
        }
    }
    Enable site and obtain certificate
    sudo ln -s /etc/nginx/sites-available/openbao /etc/nginx/sites-enabled/
    sudo certbot --nginx -d bao.yourdomain.com
    sudo systemctl reload nginx

    Option B: Native TLS in OpenBao

    Update listener block in config
    listener "tcp" {
      address       = "0.0.0.0:8200"
      tls_cert_file = "/path/to/fullchain.pem"
      tls_key_file  = "/path/to/privkey.pem"
    }

    Update your api_addr to use https:// and restart OpenBao.

    12

    Production Hardening Checklist

    #ItemDetails
    1Enable TLSNever run without TLS in production
    2Revoke Root TokenAfter initial setup: bao token revoke YOUR_ROOT_TOKEN
    3Disable SwapUse swapoff -a or ensure swap is encrypted
    4Enable Audit LoggingAt least one audit device must be active
    5Firewall RulesRestrict port 8200 to known IPs; block 8201 externally unless clustering
    6Least-Privilege PoliciesCreate scoped policies per application; never share root token
    7Token TTLsSet short TTLs and require renewal; avoid long-lived tokens
    8Unseal Key DistributionSplit unseal keys among multiple trusted operators
    9Regular UpdatesSubscribe to OpenBao's security advisories and update promptly
    10Monitor & AlertMonitor /v1/sys/health endpoint; alert on seal events
    13

    Backup & Recovery

    The integrated Raft storage backend supports native snapshots for backup and recovery.

    Raft Snapshot Backup

    Create and automate backups
    # Create a snapshot
    bao operator raft snapshot save backup.snap
    
    # Automate with cron (daily at 2 AM)
    0 2 * * * /usr/bin/bao operator raft snapshot save \
      /opt/openbao/backups/bao-$(date +\%Y\%m\%d).snap

    Restore from Snapshot

    Restore backup
    # Restore (requires initialized and unsealed server)
    bao operator raft snapshot restore backup.snap

    Backup Security: Snapshots contain all your secrets in encrypted form. Store backups in an encrypted, off-site location. The unseal keys are still required to access the data after restore.

    14

    Troubleshooting

    IssueSolution
    Server won't startCheck logs: docker compose logs openbao or journalctl -u openbao. Verify config syntax.
    Connection refused on 8200Ensure listener address is 0.0.0.0:8200 (not 127.0.0.1) if accessing remotely. Check firewall.
    Server is sealed after restartOpenBao seals on restart by design. Unseal with 3 of 5 keys each time. Consider auto-unseal with a KMS.
    Permission denied errorsVerify your token has the correct policy attached. Use bao token lookup to inspect capabilities.
    Audit log blocking requestsIf the audit log is full or inaccessible, OpenBao blocks all requests. Ensure log rotation and disk space.
    Docker IPC_LOCK capabilityEnsure cap_add: IPC_LOCK is set in docker-compose.yml.
    High memory usageReview lease counts: bao lease list. Revoke unused leases. Tune max_lease_ttl.
    15

    Next Steps & Further Reading

    • Dynamic Database Credentials: Generate short-lived database users with automatic revocation
    • PKI Secrets Engine: Run your own Certificate Authority for internal TLS with ACME support
    • Transit Encryption: Encrypt and decrypt application data without exposing keys
    • OIDC/LDAP Authentication: Integrate with your existing identity provider
    • Namespaces: Create isolated tenant environments for different teams or projects
    • High Availability with Raft: Deploy a multi-node cluster across multiple RamNode VPS instances
    • Auto-Unseal: Configure automatic unsealing with cloud KMS or PKCS#11 HSM

    Official Resources

    ResourceURL
    OpenBao Documentationopenbao.org/docs
    OpenBao GitHubgithub.com/openbao/openbao
    Docker Hub Imagehub.docker.com/r/openbao/openbao
    OpenBao API Referenceopenbao.org/api-docs

    OpenBao Deployed Successfully!

    Your open-source secrets management infrastructure is now running on RamNode. Store, manage, and audit access to your sensitive data with enterprise-grade security.