Passwords, API tokens, MFA seeds, and session cookies live encrypted in the vault. When the agent needs one, we inject it at the keystroke layer — after the LLM, before the page.
If the password is in the prompt, it lives forever in that model provider's logs, your traces, and any replay you recorded. One support ticket later and it is on someone's laptop.
The vault is a one-way pipe. The agent references a credential by handle — acme-okta — and the runtime substitutes the value into the keyboard stream at exactly the right DOM field.
// Agent prompt (safe to log, audit, share)
"Log in to Acme billing using the acme-okta
credential, download the last three invoices,
then log out."
// What the agent sees
tool.fill_credential("acme-okta.username")
tool.fill_credential("acme-okta.password")
tool.fill_credential("acme-okta.totp")
// Plaintext values never leave the microVM.
Each credential wrapped with a per-customer data key, rooted in AWS KMS or your own HSM on Enterprise.
Grant an agent access to a single credential for a single session. Access revokes automatically on disconnect.
Built-in time-based one-time passwords. Bring-your-own hardware key via our WebAuthn proxy.
Vaulted values are masked in replays, logs, HAR files, and console output.
Rotate a credential and every running agent picks up the new value on the next keystroke.
Proxy-mode: BrowserAnvil requests credentials from your Vault, 1Password, or AWS Secrets Manager at session start.
Your agent says fill_credential("acme-okta.password") — nothing sensitive in the prompt.
The call hits the VM-local credential agent, not your application code.
The wrapped key is decrypted inside the VM boundary only for the duration of the keystroke.
Value is typed via CDP as synthesized keyboard events, bypassing the JS heap entirely.
We are explicit about our limits. See Compliance for the full threat model and audit reports.
runtime.vault.put(
handle="acme-okta",
values={
"username": "agent@example.com",
"password": "...",
"totp_seed": "JBSWY3DP...",
},
scope=["team:backoffice"],
)
async with runtime.session(
credentials=["acme-okta"]
) as s:
page = await s.new_page()
await page.goto("https://acme.com/login")
await page.fill_credential("#user", "acme-okta.username")
await page.fill_credential("#pass", "acme-okta.password")
Our security team insisted we never put banking credentials in an LLM prompt. The vault is the only reason this project exists in production.
No. They are encrypted at rest with AWS KMS, and the decryption key is only resident in the microVM memory for the duration of a keystroke.
Yes. Rotation is an API call. Running sessions pick up the new value on the next fill_credential invocation.
The session emits a credential_revoked event. Your agent can handle it or terminate cleanly.
No. Access to the production KMS is restricted, audited, and requires a break-glass procedure that notifies the customer.
Vault every credential your agent touches, in minutes.