Skip to main content

Overview

RunTools provides centralized secrets management for storing API keys, provider credentials, and tool configuration. Secrets are encrypted at rest with AES-256-GCM and managed via the dashboard, CLI, or API. The secrets system lives on the tools service (tools.runtools.ai/v1/secrets) and uses the same encryption as tool credentials.

Creating Secrets

# Store a provider API key
runtools secret set ANTHROPIC_API_KEY "sk-ant-xxx" --category provider

# Store a tool credential
runtools secret set GITHUB_TOKEN "ghp_xxx" --category tool

# Store a custom secret
runtools secret set MY_DATABASE_URL "postgres://user:pass@host/db" --category custom

# With description and scope
runtools secret set OPENAI_API_KEY "sk-xxx" \
  --category provider \
  --scope agents \
  --description "OpenAI key for agent runs"

# Value from stdin (for long values or scripts)
echo "my-secret-value" | runtools secret set MY_SECRET
Or from the dashboard: Credentials > Tool & Provider Keys > Add Secret.

Listing Secrets

# List all secrets (metadata only, never values)
runtools secret list

# Filter by category
runtools secret list --category provider
The API never returns secret values in list responses — only metadata (name, scope, category, description, timestamps).

Revealing Secrets

Reveal operations are auditable — the system logs who revealed what and when.
cURL
# Reveal a secret value (audited)
curl -X POST https://tools.runtools.ai/v1/secrets/ANTHROPIC_API_KEY/reveal \
  -H "Authorization: Bearer rt_live_xxx"
In the dashboard, click the eye icon on a secret to reveal its value. The value auto-hides after a few seconds.

Deleting Secrets

runtools secret delete ANTHROPIC_API_KEY

# Skip confirmation
runtools secret delete ANTHROPIC_API_KEY --force

Secret Properties

PropertyDescriptionValues
nameSecret identifier (unique per org)Any string
valueThe secret valueEncrypted with AES-256-GCM
scopeWhere this secret can be usedall, agents, tools, sandboxes
categoryGrouping for UI displayprovider, tool, custom
descriptionHuman-readable descriptionOptional

Dashboard: Credentials Page

The Credentials page (Dashboard > Organization > Credentials) combines:
  • API Keys — RunTools API keys (rt_live_xxx) for authenticating API calls
  • SSH Keys — Public keys for SSH access to sandboxes
  • Tool & Provider Keys — Secrets stored via the secrets API (provider keys, tool keys, custom)
  • Connected Apps — OAuth connections for automatic credential resolution
Secrets are grouped by category with search and CRUD operations.
For OAuth-enabled tools (GitHub, Gmail, Slack, etc.), use Connected Apps instead of manually storing tokens. Connections auto-refresh and are more secure. See OAuth & Connected Apps.

Security

Encryption

  • Secrets are encrypted at rest using AES-256-GCM
  • 32-byte encryption key stored as environment variable on the tools service
  • Each secret has its own random IV (initialization vector)
  • Storage format: base64(iv):base64(ciphertext):base64(tag)

Access Control

  • Secrets are org-scoped — all members can access them
  • Only authenticated users with valid API keys or WorkOS sessions can read/write
  • Reveal operations are logged for audit purposes

What’s NOT Built Yet

  • Per-secret access control (restrict who can reveal)
  • Auto-rotation of keys
  • Multiple keys per provider
  • Integration with external secret managers (AWS Secrets Manager, Vault)

API Reference

MethodPathDescription
GET/v1/secretsList all secrets (metadata only)
POST/v1/secretsCreate or update (upsert) a secret
GET/v1/secrets/:nameGet single secret metadata
DELETE/v1/secrets/:nameDelete a secret
POST/v1/secrets/:name/revealDecrypt and return the secret value

Best Practices

ANTHROPIC_API_KEY not KEY1. Include the provider/purpose in the name.
Use provider for LLM API keys, tool for tool credentials, custom for everything else.
If a secret is only needed by agents, set scope to agents instead of all.
Update secrets periodically, especially after team changes. The upsert API makes rotation easy — just POST with the same name and a new value.
The API never returns values in list/get responses. Only use the reveal endpoint when you actually need the value.