← Back to Agent Auth Overview

Vault Integration

Store, retrieve, and audit secrets for agents. Keys never exposed to agent code.

Why Vault?

  • No keys in code — Secrets never exposed to agents
  • Scoped access — Read-only, write-only, or custom scopes
  • Full audit — Every access logged with agent DID
  • Easy revocation — One API call to invalidate
  • Ed25519 signing — No bearer tokens, just signatures

Before vs After

javascript
// Before: API keys in environment variables
// - Anyone with env access can see the key
// - No audit trail of who used it
// - Revocation requires code deploy
OPENAI_API_KEY="sk-..."
ANTHROPIC_API_KEY="sk-ant..."
// After: Vault with scoped secrets
// - Keys never exposed to agent code
// - Every access logged with agent DID
// - Revoke with one API call
const secret = await vault.getSecret("openai-api-key");
// Agent gets scoped token, not the actual key

Store a Secret

Create a scoped secret. The agent receives a token, never the raw key.

TypeScript

typescript
import { NervePay } from "@nervepay/sdk";
const client = new NervePay({
agentDid: "did:nervepay:agent:ABC123...",
privateKey: process.env.AGENT_PRIVATE_KEY!
});
// Store a scoped secret
const secret = await client.vault.createSecret({
name: "openai-api-key",
value: process.env.OPENAI_API_KEY,
scope: "read", // Agent can only READ, not write or delete
ttl: 86400 // 24 hour TTL
});
console.log("Secret stored:", secret.id);
// Agent gets back a scoped token, not the raw key

Python

python
from nervepay import NervePay
import os
client = NervePay(
agent_did="did:nervepay:agent:ABC123...",
private_key=os.environ["AGENT_PRIVATE_KEY"]
)
# Store a scoped secret
secret = client.vault.create_secret(
name="openai-api-key",
value=os.environ["OPENAI_API_KEY"],
scope="read",
ttl=86400
)
print(f"Secret stored: {secret['id']}")

Retrieve a Secret

Agents request secrets. Scope determines what they can access.

TypeScript

typescript
import { NervePay } from "@nervepay/sdk";
const client = new NervePay({
agentDid: "did:nervepay:agent:ABC123...",
privateKey: process.env.AGENT_PRIVATE_KEY!
});
// Retrieve with scope check
const secret = await client.vault.getSecret("openai-api-key");
// If agent has "read" scope, they get the value
// If scope is "none", they get an error
if (secret.accessible) {
console.log("API Key:", secret.value);
} else {
console.log("Access denied - insufficient scope");
}

Python

python
import os
from nervepay import NervePay
client = NervePay(
agent_did="did:nervepay:agent:ABC123...",
private_key=os.environ["AGENT_PRIVATE_KEY"]
)
# Retrieve with scope check
secret = client.vault.get_secret("openai-api-key")
if secret["accessible"]:
print(f"API Key: {secret['value']}")
else:
print("Access denied - insufficient scope")

Access Scopes

Define what agents can do with each secret.

"read"

Read-only access

"write"

Read and update

"admin"

Full access

"none"

No access

javascript
// Vault supports multiple access scopes:
// - "read" - Agent can read the secret value
// - "write" - Agent can update the secret
// - "admin" - Full access including delete
// - "none" - No access (for highly sensitive keys)
// Scopes are checked on EVERY request
// Even if agent has the token, scope limits what they can do

Ed25519 Auth Headers

Sign every request with the agent's Ed25519 key. No bearer tokens.

TypeScript

typescript
import { NervePay } from "@nervepay/sdk";
const client = new NervePay({
agentDid: "did:nervepay:agent:ABC123...",
privateKey: process.env.AGENT_PRIVATE_KEY!
});
// Auth headers for ANY API call
const headers = client.authHeaders("GET", "/v1/vault/secrets/my-key");
// Use with any HTTP client
const response = fetch("https://api.nervepay.xyz/v1/vault/secrets/my-key", {
method: "GET",
headers: {
...headers,
"Content-Type": "application/json"
}
});
// Headers include:
// - Authorization: Ed25519 signature
// - X-NervePay-Timestamp: Request timestamp
// - X-NervePay-DID: Agent identity

Python

python
import os
import requests
from nervepay import NervePay
client = NervePay(
agent_did="did:nervepay:agent:ABC123...",
private_key=os.environ["AGENT_PRIVATE_KEY"]
)
headers = client.auth_headers("GET", "/v1/vault/secrets/my-key")
response = requests.get(
"https://api.nervepay.xyz/v1/vault/secrets/my-key",
headers=headers
)
# Headers include:
# - Authorization: Ed25519 signature
# - X-NervePay-Timestamp: Request timestamp
# - X-NervePay-DID: Agent identity

Next Steps