Files
magistrala/docker/openbao-entrypoint.sh
T
Steve Munene 7f03134d8e
Property Based Tests / api-test (push) Has been cancelled
Continuous Delivery / lint-and-build (push) Has been cancelled
Deploy GitHub Pages / swagger-ui (push) Has been cancelled
CI Pipeline / Lint Proto (push) Has been cancelled
CI Pipeline / Detect Changes (push) Has been cancelled
Continuous Delivery / Build and Push Docker Images (push) Has been cancelled
CI Pipeline / lint-and-build (push) Has been cancelled
CI Pipeline / Test ${{ matrix.module }} (push) Has been cancelled
CI Pipeline / Upload Coverage (push) Has been cancelled
NOISSUE - Update bootstrap and provision service (#3476)
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com>
Signed-off-by: JeffMboya <jangina.mboya@gmail.com>
Co-authored-by: JeffMboya <jangina.mboya@gmail.com>
2026-05-08 10:35:00 +02:00

491 lines
17 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0
set -e
apk add --no-cache jq
# Create required directories
mkdir -p /opt/openbao/config /opt/openbao/data /opt/openbao/logs
cat > /opt/openbao/config/config.hcl << 'EOF'
storage "file" {
path = "/opt/openbao/data"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = true
}
ui = true
log_level = "Info"
disable_mlock = true
# API timeout settings
default_lease_ttl = "168h"
max_lease_ttl = "720h"
EOF
export BAO_ADDR=http://127.0.0.1:8200
wait_for_bao() {
local retries=30
while [ "$retries" -gt 0 ]; do
local code=0
bao status -format=json >/dev/null 2>&1 || code=$?
# exit 0 = unsealed, exit 2 = sealed — both mean the server is up and responding
if [ "$code" -eq 0 ] || [ "$code" -eq 2 ]; then
return 0
fi
retries=$((retries - 1))
sleep 2
done
echo "ERROR: OpenBao server did not become ready in time" >&2
exit 1
}
unseal_bao() {
local key1="$1" key2="$2" key3="$3"
if [ -z "$key1" ] || [ -z "$key2" ] || [ -z "$key3" ]; then
echo "ERROR: One or more unseal keys are empty — cannot unseal" >&2
exit 1
fi
bao operator unseal "$key1"
bao operator unseal "$key2"
bao operator unseal "$key3"
}
create_pki_policy() {
cat > /opt/openbao/config/pki-policy.hcl << EOF
path "pki_int/issue/${MG_CERTS_OPENBAO_PKI_ROLE}" {
capabilities = ["create", "update"]
}
path "pki_int/sign/${MG_CERTS_OPENBAO_PKI_ROLE}" {
capabilities = ["create", "update"]
}
path "pki_int/sign-verbatim/${MG_CERTS_OPENBAO_PKI_ROLE}" {
capabilities = ["create", "update"]
}
path "pki_int/certs" {
capabilities = ["list"]
}
path "pki_int/cert/*" {
capabilities = ["read"]
}
path "pki_int/revoke" {
capabilities = ["create", "update"]
}
path "pki_int/ca" {
capabilities = ["read"]
}
path "pki_int/ca_chain" {
capabilities = ["read"]
}
path "pki_int/crl" {
capabilities = ["read"]
}
path "pki/ca" {
capabilities = ["read"]
}
path "pki/ca_chain" {
capabilities = ["read"]
}
path "pki/crl" {
capabilities = ["read"]
}
path "auth/token/renew-self" {
capabilities = ["update"]
}
path "auth/token/lookup-self" {
capabilities = ["read"]
}
path "sys/renew/*" {
capabilities = ["update"]
}
path "auth/approle/role/${MG_CERTS_OPENBAO_PKI_ROLE}/secret-id" {
capabilities = ["create", "update"]
}
path "auth/approle/role/${MG_CERTS_OPENBAO_PKI_ROLE}/secret-id-accessor/lookup" {
capabilities = ["create", "update"]
}
path "auth/approle/role/${MG_CERTS_OPENBAO_PKI_ROLE}/secret-id-accessor/destroy" {
capabilities = ["create", "update"]
}
EOF
bao policy write pki-policy /opt/openbao/config/pki-policy.hcl > /dev/null
}
# Check if we have pre-configured unseal keys and root token
if [ -n "$MG_CERTS_OPENBAO_UNSEAL_KEY_1" ] && [ -n "$MG_CERTS_OPENBAO_UNSEAL_KEY_2" ] && [ -n "$MG_CERTS_OPENBAO_UNSEAL_KEY_3" ] && [ -n "$MG_CERTS_OPENBAO_ROOT_TOKEN" ]; then
echo "Using pre-configured unseal keys and root token..."
bao server -config=/opt/openbao/config/config.hcl > /opt/openbao/logs/server.log 2>&1 &
BAO_PID=$!
wait_for_bao
unseal_bao "$MG_CERTS_OPENBAO_UNSEAL_KEY_1" "$MG_CERTS_OPENBAO_UNSEAL_KEY_2" "$MG_CERTS_OPENBAO_UNSEAL_KEY_3"
export BAO_TOKEN=$MG_CERTS_OPENBAO_ROOT_TOKEN
else
# Initialize OpenBao if not already done
if [ ! -f /opt/openbao/data/init.json ]; then
echo "Initializing OpenBao for the first time..."
bao server -config=/opt/openbao/config/config.hcl > /opt/openbao/logs/server.log 2>&1 &
BAO_PID=$!
wait_for_bao
# Initialize with 5 key shares and threshold of 3
bao operator init -key-shares=5 -key-threshold=3 -format=json > /opt/openbao/data/init.json
# Extract unseal keys and root token
UNSEAL_KEY_1=$(jq -r '.unseal_keys_b64[0]' /opt/openbao/data/init.json)
UNSEAL_KEY_2=$(jq -r '.unseal_keys_b64[1]' /opt/openbao/data/init.json)
UNSEAL_KEY_3=$(jq -r '.unseal_keys_b64[2]' /opt/openbao/data/init.json)
ROOT_TOKEN=$(jq -r '.root_token' /opt/openbao/data/init.json)
unseal_bao "$UNSEAL_KEY_1" "$UNSEAL_KEY_2" "$UNSEAL_KEY_3"
export BAO_TOKEN=$ROOT_TOKEN
echo "OpenBao initialized successfully!"
else
echo "OpenBao already initialized, starting server..."
bao server -config=/opt/openbao/config/config.hcl > /opt/openbao/logs/server.log 2>&1 &
BAO_PID=$!
wait_for_bao
# Check if OpenBao is sealed and unseal if necessary
if bao status -format=json | jq -e '.sealed == true' >/dev/null 2>&1; then
echo "OpenBao is sealed, unsealing..."
UNSEAL_KEY_1=$(jq -r '.unseal_keys_b64[0]' /opt/openbao/data/init.json)
UNSEAL_KEY_2=$(jq -r '.unseal_keys_b64[1]' /opt/openbao/data/init.json)
UNSEAL_KEY_3=$(jq -r '.unseal_keys_b64[2]' /opt/openbao/data/init.json)
unseal_bao "$UNSEAL_KEY_1" "$UNSEAL_KEY_2" "$UNSEAL_KEY_3"
echo "OpenBao unsealed successfully!"
else
echo "OpenBao is already unsealed!"
fi
ROOT_TOKEN=$(jq -r '.root_token' /opt/openbao/data/init.json)
export BAO_TOKEN=$ROOT_TOKEN
fi
fi
# Configure OpenBao PKI and AppRole if not already configured
if [ ! -f /opt/openbao/data/configured ]; then
echo "Configuring OpenBao PKI and AppRole..."
# Create namespace if specified
if [ -n "$MG_CERTS_OPENBAO_NAMESPACE" ]; then
if bao namespace create "$MG_CERTS_OPENBAO_NAMESPACE" 2>/tmp/ns_error; then
export BAO_NAMESPACE="$MG_CERTS_OPENBAO_NAMESPACE"
echo "$MG_CERTS_OPENBAO_NAMESPACE" > /opt/openbao/data/namespace
echo "Created namespace: $MG_CERTS_OPENBAO_NAMESPACE"
else
if grep -q "namespace already exists" /tmp/ns_error; then
export BAO_NAMESPACE="$MG_CERTS_OPENBAO_NAMESPACE"
echo "$MG_CERTS_OPENBAO_NAMESPACE" > /opt/openbao/data/namespace
echo "Using existing namespace: $MG_CERTS_OPENBAO_NAMESPACE"
else
echo "ERROR: Failed to create namespace $MG_CERTS_OPENBAO_NAMESPACE:" >&2
cat /tmp/ns_error >&2
exit 1
fi
fi
rm -f /tmp/ns_error
fi
# Enable authentication methods and secrets engines
if ! bao auth enable approle > /tmp/auth_success 2>/tmp/auth_error; then
if ! grep -q "already in use" /tmp/auth_error; then
echo "ERROR: Failed to enable AppRole auth method:" >&2
cat /tmp/auth_error >&2
exit 1
fi
echo "AppRole already enabled"
fi
rm -f /tmp/auth_error /tmp/auth_success
# Enable PKI secrets engine
if ! bao secrets enable -path=pki pki > /tmp/pki_success 2>/tmp/pki_error; then
# If the failure wasnt because the mount already exists, abort
if ! grep -q "already in use" /tmp/pki_error; then
echo "ERROR: Failed to enable PKI secrets engine:" >&2
cat /tmp/pki_error >&2
exit 1
fi
echo "PKI already enabled"
fi
rm -f /tmp/pki_error /tmp/pki_success
# Configure PKI engine
bao secrets tune -max-lease-ttl=87600h pki > /dev/null
# Validate required CA environment variables
for var in MG_CERTS_OPENBAO_PKI_CA_CN MG_CERTS_OPENBAO_PKI_CA_O MG_CERTS_OPENBAO_PKI_CA_C; do
eval "value=\$var"
if [ -z "$value" ]; then
echo "ERROR: Required environment variable $var is not set" >&2
exit 1
fi
done
PKI_CMD="bao write -field=certificate pki/root/generate/internal \
common_name=\"$MG_CERTS_OPENBAO_PKI_CA_CN\" \
organization=\"$MG_CERTS_OPENBAO_PKI_CA_O\" \
country=\"$MG_CERTS_OPENBAO_PKI_CA_C\" \
ttl=87600h \
key_bits=2048 \
exclude_cn_from_sans=false"
[ -n "$MG_CERTS_OPENBAO_PKI_CA_OU" ] && PKI_CMD="$PKI_CMD ou=\"$MG_CERTS_OPENBAO_PKI_CA_OU\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_L" ] && PKI_CMD="$PKI_CMD locality=\"$MG_CERTS_OPENBAO_PKI_CA_L\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_ST" ] && PKI_CMD="$PKI_CMD province=\"$MG_CERTS_OPENBAO_PKI_CA_ST\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_ADDR" ] && PKI_CMD="$PKI_CMD street_address=\"$MG_CERTS_OPENBAO_PKI_CA_ADDR\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_PO" ] && PKI_CMD="$PKI_CMD postal_code=\"$MG_CERTS_OPENBAO_PKI_CA_PO\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_DNS_NAMES" ] && PKI_CMD="$PKI_CMD alt_names=\"$MG_CERTS_OPENBAO_PKI_CA_DNS_NAMES\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_IP_ADDRESSES" ] && PKI_CMD="$PKI_CMD ip_sans=\"$MG_CERTS_OPENBAO_PKI_CA_IP_ADDRESSES\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_URI_SANS" ] && PKI_CMD="$PKI_CMD uri_sans=\"$MG_CERTS_OPENBAO_PKI_CA_URI_SANS\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_EMAIL_ADDRESSES" ] && PKI_CMD="$PKI_CMD email_sans=\"$MG_CERTS_OPENBAO_PKI_CA_EMAIL_ADDRESSES\""
eval $PKI_CMD > /dev/null
if [ $? -eq 0 ]; then
echo "OpenBao root CA certificate generated successfully!"
else
echo "ERROR: Failed to generate OpenBao root CA certificate" >&2
exit 1
fi
if ! bao secrets enable -path=pki_int pki > /tmp/pki_int_success 2>/tmp/pki_int_error; then
if ! grep -q "already in use" /tmp/pki_int_error; then
echo "ERROR: Failed to enable intermediate PKI secrets engine:" >&2
cat /tmp/pki_int_error >&2
exit 1
fi
echo "Intermediate PKI already enabled"
fi
rm -f /tmp/pki_int_error /tmp/pki_int_success
bao secrets tune -max-lease-ttl=8760h pki_int > /dev/null
INTERMEDIATE_CN="${MG_CERTS_OPENBAO_PKI_CA_CN} Intermediate"
INTERMEDIATE_CSR_CMD="bao write -field=csr pki_int/intermediate/generate/internal \
common_name=\"$INTERMEDIATE_CN\" \
organization=\"$MG_CERTS_OPENBAO_PKI_CA_O\" \
country=\"$MG_CERTS_OPENBAO_PKI_CA_C\" \
ttl=8760h \
key_bits=2048"
[ -n "$MG_CERTS_OPENBAO_PKI_CA_OU" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD ou=\"$MG_CERTS_OPENBAO_PKI_CA_OU\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_L" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD locality=\"$MG_CERTS_OPENBAO_PKI_CA_L\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_ST" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD province=\"$MG_CERTS_OPENBAO_PKI_CA_ST\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_ADDR" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD street_address=\"$MG_CERTS_OPENBAO_PKI_CA_ADDR\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_PO" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD postal_code=\"$MG_CERTS_OPENBAO_PKI_CA_PO\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_DNS_NAMES" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD alt_names=\"$MG_CERTS_OPENBAO_PKI_CA_DNS_NAMES\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_IP_ADDRESSES" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD ip_sans=\"$MG_CERTS_OPENBAO_PKI_CA_IP_ADDRESSES\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_URI_SANS" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD uri_sans=\"$MG_CERTS_OPENBAO_PKI_CA_URI_SANS\""
[ -n "$MG_CERTS_OPENBAO_PKI_CA_EMAIL_ADDRESSES" ] && INTERMEDIATE_CSR_CMD="$INTERMEDIATE_CSR_CMD email_sans=\"$MG_CERTS_OPENBAO_PKI_CA_EMAIL_ADDRESSES\""
INTERMEDIATE_CSR=$(eval $INTERMEDIATE_CSR_CMD)
if [ $? -ne 0 ] || [ -z "$INTERMEDIATE_CSR" ]; then
echo "ERROR: Failed to generate intermediate CA CSR" >&2
exit 1
fi
echo "Intermediate CA CSR generated successfully!"
INTERMEDIATE_CERT=$(bao write -field=certificate pki/root/sign-intermediate \
csr="$INTERMEDIATE_CSR" \
format=pem_bundle \
ttl=8760h \
use_csr_values=true)
if [ $? -ne 0 ] || [ -z "$INTERMEDIATE_CERT" ]; then
echo "ERROR: Failed to sign intermediate CA certificate" >&2
exit 1
fi
echo "Intermediate CA certificate signed successfully!"
bao write pki/config/urls \
issuing_certificates='http://127.0.0.1:8200/v1/pki/ca' \
crl_distribution_points='http://127.0.0.1:8200/v1/pki/crl' \
ocsp_servers='http://127.0.0.1:8200/v1/pki/ocsp' > /dev/null
bao write pki_int/config/urls \
issuing_certificates='http://127.0.0.1:8200/v1/pki_int/ca' \
crl_distribution_points='http://127.0.0.1:8200/v1/pki_int/crl' \
ocsp_servers='http://127.0.0.1:8200/v1/pki_int/ocsp' > /dev/null
bao write pki_int/intermediate/set-signed certificate="$INTERMEDIATE_CERT" > /dev/null
if [ $? -eq 0 ]; then
echo "Intermediate CA setup completed successfully!"
else
echo "ERROR: Failed to set signed intermediate certificate" >&2
exit 1
fi
echo "$INTERMEDIATE_CERT" > /opt/openbao/data/intermediate_ca.pem
ROLE_CMD="bao write pki_int/roles/${MG_CERTS_OPENBAO_PKI_ROLE} \
allow_any_name=true \
enforce_hostnames=false \
allow_ip_sans=true \
allow_localhost=true \
allow_bare_domains=true \
allow_subdomains=true \
allow_glob_domains=true \
allowed_domains=\"*\" \
allowed_uri_sans=\"*\" \
allowed_other_sans=\"*\" \
server_flag=true \
client_flag=true \
code_signing_flag=false \
email_protection_flag=false \
key_type=rsa \
key_bits=2048 \
key_usage=\"DigitalSignature,KeyEncipherment,KeyAgreement\" \
ext_key_usage=\"ServerAuth,ClientAuth,OCSPSigning\" \
use_csr_common_name=true \
use_csr_sans=true \
basic_constraints_valid_for_non_ca=true \
max_ttl=720h \
ttl=720h"
eval "$ROLE_CMD" > /dev/null
create_pki_policy
# Create AppRole
SECRET_ID_TTL="${MG_CERTS_OPENBAO_SECRET_ID_TTL}"
bao write auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}" \
token_policies=pki-policy \
token_ttl=1h \
token_max_ttl=4h \
bind_secret_id=true \
secret_id_ttl="$SECRET_ID_TTL" > /dev/null
# Set custom role ID if provided
if [ -n "$MG_CERTS_OPENBAO_APP_ROLE" ]; then
bao write auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}"/role-id role_id="$MG_CERTS_OPENBAO_APP_ROLE" > /dev/null
fi
# Set custom secret ID if provided, otherwise generate one
if [ -n "$MG_CERTS_OPENBAO_APP_SECRET" ]; then
bao write auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}"/custom-secret-id secret_id="$MG_CERTS_OPENBAO_APP_SECRET" > /dev/null
echo "$MG_CERTS_OPENBAO_APP_SECRET" > /opt/openbao/data/secret_id
else
GENERATED_SECRET_ID=$(bao write -field=secret_id -force auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}"/secret-id)
echo "$GENERATED_SECRET_ID" > /opt/openbao/data/secret_id
fi
# Generate service token for additional access
SERVICE_TOKEN=$(bao write -field=token auth/token/create \
policies=pki-policy \
ttl=24h \
renewable=true \
display_name="certs-service" 2>/dev/null)
echo "SERVICE_TOKEN=$SERVICE_TOKEN" > /opt/openbao/data/service_token
# Mark configuration as complete
touch /opt/openbao/data/configured
echo "OpenBao configuration completed successfully!"
else
echo "OpenBao already configured, verifying and updating configuration..."
# Restore namespace if it exists
if [ -f /opt/openbao/data/namespace ] && [ -n "$MG_CERTS_OPENBAO_NAMESPACE" ]; then
SAVED_NAMESPACE=$(cat /opt/openbao/data/namespace)
if [ "$SAVED_NAMESPACE" = "$MG_CERTS_OPENBAO_NAMESPACE" ]; then
export BAO_NAMESPACE="$MG_CERTS_OPENBAO_NAMESPACE"
fi
fi
# Check if AppRole role exists, create if missing
if ! bao read auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}" > /dev/null 2>&1; then
if ! bao auth enable approle > /tmp/auth_success 2>/tmp/auth_error; then
if ! grep -q "already in use" /tmp/auth_error; then
echo "ERROR: Failed to enable AppRole auth method:" >&2
cat /tmp/auth_error >&2
exit 1
fi
fi
rm -f /tmp/auth_error /tmp/auth_success
create_pki_policy
SECRET_ID_TTL="${MG_CERTS_OPENBAO_SECRET_ID_TTL}"
bao write auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}" \
token_policies=pki-policy \
token_ttl=1h \
token_max_ttl=4h \
bind_secret_id=true \
secret_id_ttl="$SECRET_ID_TTL" > /dev/null
if [ -n "$MG_CERTS_OPENBAO_APP_ROLE" ]; then
bao write auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}"/role-id role_id="$MG_CERTS_OPENBAO_APP_ROLE" > /dev/null
fi
fi
SECRET_ID_VALID=false
if [ -n "$MG_CERTS_OPENBAO_APP_SECRET" ]; then
if bao write -field=client_token auth/approle/login role_id="$MG_CERTS_OPENBAO_APP_ROLE" secret_id="$MG_CERTS_OPENBAO_APP_SECRET" > /dev/null 2>&1; then
SECRET_ID_VALID=true
echo "$MG_CERTS_OPENBAO_APP_SECRET" > /opt/openbao/data/secret_id
fi
elif [ -f /opt/openbao/data/secret_id ]; then
STORED_SECRET_ID=$(cat /opt/openbao/data/secret_id)
if [ -n "$STORED_SECRET_ID" ]; then
ROLE_ID=$(bao read -field=role_id auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}"/role-id)
if bao write -field=client_token auth/approle/login role_id="$ROLE_ID" secret_id="$STORED_SECRET_ID" > /dev/null 2>&1; then
SECRET_ID_VALID=true
fi
fi
fi
if [ "$SECRET_ID_VALID" = "false" ]; then
NEW_SECRET_ID=$(bao write -field=secret_id -force auth/approle/role/"${MG_CERTS_OPENBAO_PKI_ROLE}"/secret-id)
if [ -z "$NEW_SECRET_ID" ]; then
echo "ERROR: Failed to generate new secret ID" >&2
else
echo "$NEW_SECRET_ID" > /opt/openbao/data/secret_id
echo "Generated new secret ID for certs service"
fi
fi
# Regenerate service token
SERVICE_TOKEN=$(bao write -field=token auth/token/create \
policies=pki-policy \
ttl=24h \
renewable=true \
display_name="certs-service" 2>/dev/null)
if [ -n "$SERVICE_TOKEN" ]; then
echo "SERVICE_TOKEN=$SERVICE_TOKEN" > /opt/openbao/data/service_token
fi
fi
echo "================================"
echo "OpenBao Production Setup Complete"
echo "================================"
echo "OpenBao Address: http://localhost:8200"
echo "UI Available at: http://localhost:8200/ui"
echo "================================"
echo "IMPORTANT: Store the init.json file securely!"
echo "It contains unseal keys and root token!"
echo "================================"
echo "OpenBao is ready for certs service on port 8200"
if [ -n "$BAO_PID" ]; then
wait $BAO_PID
else
echo "ERROR: OpenBao server process ID not available" >&2
exit 1
fi