VOOZH about

URL: https://dev.to/0012303/hashicorp-vault-has-a-free-api-heres-how-to-use-it-for-secrets-management-257

⇱ HashiCorp Vault Has a Free API: Here's How to Use It for Secrets Management - DEV Community


HashiCorp Vault provides a complete HTTP API for managing secrets, encryption keys, database credentials, and access policies. The open-source version is free and gives you enterprise-grade secrets management.

Why Use the Vault API?

  • Centralize all secrets in one secure location
  • Rotate database credentials automatically
  • Encrypt sensitive data without managing keys
  • Audit every secret access with detailed logs

Getting Started

# Start Vault in dev mode
vault server -dev

export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='your-root-token'

# Store a secret
curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
 -X POST "$VAULT_ADDR/v1/secret/data/myapp/config" \
 -d '{"data": {"db_password": "supersecret", "api_key": "abc123"}}' | jq .

# Read a secret
curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
 "$VAULT_ADDR/v1/secret/data/myapp/config" | jq '.data.data'

Python Client

import requests

class VaultClient:
 def __init__(self, addr='http://127.0.0.1:8200', token=None):
 self.addr = addr
 self.headers = {'X-Vault-Token': token}

 def read_secret(self, path):
 resp = requests.get(f"{self.addr}/v1/secret/data/{path}", headers=self.headers)
 if resp.status_code == 200:
 return resp.json()['data']['data']
 return None

 def write_secret(self, path, data):
 resp = requests.post(
 f"{self.addr}/v1/secret/data/{path}",
 json={'data': data},
 headers=self.headers
 )
 return resp.json()

 def delete_secret(self, path):
 resp = requests.delete(f"{self.addr}/v1/secret/data/{path}", headers=self.headers)
 return resp.status_code == 204

 def list_secrets(self, path):
 resp = requests.request('LIST', f"{self.addr}/v1/secret/metadata/{path}", headers=self.headers)
 if resp.status_code == 200:
 return resp.json()['data']['keys']
 return []

# Usage
vault = VaultClient(token='your-root-token')

# Store application secrets
vault.write_secret('myapp/production', {
 'database_url': 'postgres://prod-server:5432/mydb',
 'redis_url': 'redis://prod-cache:6379',
 'stripe_key': 'sk_live_xxxxx',
 'jwt_secret': 'my-jwt-signing-key'
})

# Read secrets in your app
config = vault.read_secret('myapp/production')
print(f"DB: {config['database_url']}")

Dynamic Database Credentials

# Enable database secrets engine
curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
 -X POST "$VAULT_ADDR/v1/sys/mounts/database" \
 -d '{"type": "database"}'

# Configure PostgreSQL connection
curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
 -X POST "$VAULT_ADDR/v1/database/config/mydb" \
 -d '{
 "plugin_name": "postgresql-database-plugin",
 "connection_url": "postgresql://{{username}}:{{password}}@localhost:5432/mydb",
 "allowed_roles": ["readonly", "readwrite"],
 "username": "vault_admin",
 "password": "admin_password"
 }'

# Create a role
curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
 -X POST "$VAULT_ADDR/v1/database/roles/readonly" \
 -d '{
 "db_name": "mydb",
 "creation_statements": ["CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '\''{{password}}'\'' VALID UNTIL '\''{{expiration}}'\'' INHERIT; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"],
 "default_ttl": "1h",
 "max_ttl": "24h"
 }'

# Get temporary credentials (auto-expire in 1 hour!)
curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
 "$VAULT_ADDR/v1/database/creds/readonly" | jq '{username: .data.username, password: .data.password, ttl: .lease_duration}'

Encryption as a Service

import base64

def encrypt(vault, plaintext, key_name='my-key'):
 encoded = base64.b64encode(plaintext.encode()).decode()
 resp = requests.post(
 f"{vault.addr}/v1/transit/encrypt/{key_name}",
 json={'plaintext': encoded},
 headers=vault.headers
 )
 return resp.json()['data']['ciphertext']

def decrypt(vault, ciphertext, key_name='my-key'):
 resp = requests.post(
 f"{vault.addr}/v1/transit/decrypt/{key_name}",
 json={'ciphertext': ciphertext},
 headers=vault.headers
 )
 encoded = resp.json()['data']['plaintext']
 return base64.b64decode(encoded).decode()

# Encrypt sensitive data
ciphertext = encrypt(vault, 'SSN: 123-45-6789')
print(f"Encrypted: {ciphertext}")

# Decrypt when needed
plaintext = decrypt(vault, ciphertext)
print(f"Decrypted: {plaintext}")

Application Integration Pattern

import os
from functools import lru_cache

class AppConfig:
 def __init__(self):
 self.vault = VaultClient(
 addr=os.environ.get('VAULT_ADDR', 'http://127.0.0.1:8200'),
 token=os.environ.get('VAULT_TOKEN')
 )
 self._env = os.environ.get('APP_ENV', 'development')

 @lru_cache(maxsize=1)
 def get_config(self):
 return self.vault.read_secret(f'myapp/{self._env}')

 @property
 def database_url(self):
 return self.get_config()['database_url']

 @property
 def redis_url(self):
 return self.get_config()['redis_url']

 def refresh(self):
 self.get_config.cache_clear()

config = AppConfig()
print(config.database_url)

Real-World Use Case

A healthcare company stored 500+ database passwords in a shared spreadsheet. After a security audit, they migrated to Vault with dynamic credentials. Every application now gets unique, time-limited database credentials that auto-expire. When an employee leaves, no password rotation needed — their Vault token is simply revoked.

What You Can Build

  • Secrets management platform for your organization
  • Dynamic credential system with auto-rotation
  • Encryption service for sensitive data at rest
  • PKI infrastructure for internal TLS certificates
  • Access audit system tracking who accessed what secrets

Need custom security automation? I build DevOps tools and infrastructure solutions.

Email me: spinov001@gmail.com
Check out my developer tools: https://apify.com/spinov001