Store and retrieve API keys with AES-256 encryption and per-agent SPIFFE identity scoping. No secrets in environment variables, logs, or shared config.
Environment variables are the most common way to pass secrets to AI agents, but they’re shared across all processes in a container, visible in logs, and manually rotated. Hexr Vault replaces them with identity-scoped secrets: each secret is encrypted at rest with AES-256-GCM, and access is gated by the requesting agent’s SPIFFE identity. A researcher role cannot read secrets scoped to a writer role — even if they’re in the same agent. This guide shows you how to store, retrieve, and scope secrets using the Hexr Vault client.
Replace environment variable lookups with VaultClient. Secrets are encrypted at rest and scoped to your agent’s SPIFFE identity:
my_agent.py
from hexr import hexr_agentfrom hexr.vault import VaultClient@hexr_agent(name="my-agent", tenant="acme-corp")def main(): vault = VaultClient() # Store a secret (encrypted at rest, scoped to this agent) vault.put("OPENAI_API_KEY", "sk-...") # Retrieve it key = vault.get("OPENAI_API_KEY")
2
Inject secrets as function parameters (optional)
Use the @secrets_batch decorator to inject secrets directly into your function signature — no VaultClient calls needed in your business logic:
my_agent.py
from hexr import hexr_agentfrom hexr.vault import secrets_batch@hexr_agent(name="my-agent", tenant="acme-corp")@secrets_batch(["OPENAI_API_KEY", "ANTHROPIC_API_KEY"])def main(OPENAI_API_KEY: str, ANTHROPIC_API_KEY: str): # Secrets injected as function parameters print(f"OpenAI key starts with: {OPENAI_API_KEY[:8]}...")
3
Scope secrets to specific roles (optional)
In multi-role agents, you can restrict secrets to the role that needs them. A role that doesn’t own a secret receives an access denied error:
scoped_secrets.py
# Agent-level: all processes in this agent can accessvault.put("SHARED_KEY", "value")# Stored with scope: spiffe://hexr.cloud/agent/acme/my-agent/*# Process-level: only the researcher process can accessvault.put("RESEARCH_DB_KEY", "value", scope="researcher")# Stored with scope: spiffe://hexr.cloud/agent/acme/my-agent/researcher
A writer process trying to read RESEARCH_DB_KEY will receive an access denied error.
Never log or print secret values returned from vault.get(). The Vault client intentionally withholds values from traces and spans, but your application code is responsible for not exposing them.