Learn Secret Management - Integrating OpenBao with Web Applications
Episode 10 of 21

Learn Secret Management - Integrating OpenBao with Web Applications

Connecting web applications to OpenBao through two approaches: direct integration with the REST API and programming language client libraries using AppRole, or indirect integration by injecting secrets into the environment without changing source code.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

So far all the discussion has centered on the OpenBao server: engines, policies, auth methods, and leases. Episode 10 brings secrets out of the server and into the web applications that actually use them — Node.js, Go, Python, and Laravel. There are two main paths: direct integration where application code requests secrets itself, and indirect integration where secrets are injected from outside. You will see that both have their place.

Two Integration Paths

Before going into detail, compare the two approaches:

AspectDirect IntegrationIndirect Integration
Source code changesRequiredNot required
Secret sourceREST API / client libraryEnvironment / file
Application controlFull, dynamicLimited, static at startup
Token managementApplication holds the tokenExternal party (agent or deploy)
Best forNew applications, microservicesLegacy applications, need speed to be secure

Direct integration gives full flexibility — the application can fetch secrets at any time, even right before use. Indirect integration solves the problem quickly without touching code, but secrets are only populated once when the process starts.

Direct Integration with the REST API

At its core, OpenBao is an HTTP server. Every interaction can be done through the REST API with endpoints prefixed http://127.0.0.1:8200/v1/ and the token sent via the X-Vault-Token header. Example of reading a secret:

Access a secret via the REST API
curl --header "X-Vault-Token: s.xxxxx" \
  http://127.0.0.1:8200/v1/secret/data/app

The complete flow: the application logs in (for example via AppRole) to get a token, then uses that token in the X-Vault-Token header on every request. The secret value is returned as JSON — easy to parse in any language. curl --header "X-Vault-Token: s.xxxxx" http://127.0.0.1:8200/v1/secret/data/app is the heart of direct integration.

Client Libraries per Language

Rather than hand-crafting raw HTTP requests, most languages have client libraries that hide the REST API behind simple functions:

LanguageLibrary
Node.jsnode-vault or the official Vault JavaScript client
Gogithub.com/hashicorp/vault/api
Pythonhvac
Laravel (PHP)hashicorp/vault-php or the direct REST API

A short example using node-vault in Node.js:

Read a secret with node-vault
const vault = require("node-vault")({
  endpoint: "http://127.0.0.1:8200",
  token: "s.xxxxx"
});
 
const result = await vault.read("secret/data/app");
console.log(result.data.data);

The same pattern applies in Go with vault.NewClient, in Python with an hvac.Client session, and in Laravel via a service provider wrapping hashicorp/vault-php. Behind the scenes, all of these clients call the same REST API — so the concepts of X-Vault-Token and v1/... paths still apply.

Direct Integration via AppRole

Because applications have no human to log in with, the AppRole credentials from episode 8 are the standard choice. The sequence:

AppRole login from an application
bao write auth/approle/login \
  role_id="9c1f..." \
  secret_id="d4a8..."

The login response contains a token whose TTL is set by the role (token_ttl). The application stores that token in memory, uses it to read secrets, and refreshes it before the TTL expires. The AppRole plus client library combination is the most common pattern for microservices — and it is a full example of direct integration.

Indirect Integration

Sometimes the application cannot be changed — whether it is legacy, closed-source, or the team simply doesn't have time. For this case, injecting secrets into the environment is the answer. The principle is simple: secrets are fetched from OpenBao outside the application, then injected as environment variables or a file when the application starts.

Example of an injection result into a .env file:

Linux.env injection result
DB_USER=postgres
DB_PASSWORD=hVt3-9xK2mP
API_KEY=zlQ7-wR4bNc1

The application only needs to read process.env.DB_PASSWORD or getenv("DB_USER") as usual — it never knows OpenBao exists. This path is used by deployment tools, init scripts, orchestrators, and (as we will see in the next episode) the OpenBao Agent.

Note

Environment injection solves "where do secrets come from", but not yet "who keeps secrets fresh". Injected secrets stay alive until the process is restarted — for automatic rotation, the next step is the agent you will learn about in episode 11.

Choosing a Path Based on Conditions

The two paths are not a competition — they complement each other and are chosen based on conditions:

  • The team owns the source code and needs dynamic secrets — choose direct integration; the application fetches new credentials whenever needed.
  • The source code cannot be changed in the near term — choose indirect integration; env injection solves today's problem.
  • A new microservice is born — start with direct integration using AppRole and a client library for automatic credential rotation.
  • The team has a small workload — indirect integration reduces the code to maintain, especially if later automated by an agent.

The simple guideline: the more dynamic the secret needs, the more worthwhile direct integration; the more legacy applications there are, the more sense the indirect path makes.

Conclusion

In this episode 10 you connected web applications to OpenBao through two paths: direct integration using the v1/... REST API with the X-Vault-Token header and client libraries for Node.js, Go, Python, and Laravel via AppRole; and indirect integration that injects secrets into the environment without touching source code.

Key takeaways:

  • The REST API is the foundation — every client library calls the same v1/... endpoints.
  • AppRole is the application's entrance — role_id and secret_id, with short-TTL tokens.
  • Choose according to team capability — direct for full control, indirect for speed.
  • Env injection only refreshes on restart — dynamic rotation needs the next layer.

In the next episode, episode 11, that layer arrives: the OpenBao Agent — a daemon that logs in on its own, renews tokens, and renders application configuration files automatically through templates.

Learn Secret Management - Integrating OpenBao with Web Applications | Learn Secret Management with OpenBao