ADocumentation Index
Fetch the complete documentation index at: https://docs.agent-vault.dev/llms.txt
Use this file to discover all available pages before exploring further.
Service is a per-vault configuration that defines which upstream traffic agents can reach through the proxy and how Agent Vault authenticates to each one. When an agent makes a proxied request, Agent Vault matches the request against the vault’s services by host pattern (which may include an inline path glob like slack.com/api/*), attaches the configured credentials, and forwards the request. If no service matches, the request is forwarded as plain proxy traffic by default; vault admins can flip a vault into strict deny mode (unmatched_host_policy=deny in vault settings) to reject unmatched requests with 403 instead.
Each service contains:
- Name: A canonical per-vault identifier (slug, 3–64 lowercase alphanumeric/hyphen chars, no leading/trailing hyphen, no consecutive hyphens). Required on write for new services — pick a deliberate name like
stripe,slack-bot, orinternal-billing.namemay be omitted only whenhost+pathuniquely matches an existing service (the server adopts that service’s name, the same pattern as host-based delete). Legacy services persisted without a name before this contract are auto-slugified fromhost+pathon read so they remain addressable; the slug becomes durable on the next write. - Host: The single matcher field. Accepts a bare hostname (
api.stripe.com), a one-level wildcard (*.github.com), or an inline path-scoped form (slack.com/api/*). Reads and writes use the same shape: writes accept any of those forms; reads return the joined inline form so you see exactly what you wrote. - Auth config: How Agent Vault authenticates. Five types are supported:
bearer,basic,api-key,custom, andpassthrough(opt out of injection).
- Automatically: As agents do their work, they can raise proposals to add or modify services. You review each proposal, provide any required credentials, and approve. This is the recommended workflow for working with Agent Vault.
- Manually: You can set services directly via the CLI by applying a YAML file or by using the interactive builder. This can be useful for pre-configuring a vault before inviting agents.
Service structure
Services are defined in a YAML file. Here’s what a single service looks like:stripe-services.yaml
host tells Agent Vault which requests this service applies to. The auth block tells Agent Vault how to authenticate, referencing credential keys by name (not the actual credential values). The following section covers all five auth types.
Auth types
Every service must include anauth config that tells Agent Vault how to authenticate to the target host. The auth config references credential key names (not the actual credential values) stored in the vault.
Bearer
Attaches anAuthorization: Bearer <token> header. The token field references a credential key.
Basic
Attaches anAuthorization: Basic <base64> header using HTTP Basic authentication. The username field is required; password is optional (defaults to empty).
API key
Attaches a credential value to a named header with an optional prefix. Theheader field defaults to Authorization if omitted.
Custom
Freeform header templates with{{ SECRET }} placeholders. Each placeholder is resolved to the corresponding credential at proxy time. Use this when none of the typed auth methods fit.
Passthrough
Allowlists the host without injecting a credential. No credential is stored, read, or attached; client request headers (includingAuthorization and Cookie) flow through to the upstream — same as for credentialed services, just without a broker-injected auth header on top.
Header forwarding
Agent Vault forwards your client’s request headers to the upstream unchanged, except for:- Hop-by-hop headers per RFC 7230 (
Connection,Keep-Alive,Proxy-Authenticate,Proxy-Authorization,Proxy-Connection,Te,Trailer,Transfer-Encoding,Upgrade). - Broker-scoped headers that authenticate the client to Agent Vault itself (
X-Vault,Proxy-Authorization). - The auth slot — the specific header(s) the configured auth type manages. With
auth.type: bearerorbasic, the broker overridesAuthorization. Withapi-key, it overrides whatever you named inauth.header. Withcustom, it overrides every key inauth.headers. Withpassthrough, nothing.
anthropic-version, OpenAI-Beta, If-Match, and tracing IDs reach the upstream regardless of auth type. The broker only takes over the headers it’s responsible for injecting.
Substitutions
Auth types only inject HTTP headers. Some upstream APIs want a credential value in the URL path or query string instead — Twilio’s/Accounts/{AccountSID}/Messages.json, legacy services that take ?api_key=. For those, declare a substitutions block alongside the auth.
GET https://api.twilio.com/2010-04-01/Accounts/__account_sid__/Messages.json (routed through the broker via HTTPS_PROXY/HTTP_PROXY). Agent Vault:
- Resolves the basic auth credentials and injects
Authorization: Basic <base64(SID:TOKEN)>. - Scans only the path (the only surface in
in:), finds__account_sid__, replaces it with the URL-encoded SID. - Forwards the request.
Field reference
key— UPPER_SNAKE_CASE credential reference. Must resolve to a credential in the vault or a slot in the same proposal.placeholder— the exact wire string Agent Vault matches case-sensitively as a literal. Operators choose the string; the broker does not auto-wrap delimiters around it. The recommended convention is__name__(double-underscore-bounded snake_case).in— list of surfaces the broker is allowed to scan. Subset ofpath,query,header. Defaults to[path, query]if omitted.bodyis reserved for a future version.
Scoping is the security boundary
Agent Vault only scans surfaces listed inin. If an agent embeds the placeholder in a non-declared surface (a JSON body to round-trip via an echo upstream, a header that wasn’t declared), the literal string passes through to upstream — the broker will not substitute. There is no way to coerce the broker into substituting somewhere the operator did not authorize.
Use this property to pick a narrow in for strong secrets that happen to live in URLs (legacy ?api_key= APIs): keep in: [query] and the agent cannot exfiltrate the value through a body or a different header.
Placeholder safety rules
The validator rejects placeholders that would cause false-positive substitutions in legitimate URL content:- Length ≥ 4 characters.
- Must contain a
__sequence or a non-[A-Za-z0-9_]character — so a bare word likeaccount_sidis rejected (it could appear as a real path segment), while__account_sid__,sid.value,sid-val, and~sid~all pass. - At least one alphanumeric character — strings made entirely of delimiters like
____or~~~~are rejected because they would aggressively match URL punctuation. - Only RFC 3986 unreserved characters
[A-Za-z0-9_-.~]are permitted, so the placeholder survives any HTTP client / SDK / middlebox without percent-encoding round-trips.
header scope is request-wide
When in includes header, the broker scans every outbound header for the placeholder — not one specific named header. Pick a unique placeholder so a typo or a copy-pasted value can’t accidentally land in a header you didn’t intend to rewrite. (Path and query are scoped to those URL components and don’t have this concern.)
Composes with all auth types
Substitutions and auth are independent. A service can use either, both, or neither:- Twilio:
auth: basic(header) + path substitution for the SID. - Legacy
?api_key=API:auth: api-keyfor an audit header + query substitution for the actual key. - A pure-substitution case (e.g. an internal API where the only secret lives in the path):
auth: passthrough+ path substitution.
Matching rules
Thehost pattern is the single matcher knob. It can carry just a hostname (api.stripe.com), a wildcard host (*.github.com), or an inline path glob (slack.com/api/*).
Host portion supports two modes:
- Exact match:
api.stripe.commatches onlyapi.stripe.com. - Wildcard:
*.github.commatchesapi.github.com,uploads.github.com, etc. The*replaces exactly one subdomain segment.
/) is a URL glob. A bare host with no path matches any path; a non-empty path must start with / and may use * as a greedy glob (cross-/). **, ?, regex, and a bare * are rejected.
Matching priority
When twohost patterns could match a request, the winner is chosen deterministically:
- Host tier first. A pattern whose host portion is an exact match of the request host always beats one with a wildcard host (
*.example.com) — even when the wildcard rule has a more specific path portion. - Path specificity within a host tier. Among patterns in the same host tier, the rule with the longest literal path prefix wins (characters in the path portion before the first
*). A bare-host pattern (no path) scores 0 (catch-all). - Declaration order on tie. If two rules tie on host tier and literal path-prefix length, the rule appearing first in the configured service list wins.
| Request | slack-bot (slack.com/api/*) | slack-conn (slack.com/api/apps.connections.*) | Winner |
|---|---|---|---|
slack.com/api/apps.connections.open | matches, prefix length 5 | matches, prefix length 22 | slack-conn |
slack.com/api/chat.postMessage | matches | doesn’t match | slack-bot |
slack.com/oauth/v2/authorize | doesn’t match | doesn’t match | none |
- To override a wildcard-host rule for a specific subdomain, add the exact-host rule — it takes priority no matter what its path portion looks like.
- To layer two credentials on the same host, give them different path portions; the more specific path will win.
- The matcher does not run regex, does not match on method/headers/query/body, and does not bound
*at path segments. Patterns that tie under rule 2 (e.g.slack.com/api/*/v2andslack.com/api/*/v3) fall to declaration order.
Example
A vault can define multiple services with different auth types and path scopes:services.yaml
my-vault can now proxy requests to these hosts, and Agent Vault attaches the real credentials at request time.
Managing services
Set from a file
Set interactively
View current services
Clear all services
403 on every proxy request until new services are configured. Prompts for confirmation unless you pass --yes.
vault service remove, enable, and disable accept either the canonical service name or the bare host. When several path-scoped services share a host (e.g. Slack with slack.com/api/* and slack.com/api/apps.connections.*), passing the bare host returns 409 multiple services match host … with a candidates array of {name, host} (each host carries the joined inline form). Retry with the specific name shown in agent-vault vault service list.How proposals modify services
How proposals modify services
Agents don’t edit service configurations directly. Instead, they propose changes
through proposals, bundles of service and credential
modifications that a human reviews and approves.Each service in a proposal has an
action field:set: Idempotent upsert keyed by canonicalname(slug). Adds the service when no entry has that name, or replaces it when one does.nameis required for new services. It may be omitted only whenhost+pathuniquely matches an existing service — the server adopts that entry’s name (the same pattern as host-based delete), so an agent that knows the host but not the canonical name can still target an existing service.delete: Removes the service matching the givenname. Whennameis omitted, the bare host portion ofhostis used as a fallback — a unique host match is resolved automatically; a host shared by multiple path-scoped services returns409 multiple services match host …with acandidateslist, and the proposal must be retried with an explicitname.
name.This means agents can request access to new services without you manually
editing YAML files. You just review and click “Allow” in the browser
approval page.What happens when an agent hits an unknown host
What happens when an agent hits an unknown host
When a proxy request targets a host not covered by any service, Agent Vault returns
403
with a proposal_hint in the response body. The hint includes the denied
host and the endpoint to create a proposal.Well-behaved agents use this hint to automatically raise a
proposal requesting access. You receive a browser link
to review the request and provide any needed credentials.

