Credential Vault
Overview
Each Identity has two encrypted storage systems:
- Passwords — website credentials (domain + username + password)
- Secrets — key-value secrets (API keys, environment variables, tokens)
Both are E2E-encrypted. The server never sees plaintext values. The CLI handles encryption and decryption transparently using your PIN-derived keys.
Passwords
Store and retrieve website credentials. Ideal for services your agent signs up for.
Create a password entry
# Auto-generate a password
ravi passwords create example.com --json
# With specific credentials
ravi passwords create example.com \
--username "agent@in.ravi.app" \
--password "S3cret!" \
--notes "Created during onboarding" \
--json
Create flags: --username, --password, --generate, --length (default: 16), --no-special, --no-digits, --exclude-chars, --notes
List passwords
ravi passwords list --json
[
{
"uuid": "abc-123",
"domain": "example.com",
"username": "agent@in.ravi.app",
"created_dt": "2026-02-25T10:30:00Z"
}
]
Passwords are hidden in list view for security.
Retrieve a password
ravi passwords get <uuid> --json
{
"uuid": "abc-123",
"domain": "example.com",
"username": "agent@in.ravi.app",
"password": "S3cret!",
"notes": "Created during onboarding",
"created_dt": "2026-02-25T10:30:00Z"
}
Update and delete
# Update a field
ravi passwords edit <uuid> --password "NewPass!" --json
# Delete an entry
ravi passwords delete <uuid> --json
Generate a password without storing
ravi passwords generate --length 24 --json
Secrets
Store key-value secrets like API keys, tokens, and environment variables.
Store a secret
ravi secrets set OPENAI_API_KEY "sk-abc123..." --json
Retrieve a secret
ravi secrets get OPENAI_API_KEY --json
{
"uuid": "def-456",
"key": "OPENAI_API_KEY",
"value": "sk-abc123...",
"notes": "",
"created_dt": "2026-02-25T10:30:00Z"
}
List all secrets
ravi secrets list --json
Values are redacted in list view — only keys and metadata are shown.
Delete a secret
ravi secrets delete OPENAI_API_KEY --json
Passwords vs. Secrets
| Use case | Store in | Example |
|---|---|---|
| Website login credentials | Passwords | ravi passwords create github.com |
| API keys and tokens | Secrets | ravi secrets set GITHUB_TOKEN "ghp_..." |
| Environment variables | Secrets | ravi secrets set DATABASE_URL "postgres://..." |
| Service accounts with username/password | Passwords | ravi passwords create aws.amazon.com --username admin |
Rule of thumb: if it has a domain + username + password, use Passwords. If it’s a key-value pair, use Secrets.
Domain cleaning
When creating password entries, the CLI auto-cleans URLs to base domains:
https://mail.google.com/inboxbecomesgoogle.comhttps://github.com/settingsbecomesgithub.com
Common recipes
Store credentials during signup
EMAIL=$(ravi get email --json | jq -r '.email')
CREDS=$(ravi passwords create example.com --username "$EMAIL" --json)
PASSWORD=$(echo "$CREDS" | jq -r '.password')
# Use $PASSWORD to fill the signup form
Retrieve credentials for login
ENTRY=$(ravi passwords list --json | jq -r '.[] | select(.domain == "example.com")')
UUID=$(echo "$ENTRY" | jq -r '.uuid')
CREDS=$(ravi passwords get "$UUID" --json)
USERNAME=$(echo "$CREDS" | jq -r '.username')
PASSWORD=$(echo "$CREDS" | jq -r '.password')
Use a stored API key
API_KEY=$(ravi secrets get OPENAI_API_KEY --json | jq -r '.value')
curl -H "Authorization: Bearer $API_KEY" https://api.openai.com/v1/models
Secrets in containerized deployments
A critical constraint: Ravi secrets are E2E-encrypted end-to-end. The server stores only ciphertext. If you call the REST API directly, you get ciphertext back — decryption happens locally in the CLI using your PIN-derived keys. Agents running in containers or CI cannot retrieve plaintext secrets via HTTP alone. They need either the ravi CLI installed and authenticated inside the container, or secrets injected as environment variables at startup time.
Option 1: Startup-time injection (recommended)
Extract secrets from Ravi on the host before the container starts, then pass them as environment variables. The container never needs ravi installed — it just reads standard env vars.
# On the host — extract and inject at container start
OPENAI_KEY=$(ravi secrets get OPENAI_API_KEY --json | jq -r '.value')
DB_URL=$(ravi secrets get DATABASE_URL --json | jq -r '.value')
docker run \
-e OPENAI_API_KEY="$OPENAI_KEY" \
-e DATABASE_URL="$DB_URL" \
my-agent:latest
For Kubernetes, generate a Secret manifest at deploy time:
OPENAI_KEY=$(ravi secrets get OPENAI_API_KEY --json | jq -r '.value')
kubectl create secret generic agent-secrets \
--from-literal=OPENAI_API_KEY="$OPENAI_KEY" \
--dry-run=client -o yaml | kubectl apply -f -
Advantage: the container has zero dependency on Ravi at runtime — no CLI to install, no auth token to manage inside the image. Secrets live only in process memory.
Option 2: CLI inside the container
If the agent needs to read or write secrets dynamically at runtime (not only at startup), install the ravi CLI in the container image and inject the pre-authenticated token at run time:
FROM node:22-slim
# Install ravi CLI
RUN curl -fsSL https://ravi.app/install.sh | sh
Then mount your auth token read-only when running the container:
docker run \
-v ~/.ravi/auth.json:/root/.ravi/auth.json:ro \
-e RAVI_CONFIG_DIR=/tmp/ravi-worker \
my-agent:latest
Mount read-only (
:ro) so the container cannot overwrite your token. Set a per-containerRAVI_CONFIG_DIRso parallel containers do not share state.
GitHub Actions
Store the contents of your local ~/.ravi/auth.json as a repository secret named RAVI_AUTH_JSON (after authenticating once locally with ravi auth login). Then inject it in the workflow:
jobs:
run-agent:
runs-on: ubuntu-latest
steps:
- name: Install ravi
run: curl -fsSL https://ravi.app/install.sh | sh
- name: Restore auth token
run: |
mkdir -p ~/.ravi
echo '${{ secrets.RAVI_AUTH_JSON }}' > ~/.ravi/auth.json
- name: Extract secrets and run
run: |
API_KEY=$(ravi secrets get OPENAI_API_KEY --json | jq -r '.value')
export OPENAI_API_KEY="$API_KEY"
python agent.py
See Authentication for the full headless token setup and token refresh for long-running processes.
Next steps
- E2E Encryption — how the zero-knowledge encryption works
- Service Signup — full workflow with credential storage
- Production Patterns — parallel isolation, polling loops, ephemeral identities
- Harness Integration — injecting Ravi identities at dispatch time