HashiCorp Vault is an industry-standard secrets management platform that stores, generates, and controls access to sensitive values such as API keys, database passwords, TLS certificates, and encryption keys. Unlike storing secrets in environment variables or configuration files, Vault provides audit logging, dynamic credentials with short TTLs, and fine-grained access policies. On RHEL 8, Vault installs cleanly from HashiCorp’s official RPM repository and integrates with systemd for reliable operation. In this tutorial you will add the HashiCorp repository, install Vault, configure a server, initialize and unseal it, and perform basic secrets operations including AppRole authentication for applications.
Prerequisites
- RHEL 8 server with a non-root sudo user
- At least 1 GB RAM; 2 GB recommended for production Raft storage
- Outbound internet access to
rpm.releases.hashicorp.com, or a local mirror firewalldrunning; port 8200 will be opened for the Vault listener- Optionally, a dedicated block device or directory for Raft integrated storage
Step 1 — Add the HashiCorp Repository and Install Vault
HashiCorp provides a signed RPM repository for RHEL/CentOS. Add the repository, import the GPG key, and install Vault.
dnf install -y yum-utils
yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
dnf install -y vault
vault version
The package creates the vault system user, installs the binary to /usr/bin/vault, places a default configuration in /etc/vault.d/vault.hcl, and registers a systemd unit at /usr/lib/systemd/system/vault.service.
Step 2 — Configure vault.hcl
Edit the main configuration file to define the TCP listener, the storage backend (Raft integrated storage is recommended for single-node setups), and the API address Vault will advertise.
cat > /etc/vault.d/vault.hcl << 'EOF'
ui = true
storage "raft" {
path = "/opt/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = "true"
}
api_addr = "http://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8201"
EOF
mkdir -p /opt/vault/data
chown vault:vault /opt/vault/data
chmod 750 /opt/vault/data
Note: tls_disable = "true" is used here for a local development/lab setup. In production, configure TLS certificates under tls_cert_file and tls_key_file and remove the disable flag.
Step 3 — Open Firewall Port and Start Vault
firewall-cmd --permanent --add-port=8200/tcp
firewall-cmd --reload
systemctl enable --now vault
systemctl status vault
# Set the Vault address for CLI use
export VAULT_ADDR='http://127.0.0.1:8200'
echo 'export VAULT_ADDR=http://127.0.0.1:8200' >> /etc/profile.d/vault.sh
Step 4 — Initialize and Unseal Vault
A freshly started Vault is in a sealed state and cannot process requests. Initialization generates the master key shares and a root token. You must unseal Vault by providing at least 3 of the 5 key shares each time the service restarts.
# Initialize with default 5 key shares, threshold of 3
vault operator init
# Save ALL five unseal keys and the Initial Root Token in a secure location
# (password manager, HSM, or printed and stored in a safe)
# Unseal three times, entering a different key share each time
vault operator unseal # enter key share 1
vault operator unseal # enter key share 2
vault operator unseal # enter key share 3
# Verify Vault is unsealed
vault status
The vault status output should show Sealed: false and Storage Type: raft. Log in with the root token for initial configuration:
vault login # paste the Initial Root Token when prompted
Step 5 — Enable the KV-v2 Secrets Engine and Store Secrets
The KV (key-value) version 2 secrets engine adds versioning and soft-delete functionality. Enable it at the secret/ path and write your first secret.
# Enable KV-v2 at the path "secret/"
vault secrets enable -path=secret kv-v2
# Write a secret
vault kv put secret/myapp/config
db_password="S3cur3P@ssw0rd"
api_key="abcdef1234567890"
# Read it back
vault kv get secret/myapp/config
# Read a specific field only
vault kv get -field=db_password secret/myapp/config
# View version history
vault kv metadata get secret/myapp/config
Step 6 — Configure AppRole Authentication for Applications
Applications should authenticate to Vault using AppRole rather than a root token. AppRole issues a role_id (public identifier) and a secret_id (credential) that together produce a short-lived token with a scoped policy.
# Enable the AppRole auth method
vault auth enable approle
# Create a policy granting read-only access to myapp secrets
cat > /tmp/myapp-policy.hcl << 'EOF'
path "secret/data/myapp/*" {
capabilities = ["read"]
}
EOF
vault policy write myapp-read /tmp/myapp-policy.hcl
# Create an AppRole tied to that policy
vault write auth/approle/role/myapp
policies="myapp-read"
token_ttl=1h
token_max_ttl=4h
# Retrieve the role_id (not secret; can be embedded in app config)
vault read auth/approle/role/myapp/role-id
# Generate a secret_id (treat like a password; generate per-deployment)
vault write -f auth/approle/role/myapp/secret-id
# Application authenticates and receives a token
vault write auth/approle/login
role_id=""
secret_id=""
Conclusion
You have added the HashiCorp RPM repository, installed Vault on RHEL 8, configured Raft integrated storage, initialized and unsealed the cluster, enabled the KV-v2 secrets engine, and set up AppRole authentication so applications can retrieve secrets without hard-coded credentials. Vault’s audit log, policy engine, and dynamic secrets capabilities make it a foundational component of a mature secrets management strategy.
Next steps: How to Configure Vault Auto-Unseal with AWS KMS on RHEL 8, How to Issue Dynamic PostgreSQL Credentials with Vault on RHEL 8, and How to Set Up a Certificate Authority with OpenSSL on RHEL 8.