This guide covers the setup, configuration, and end-to-end usage of HashiCorp Vault for credential resolution in Docling Pipelines.
In enterprise pipelines, operators often require credentials such as database passwords, API tokens, or cloud storage keys. Hardcoding credentials in flow definitions risks exposure in version control and shared databases.
The HashiCorp Vault integration replaces cleartext credentials in flow definitions with immutable vault:// URIs:
vault:// pointers without masking them as ********.graph TD
A[Web UI / Flow JSON] -->|vault:// URI| B[REST API / Storage]
B -->|Flow JSON| C[Flow Validator]
C -->|Dry-run Sanitization| D[Python Orchestrator]
D -->|Resolve URIs| E[HashiCorpVault Provider]
E -->|AppRole or Token| F[(HashiCorp Vault)]
F -->|Decrypted Secret| E
E -->|Transient Memory Config| G[Operator Instance]
G -->|Execute Pipeline| H[External Service / Storage]
FlowValidator detects vault:// strings on sensitive fields and substitutes valid mock types so validation succeeds without querying Vault.PythonOperatorExecutor scans the operator configuration, identifies vault:// patterns, and resolves each reference via SecretProvider.vault://<provider>/<secret_path>#<field_key>
<provider>: Registered provider name (e.g., hashicorp).<secret_path>: Vault KV v2 path (e.g., docpipe/s3 or secret/data/docpipe/s3).#<field_key>: Target key in the secret’s data map (e.g., #access_key).Store each credential as an individual key-value pair in Vault. Recommended for standard credentials:
Vault Secret Data (secret/docpipe/openai):
{
"api_key": "<API_KEY>"
}
Flow JSON:
{
"type": "embeddings",
"name": "embeddings_node",
"config": {
"provider": "openai",
"provider_config": {
"api_key": "vault://hashicorp/docpipe/openai#api_key" # pragma: allowlist secret
}
}
}
For complex or multi-parameter credentials (e.g. cloud service accounts or full connection credential blocks), store the entire credential dictionary as a serialized JSON string in Vault.
Docpipe automatically parses the resolved string into a dictionary if the target configuration field expects an object:
Vault Secret Data (secret/docpipe/storage_full):
{
"connection_creds": "{\"client_id\": \"<CLIENT_ID>\", \"region\": \"us-east-1\"}"
}
Flow JSON:
{
"type": "storage_output",
"name": "s3_export",
"config": {
"destination_type": "s3",
"destination_config": {
"bucket_name": "pipeline-results",
"credentials": "vault://hashicorp/docpipe/s3_full#connection_creds"
}
}
}
| Operator | Config Path | Description |
|---|---|---|
ingest_source |
connection_params.access_key |
S3 / Cloud access key |
connection_params.secret_key |
S3 / Cloud secret key | |
connection_params.credentials |
Full credential dictionary or JSON string | |
connection_params.client_secret |
SharePoint / OAuth client secret | |
embeddings |
provider_config.api_key |
LLM / Embedding provider API key |
extract_operator |
llm_config.api_key |
Extraction LLM provider API key |
entity_extraction.api_key |
Entity extraction LLM API key | |
document_classifier |
provider_config.api_key |
Classification LLM provider API key |
vectordb |
provider_config.username |
OpenSearch / Milvus username |
provider_config.password |
OpenSearch / Milvus password | |
provider_config.api_key |
Vector DB API token | |
storage_output |
destination_config.credentials |
Full credential dictionary or JSON string |
destination_config.provider_config.access_key |
Destination S3 access key | |
destination_config.provider_config.secret_key |
Destination S3 secret key | |
destination_config.provider_config.client_secret |
Destination SharePoint secret |
docling-pipelines-config.yaml)Configure Vault under the secrets section:
secrets:
vault:
enabled: true
provider: hashicorp
url: "http://127.0.0.1:8200"
mount_point: "secret"
auth_method: "approle" # "approle" (production) or "token" (dev/testing)
role_id: "" # or set VAULT_ROLE_ID env var
secret_id: "" # or set VAULT_SECRET_ID env var
token: "" # or set VAULT_TOKEN env var (if auth_method is token)
timeout: 30
auth_method: approle): Recommended for production services. Uses role_id and secret_id to acquire tokens with automatic lifecycle renewal.auth_method: token): Recommended for local testing. Pass a developer or service token directly.Environment variables override file configuration:
| Variable | Description | Default |
|---|---|---|
VAULT_ENABLED |
Enables secret provider when true |
false |
VAULT_PROVIDER |
Provider identifier in vault:// URIs |
hashicorp |
VAULT_ADDR / VAULT_URL |
HashiCorp Vault address | http://127.0.0.1:8200 |
VAULT_MOUNT_POINT |
KV v2 mount point | secret |
VAULT_AUTH_METHOD |
Authentication mode (approle or token) |
approle |
VAULT_ROLE_ID |
AppRole Role ID | "" |
VAULT_SECRET_ID |
AppRole Secret ID | "" |
VAULT_TOKEN |
Token for token-based auth | "" |
VAULT_TIMEOUT |
Request timeout in seconds | 30 |
Using Docker or Podman:
docker run -d \
--name vault-server \
-p 8200:8200 \
-e 'VAULT_DEV_ROOT_TOKEN_ID=dev-root-token' \
-e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \
docker.io/hashicorp/vault:1.17 server -dev
export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN="dev-root-token"
vault secrets enable -version=2 -path=secret kv || true
# Store API key for embeddings operator
vault kv put secret/docpipe/embeddings api_key="<YOUR_EMBEDDINGS_API_KEY>" # pragma: allowlist secret
# Store credentials for vectordb operator
vault kv put secret/docpipe/opensearch \
username="<YOUR_DB_USERNAME>" \
password="<YOUR_DB_PASSWORD>" # pragma: allowlist secret
# Enable AppRole
vault auth enable approle
# Create read policy
cat << 'EOF' > docpipe-read.hcl
path "secret/data/docpipe/*" {
capabilities = ["read"]
}
EOF
vault policy write docpipe-read docpipe-read.hcl
# Create AppRole
vault write auth/approle/role/docpipe-role \
secret_id_ttl=0 \
token_num_uses=0 \
token_ttl=1h \
token_max_ttl=24h \
token_policies="docpipe-read"
# Fetch credentials
export VAULT_ROLE_ID=$(vault read -format=json auth/approle/role/docpipe-role/role-id | jq -r .data.role_id)
export VAULT_SECRET_ID=$(vault write -f -format=json auth/approle/role/docpipe-role/secret-id | jq -r .data.secret_id)
Configure docpipe environment variables:
export VAULT_ENABLED=true
export VAULT_AUTH_METHOD=approle
export VAULT_ROLE_ID="$VAULT_ROLE_ID"
export VAULT_SECRET_ID="$VAULT_SECRET_ID"
# Validate flow DAG without exposing credentials
docling-pipelines --flow-file path/to/flow.json --validate
# Execute flow with dynamic Vault resolution
docling-pipelines --flow-file path/to/flow.json
The web UI canvas provides interactive support for vault:// URIs through the VaultInput component in operator properties panels.
vault://hashicorp/ prefix; you enter only the path and key (e.g., docpipe/opensearch#password).vault:// URIs leaves the reference intact when saved.FlowValidator):
Sensitive fields containing vault:// strings are replaced in-memory with mock values during schema verification. If Vault is not configured in the environment, a non-blocking warning is emitted.FlowMapper):
Standard plain passwords in flow definitions are masked as ******** when returned from API endpoints (GET /api/v1/flows). vault:// URIs are preserved unmasked for UI round-tripping.['provider_config.username', 'provider_config.password']), never the secrets themselves.| Symptom | Cause | Solution |
|---|---|---|
Cannot connect to Vault at http://127.0.0.1:8200 |
Vault server unreachable | Verify Vault is running (curl $VAULT_ADDR/v1/sys/health) |
Key 'api_key' not found at vault path 'docpipe/embeddings' |
Secret key name or path mismatch | Check secret contents with vault kv get secret/docpipe/embeddings |
VAULT_URI_MALFORMED |
URI missing provider or key | Follow vault://<provider>/<path>#<key> format |
Unregistered vault provider 'hashicorp' |
Vault provider not enabled | Set VAULT_ENABLED=true or update docling-pipelines-config.yaml |
'str' object is not a mapping |
Complex field expected JSON object | Ensure the Vault secret field contains a valid JSON string or dictionary |