Credential Brokering and Vault Integration¶
One of Boundary's killer features is dynamic credential management during sessions. Instead of giving users long-lived SSH keys or database passwords, Boundary can fetch short-lived credentials from Vault at session time, pass them to the user (brokering) or use them on the user's behalf without exposing them (injection), and revoke them when the session ends.
Concepts¶
- Credential Store: the source of credentials (static or Vault)
- Credential Library (Vault only): a specific query against the credential store (e.g., a Vault path to read)
- Credential: the actual value; static or produced by a library
- Attachment: credentials or libraries are attached to targets as brokered or injected
Static Credential Store (csst_)¶
Credentials are stored directly in Boundary (encrypted at rest via KMS).
boundary credential-stores create static \
-scope-id=p_... \
-name=local-creds
Create credentials:
boundary credentials create username-password \
-credential-store-id=csst_... \
-username=admin \
-password=s3cret \
-name=admin-creds
boundary credentials create ssh-private-key \
-credential-store-id=csst_... \
-username=ubuntu \
-private-key=file:///path/to/key \
-name=ssh-key
boundary credentials create json \
-credential-store-id=csst_... \
-object file://./creds.json
Static stores are appropriate for:
- Credentials that don't change often
- Bootstrap scenarios (before Vault integration)
- Small deployments
For real secret management, prefer Vault.
Vault Credential Store (csvlt_)¶
Boundary integrates with Vault to fetch credentials dynamically.
Setup¶
- In Vault, configure the secrets engines Boundary will read from (database, ssh, kv, etc.).
- Create a Vault policy granting read access to those paths.
- Create a Vault token tied to that policy (ideally a periodic token or use AppRole/JWT).
- In Boundary, create the credential store:
boundary credential-stores create vault \
-scope-id=p_... \
-vault-address=https://vault.example.com:8200 \
-vault-token=s.abc123 \
-name=vault-store \
-vault-namespace=platform
Credential Libraries¶
A library defines a specific credential type and path:
boundary credential-libraries create vault-generic \
-credential-store-id=csvlt_... \
-vault-path="database/creds/readonly" \
-name=db-readonly
Library types:
vault-generic: any Vault read returns a credentialvault-ssh-certificate: use Vault's SSH CA to sign a cert for the session
For SSH cert libraries:
boundary credential-libraries create vault-ssh-certificate \
-credential-store-id=csvlt_... \
-vault-path="ssh/sign/admin" \
-username=admin \
-name=ssh-signed \
-additional-valid-principals=ubuntu
Attaching to Targets¶
Brokered (client sees credentials):
boundary targets add-credential-sources \
-id=ttcp_... \
-brokered-credential-source=clvlt_...
Injected (client does not see credentials, SSH targets only):
boundary targets add-credential-sources \
-id=tssh_... \
-injected-application-credential-source=clvlt_...
Brokering vs Injection¶
Brokering¶
- User requests session
- Boundary fetches credential from Vault
- Boundary passes credential to the client via session response
- Client uses credential to auth to the target
- Session ends; Boundary revokes the Vault lease
The user sees the credential. Suitable when the client tool needs the credential to function (database CLI, custom app).
Injection¶
- User requests session
- Boundary fetches credential from Vault
- Worker uses credential during the SSH handshake with the target
- Client proxy transparently passes through
- User never sees the credential
- Session ends; Vault lease revoked
The user cannot exfiltrate the credential. Suitable for SSH where admin ops are the goal but the user doesn't need the key.
Injection is SSH-only. TCP targets cannot inject because the protocol is opaque to the worker.
Vault Policy Example for Boundary¶
# Read database dynamic creds
path "database/creds/readonly" {
capabilities = ["read"]
}
# Sign SSH certs
path "ssh/sign/admin" {
capabilities = ["create", "update"]
}
# Read static KV
path "kv/data/apps/myapp" {
capabilities = ["read"]
}
# Revoke leases Boundary owns
path "sys/leases/revoke" {
capabilities = ["update"]
}
Attach to a token or AppRole used by Boundary's credential store.
Lease Management¶
When Boundary uses Vault credentials, Vault creates a lease. Boundary records the lease ID. On session termination, Boundary calls Vault's revoke endpoint, invalidating the credential immediately.
If the lease expires before session termination (TTL shorter than session), the credential stops working mid-session. Configure TTLs to be at least as long as session max duration.
Common Credential Flows¶
Dynamic PostgreSQL Password (Brokered)¶
- Vault's database secrets engine creates a user in PostgreSQL with TTL 1h
- Boundary brokers username/password to client
- Client uses psql with those credentials
- Session ends, Boundary revokes, PostgreSQL user is dropped
Signed SSH Certificate (Injected)¶
- User has an SSH public key (or Boundary generates one)
- Vault's SSH CA signs a cert with TTL 1h, principals constrained to
admin - Worker uses signed cert to SSH into target
- User sees only the resulting shell, not the cert or private key
- Session ends, lease revoked
Static KV Password (Brokered)¶
- Vault stores a service account password at
kv/data/apps/myapp - Boundary reads on session request, brokers to client
- Client uses credentials
Useful when true dynamic creds aren't possible (shared service account).
Credential Types¶
Boundary recognizes several credential subtypes:
- username-password: two-field structure
- ssh-private-key: username + private key + optional passphrase
- json: arbitrary JSON blob; client parses
Vault libraries return any of these based on the response shape or configuration.
Error Handling¶
Common failures:
- Vault token expired: credential store can't fetch; sessions fail to authorize with credentials. Use periodic tokens or auto-rotation.
- Policy missing: Boundary gets 403 from Vault; session fails.
- Lease revoke fails: rare; verify Boundary's token has
sys/leases/revoke. - Target rejects credential: fresh credential is valid but target not configured (e.g., CA trust not established).
Inspect via boundary sessions read -id=s_... and Vault's audit log.
Credential Rotation for Boundary's Own Token¶
Boundary's token into Vault is itself a credential. Best practices:
- Use Vault AppRole or JWT auth so Boundary gets short-lived tokens
- Rotate periodically via automation
- Tie the token's TTL to rotation cadence
- Audit Vault access per Boundary credential store
If a token expires mid-flight, Boundary will fail to fetch credentials until renewed.
HCP Boundary and HCP Vault¶
HCP Boundary integrates seamlessly with HCP Vault. Use HCP Vault's AppRole auth with Boundary; configure through the HCP UI. Eliminates token-management overhead.
Terraform Example¶
resource "boundary_credential_store_vault" "main" {
name = "prod-vault"
scope_id = boundary_scope.project.id
address = "https://vault.example.com:8200"
token = var.vault_boundary_token
namespace = "platform"
}
resource "boundary_credential_library_vault" "db_readonly" {
name = "db-readonly"
credential_store_id = boundary_credential_store_vault.main.id
path = "database/creds/readonly"
http_method = "GET"
credential_type = "username_password"
}
resource "boundary_target" "postgres" {
type = "tcp"
name = "postgres-prod"
scope_id = boundary_scope.project.id
default_port = 5432
brokered_credential_source_ids = [
boundary_credential_library_vault.db_readonly.id,
]
}
Security Considerations¶
- Always use sensitive-variable handling for the Vault token
- Scope Vault policies tightly (no wildcards unless needed)
- Prefer injection over brokering when possible
- Set short Vault TTLs; let leases naturally limit exposure
- Log and monitor credential-store creation and rotation
Exam-Ready Checklist¶
- Can explain brokering vs injection and which target types support each
- Can create a Vault credential store and library via CLI
- Know credential types (username-password, ssh-private-key, json)
- Understand Vault lease lifecycle with sessions
- Can write a minimal Vault policy for Boundary
- Know SSH-certificate library vs generic library use cases