Learn OpenStack · core/security
Barbican Operations
Install and Bootstrap Barbican
# Install packages (Ubuntu/Debian)
apt install barbican-api barbican-worker python3-barbicanclient
# Sync the database
barbican-db-manage upgrade
# Register service and endpoints
openstack service create --name barbican --description "Key Manager Service" key-manager
openstack endpoint create --region RegionOne \
barbican public https://barbican.example.com:9311
openstack endpoint create --region RegionOne \
barbican internal https://10.0.0.15:9311
openstack endpoint create --region RegionOne \
barbican admin https://10.0.0.15:9311
# Create service user
openstack user create barbican \
--domain Default \
--password barbican_service_pass
openstack role add --project service --user barbican admin
Manage Secrets
Store a Secret
Store a plaintext password:
openstack secret store \
--name my-db-password \
--payload 'sup3rs3cr3t' \
--payload-content-type 'text/plain'
Store a binary secret (base64-encoded):
openstack secret store \
--name my-aes-key \
--payload "$(openssl rand -base64 32)" \
--payload-content-type 'application/octet-stream' \
--payload-content-encoding base64 \
--secret-type symmetric \
--algorithm aes \
--bit-length 256
Store a PEM private key:
openstack secret store \
--name my-tls-private-key \
--payload "$(cat /etc/ssl/private/server.key)" \
--payload-content-type 'application/pkcs8' \
--secret-type private
Store a PEM certificate:
openstack secret store \
--name my-tls-cert \
--payload "$(cat /etc/ssl/certs/server.crt)" \
--payload-content-type 'application/pkix-cert' \
--secret-type certificate
Set an expiration date on a secret:
openstack secret store \
--name temp-api-key \
--payload 'xK9mV2pQ7rL3nZ8wA1sD4tF6gH0jU5eI' \
--payload-content-type 'text/plain' \
--expiration '2026-01-01T00:00:00'
List Secrets
openstack secret list
Filter by name:
openstack secret list --name my-db-password
Filter by algorithm and secret type:
openstack secret list --algorithm aes --secret-type symmetric
Show only secrets expiring before a date:
openstack secret list --expiring-in-days 30
Get a Secret
Show metadata (does not reveal the payload):
openstack secret get https://barbican.example.com:9311/v1/secrets/abc12345-1234-1234-1234-abcdef012345
Retrieve the payload:
openstack secret get \
https://barbican.example.com:9311/v1/secrets/abc12345-1234-1234-1234-abcdef012345 \
--payload
Retrieve a binary payload (base64-encoded output):
openstack secret get \
https://barbican.example.com:9311/v1/secrets/abc12345-1234-1234-1234-abcdef012345 \
--payload \
--payload-content-type 'application/octet-stream'
Delete a Secret
openstack secret delete \
https://barbican.example.com:9311/v1/secrets/abc12345-1234-1234-1234-abcdef012345
Deleting a secret that is referenced by a container will fail with a 409 Conflict. Delete the container first.
Manage Orders
Orders tell Barbican to generate key material on your behalf. Use orders instead of secret store when you want Barbican (and its configured HSM or crypto plugin) to generate the secret — not the client.
Create a Symmetric Key Order
openstack secret order create \
--name my-volume-key \
--algorithm aes \
--bit-length 256 \
--mode cbc \
key
Parameters:
- --algorithm: aes, hmacsha256, hmacsha384, hmacsha512
- --bit-length: 128, 192, 256 (for AES)
- --mode: cbc, ctr, gcm (AES block cipher mode)
Create an Asymmetric Key Pair Order
openstack secret order create \
--name my-keypair \
--algorithm rsa \
--bit-length 4096 \
asymmetric
Parameters:
- --algorithm: rsa, ec, dsa
- --bit-length: 2048, 4096 (RSA); 256, 384, 521 (EC)
- --curve (EC only): prime256v1, secp384r1, secp521r1
Create a Certificate Order
# Full certificate (Barbican generates key + CSR, submits to CA)
openstack secret order create \
--name my-server-cert \
--algorithm rsa \
--bit-length 2048 \
--subject-dn "CN=api.example.com,O=Example Corp,C=US" \
certificate
List Orders
openstack secret order list
Get an Order
openstack secret order get \
https://barbican.example.com:9311/v1/orders/order-uuid-here
The status field shows the current state:
| Status | Meaning |
|---|---|
PENDING |
Queued, not yet picked up by worker |
PROCESSING |
Worker is actively processing |
ACTIVE |
Completed successfully; secret_href contains the result |
ERROR |
Failed; check error_status_code and error_reason |
Poll until ACTIVE:
# Loop until status is ACTIVE
ORDER_HREF="https://barbican.example.com:9311/v1/orders/order-uuid-here"
while true; do
STATUS=$(openstack secret order get "$ORDER_HREF" -f value -c Status)
echo "Status: $STATUS"
[ "$STATUS" = "ACTIVE" ] && break
[ "$STATUS" = "ERROR" ] && echo "Order failed!" && break
sleep 2
done
Manage Containers
Containers group related secrets (e.g., a TLS certificate + private key).
Create a Generic Container
SECRET_A=$(openstack secret store --name key-a --payload 'value-a' \
--payload-content-type 'text/plain' -f value -c "Secret href")
SECRET_B=$(openstack secret store --name key-b --payload 'value-b' \
--payload-content-type 'text/plain' -f value -c "Secret href")
openstack secret container create \
--name my-config-bundle \
--type generic \
--secret "api_key=$SECRET_A" \
--secret "db_password=$SECRET_B"
Create a Certificate Container
Requires secrets named exactly certificate, private_key, and optionally private_key_passphrase and intermediates:
CERT_REF="https://barbican.example.com:9311/v1/secrets/cert-uuid"
KEY_REF="https://barbican.example.com:9311/v1/secrets/key-uuid"
INT_REF="https://barbican.example.com:9311/v1/secrets/intermediates-uuid"
openstack secret container create \
--name my-tls \
--type certificate \
--secret "certificate=$CERT_REF" \
--secret "private_key=$KEY_REF" \
--secret "intermediates=$INT_REF"
This is the container type consumed by Octavia when you configure a TLS-terminated load balancer listener.
Create an RSA Key Pair Container
Requires public_key and private_key; optionally private_key_passphrase:
openstack secret container create \
--name my-rsa-pair \
--type rsa \
--secret "public_key=$PUB_REF" \
--secret "private_key=$PRIV_REF"
List Containers
openstack secret container list
Get a Container
openstack secret container get \
https://barbican.example.com:9311/v1/containers/container-uuid
Delete a Container
openstack secret container delete \
https://barbican.example.com:9311/v1/containers/container-uuid
Deleting a container does not delete the underlying secrets. Delete them separately if they are no longer needed.
Manage Certificate Authorities
List Available CAs
openstack ca list
Show CA Details
openstack ca show \
https://barbican.example.com:9311/v1/cas/ca-uuid
Show the CA's certificate chain:
openstack ca get \
https://barbican.example.com:9311/v1/cas/ca-uuid \
--cacert
Set a Preferred CA (per project)
openstack ca set \
https://barbican.example.com:9311/v1/cas/ca-uuid \
--preferred
Add a Sub-CA
If the configured plugin supports it (e.g., Dogtag), create a subordinate CA:
openstack ca create \
--name "Project Dev CA" \
--subject-dn "CN=Dev CA,O=Example Corp,C=US" \
--parent-ca-ref https://barbican.example.com:9311/v1/cas/root-ca-uuid
Manage Per-Project Quotas
Quotas limit the number of secrets, containers, and orders per project. The default is unlimited (-1).
Show Current Quotas
# Show effective quotas for the current project (includes defaults and overrides)
openstack secret quota show
# Show quota overrides for a specific project (admin only)
openstack secret quota show --project <PROJECT_ID>
Set Project Quota Overrides (admin)
openstack secret quota set \
--project <PROJECT_ID> \
--secrets 500 \
--containers 200 \
--orders 100 \
--consumers 1000 \
--cas 10
Delete Quota Overrides (revert to defaults)
openstack secret quota delete --project <PROJECT_ID>
Configure System-Wide Default Quotas
In /etc/barbican/barbican.conf:
[quota]
quota_secrets = 1000
quota_orders = 100
quota_containers = 500
quota_consumers = 1000
quota_cas = 10
Secret ACLs
By default, secrets are accessible only to the project that created them. ACLs extend access to specific users.
Add Read Access for a User
openstack acl set \
--user <USER_ID1> \
--user <USER_ID2> \
--operation-type read \
https://barbican.example.com:9311/v1/secrets/secret-uuid
View ACL
openstack acl get \
https://barbican.example.com:9311/v1/secrets/secret-uuid
Remove ACL
openstack acl delete \
https://barbican.example.com:9311/v1/secrets/secret-uuid
Direct REST API Usage
For automation or when python-barbicanclient is not available:
TOKEN=$(openstack token issue -f value -c id)
BARBICAN_URL="https://barbican.example.com:9311"
# Store a secret via REST
curl -s -X POST "$BARBICAN_URL/v1/secrets" \
-H "X-Auth-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-db-password",
"payload": "sup3rs3cr3t",
"payload_content_type": "text/plain",
"secret_type": "passphrase"
}' | python3 -m json.tool
# List secrets
curl -s "$BARBICAN_URL/v1/secrets" \
-H "X-Auth-Token: $TOKEN" | python3 -m json.tool
# Get payload
curl -s "$BARBICAN_URL/v1/secrets/abc12345/payload" \
-H "X-Auth-Token: $TOKEN" \
-H "Accept: text/plain"
Verify Barbican Health
# Check API is reachable
curl -s https://barbican.example.com:9311/ | python3 -m json.tool
# Check worker is running
systemctl status barbican-worker
# Check keystone-listener is running
systemctl status barbican-keystone-listener
# Check the barbican-api logs
journalctl -u apache2 -f # or httpd
# Run a round-trip test
SECRET=$(openstack secret store \
--name health-check \
--payload 'test-payload' \
--payload-content-type 'text/plain' \
-f value -c "Secret href")
openstack secret get "$SECRET" --payload
openstack secret delete "$SECRET"
echo "Barbican round-trip OK"