Lumbox Docs

Credential Vault

Secure password manager for AI agents — store, use, never expose.

Credential Vault

AI agents sign up for services, create accounts, and need to log back in later. The Credential Vault stores passwords, API keys, and TOTP secrets with enterprise-grade encryption — and ensures agents never see the plaintext in their conversation context.

Why This Matters

When an AI agent signs up for GitHub and gets a password, where does that password go? Without a vault:

  1. The password sits in the conversation context
  2. It could be extracted via prompt injection
  3. It appears in logs, transcripts, and audit trails
  4. Other agents or users viewing the conversation can see it

The Credential Vault eliminates all of these attack surfaces.

Security Architecture

3-Layer Protection

Layer 1: Envelope Encryption (AES-256-GCM)
  Master Key (KEK) → per-org Data Key (DEK) → encrypted credential
  DB dump is useless without the master key

Layer 2: Steel Browser Auto-Injection
  Credentials injected at browser level → fields blurred immediately
  Even screenshots can't capture the password

Layer 3: MCP Tool Design
  No tool ever returns a credential value
  Passwords flow: DB → decrypt → browser field (never into conversation)

Envelope Encryption

Each organization gets its own Data Encryption Key (DEK), which is itself encrypted by a Key Encryption Key (KEK) — the master key stored in the server environment.

KEK (master, in env)
 └─→ wraps Org DEK (stored in DB, encrypted)
      └─→ encrypts each credential value

Benefits:

  • Rotate the master key without re-encrypting every credential (just re-wrap DEKs)
  • Delete an org's DEK to make all their credentials irrecoverable
  • DB dump is useless — attacker needs both the wrapped DEK and the master key

Quick Start

Store a credential

# Via MCP (Claude Code, Cursor, etc.)
"Store my GitHub credentials: email bot@example.com, password MyS3cr3t!"

The agent calls store_credential — the password is encrypted immediately and never returned in any future API response.

Log in securely

"Log into GitHub using my stored credentials"

The agent calls login_with_credential — Steel Browser auto-fills the login form at the browser level, blurs the fields, and auto-submits. The password never appears in the conversation, DOM, or screenshots.

API Reference

Store Credential

POST /v1/credentials

Body:

{
  "service": "github.com",
  "identifier": "bot@example.com",
  "value": "MyS3cr3t!",
  "credential_type": "password",
  "label": "GitHub bot account",
  "expires_at": "2027-01-01T00:00:00Z"
}

Response (201):

{
  "id": "cred_abc123",
  "service": "github.com",
  "identifier": "bot@example.com",
  "credential_type": "PASSWORD",
  "label": "GitHub bot account",
  "stored": true,
  "message": "Credential stored securely. Use 'use_credential_in_browser' to fill it into forms."
}

The value field is never returned in any API response after storage.

List Credentials

GET /v1/credentials
GET /v1/credentials?service=github.com

Response (200):

{
  "data": [
    {
      "id": "cred_abc123",
      "service": "github.com",
      "identifier": "bot@example.com",
      "credential_type": "PASSWORD",
      "label": "GitHub bot account",
      "last_used_at": "2026-03-15T10:00:00Z",
      "created_at": "2026-03-01T10:00:00Z"
    }
  ]
}

Returns metadata only — never the actual values.

Use Credential (Internal)

POST /v1/credentials/use

This endpoint decrypts the credential for browser injection. Called internally by the MCP server's use_credential_in_browser tool. The plaintext goes directly to the browser and is never exposed in the API response to the agent.

Delete Credential

DELETE /v1/credentials/:id

Permanently deletes the credential and logs the deletion.

Audit Log

GET /v1/credentials/audit?limit=50

Every credential access is logged:

{
  "data": [
    {
      "id": "log_abc",
      "credential_id": "cred_abc123",
      "action": "use_in_browser",
      "metadata": { "service": "github.com", "identifier": "bot@example.com" },
      "created_at": "2026-03-15T10:00:00Z"
    }
  ]
}

MCP Tools

store_credential

Store a password, API key, or TOTP secret in the encrypted vault. Also syncs to Steel Browser for auto-injection into login forms.

ParameterTypeRequiredDescription
servicestringYesWebsite (e.g. github.com)
identifierstringYesUsername or email
valuestringYesThe secret (encrypted, never returned)
credential_typestringNopassword, api_key, totp_secret, oauth_token, cookie
totp_secretstringNoBase32 TOTP secret for 2FA auto-fill
namespacestringNoIsolation namespace for multi-user setups
labelstringNoHuman-readable label

login_with_credential

Most secure login method. Creates a Steel Browser session with credential injection enabled, navigates to the login page, and lets Steel auto-fill + auto-submit with fields blurred.

ParameterTypeRequiredDescription
login_urlstringYesLogin page URL
servicestringYesService matching stored credential
namespacestringNoCredential namespace
session_idstringNoBrowser session name
wait_secondsnumberNoSeconds to wait for injection (default: 5)
success_selectorstringNoCSS selector confirming login success

What happens:

  1. New browser session created with credentials: { autoSubmit: true, blurFields: true }
  2. Navigate to login URL
  3. Steel detects the login form and auto-fills username + password
  4. Fields are blurred immediately (prevents screenshots from capturing)
  5. Form auto-submits
  6. Returns snapshot of post-login page

use_credential_in_browser

Fallback for non-login password fields. Decrypts server-side and types into a specific browser element.

ParameterTypeRequiredDescription
servicestringYesService matching stored credential
identifierstringYesUsername/email matching credential
refstringYesBrowser element ref (e.g. @e5)
credential_typestringNoType of credential (default: password)
press_enterbooleanNoPress Enter after filling
session_idstringNoBrowser session name

Use this for:

  • "Confirm password" fields on settings pages
  • "Current password" fields when changing passwords
  • API key fields in third-party dashboards

list_credentials

Lists stored credentials. Returns service, identifier, type, label — never the values.

delete_credential

Permanently removes a credential from the vault.

Credential Types

TypeUse Case
passwordWebsite login passwords
api_keyThird-party API keys
totp_secret2FA authenticator secrets (auto-generates codes)
oauth_tokenOAuth access/refresh tokens
cookieSession cookies

TOTP Support

Store a TOTP secret alongside a password for sites with 2FA:

{
  "service": "github.com",
  "identifier": "bot@example.com",
  "value": "MyP@ssw0rd",
  "totp_secret": "JBSWY3DPEHPK3PXP"
}

When Steel Browser detects a one-time password field during login, it auto-generates and fills the current TOTP code.

Namespace Isolation

For multi-user credential separation:

{
  "service": "github.com",
  "identifier": "fred@example.com",
  "value": "fred-password",
  "namespace": "agent:fred"
}
{
  "service": "github.com",
  "identifier": "jane@example.com",
  "value": "jane-password",
  "namespace": "agent:jane"
}

When logging in, specify the namespace to use the correct credentials:

login_with_credential(login_url="https://github.com/login", service="github.com", namespace="agent:fred")

Threat Model

ThreatProtection
DB dump / SQL injectionEnvelope encryption — credentials encrypted with per-org DEK, DEK encrypted with master KEK
Agent leaks password in conversationNo MCP tool returns credential values. login_with_credential uses Steel injection with blurred fields
Prompt injection extracts secretsPasswords never enter the conversation context
Screenshot captures passwordSteel blurs fields immediately after injection
One org compromisedPer-org DEK isolation — other orgs unaffected
Credential access without authorizationEvery access logged in audit trail
Expired credentials usedAutomatic expiry checking before use