Introduction
AI coding agents are transforming software development. Tools like Claude Desktop, Cursor, and Cline can write code, debug issues, and even make API calls on your behalf.
But there's a problem: how do you give these agents API access without compromising security?
The common approach — pasting API keys into config files or prompts — is risky:
- Keys stored in plaintext on disk
- Agents can read .env files
- No audit trail of what was accessed
- No way to revoke access without rotating keys
- One prompt injection away from full API access
This guide shows you how to use Janee, a local secrets manager designed for AI agent workflows, to solve these problems.
What is Janee?
Janee is an MCP (Model Context Protocol) server that stores API credentials encrypted on your machine and acts as a secure proxy.
How it works:
- You store API keys in
~/.janee/config.yaml(encrypted at rest) - You run
janee serveto start the MCP server - Your AI agents connect to Janee via MCP
- When an agent needs to call an API, it requests access through Janee
- Janee injects the real key server-side, makes the request, and logs everything
- The agent receives the API response but never sees your actual key
Key benefits:
- ✅ Encrypted storage: Keys encrypted with AES-256-GCM
- ✅ Zero-knowledge agents: Agents never see the actual credentials
- ✅ Full audit trail: Every request logged with timestamp, service, method, path
- ✅ Policy enforcement: Control what HTTP methods/paths agents can access
- ✅ Configure once, use everywhere: One config, all MCP agents get access
- ✅ Open source (MIT): Full transparency
Prerequisites
- Node.js 18+ installed
- An AI agent that supports MCP (Claude Desktop, Cursor, OpenClaw, Cline, etc.)
- API keys you want to manage (Stripe, GitHub, OpenAI, etc.)
Installation
Install Janee globally via npm:
npm install -g @true-and-useful/janee
Verify installation:
janee --version
Step 1: Initialize Janee
Run the init command to set up your Janee configuration:
janee init
This creates ~/.janee/config.yaml with example services.
Step 2: Add Your API Services
You can add services interactively or via command-line arguments.
Option A: Interactive (recommended for beginners)
janee add
Janee will prompt you for:
- Service name (e.g.,
stripe) - Base URL (e.g.,
https://api.stripe.com) - Auth type (
bearer,basic,hmac-bybit, etc.) - API key/credentials
Option B: Command-line arguments
janee add stripe \
-u https://api.stripe.com \
--auth-type bearer \
-k sk_live_xxx
Step 3: Create Capabilities
Capabilities define what agents can do with each service. They include policies like:
- Time-to-live (TTL)
- Auto-approval
- Request rules (allow/deny specific HTTP methods and paths)
Example: Read-only Stripe access
capabilities:
stripe_readonly:
service: stripe
ttl: 1h
autoApprove: true
rules:
allow:
- GET *
deny:
- POST *
- DELETE *
- PUT *
Example: Stripe billing (limited write access)
capabilities:
stripe_billing:
service: stripe
ttl: 15m
requiresReason: true
rules:
allow:
- GET *
- POST /v1/refunds/*
- POST /v1/invoices/*
deny:
- POST /v1/charges/* # Can't charge cards
- DELETE *
Policies are enforced server-side. Even if an agent tries to bypass them, Janee blocks unauthorized requests.
Step 4: Start the MCP Server
janee serve
You should see:
Janee MCP server running on stdio
Config: /Users/yourname/.janee/config.yaml
Logs: /Users/yourname/.janee/logs/
Keep this running. Janee is now ready to accept requests from MCP clients.
Step 5: Configure Your AI Agent
For Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your OS:
{
"mcpServers": {
"janee": {
"command": "janee",
"args": ["serve"]
}
}
}
Restart Claude Desktop.
For Cursor
Edit Cursor's MCP settings (Settings → Extensions → MCP):
{
"mcpServers": {
"janee": {
"command": "janee",
"args": ["serve"]
}
}
}
For OpenClaw
Install the native plugin:
npm install -g @true-and-useful/janee-openclaw
openclaw plugins install @true-and-useful/janee-openclaw
Enable in your agent config:
{
agents: {
list: [{
id: "main",
tools: { allow: ["janee"] }
}]
}
}
Full integration guides: https://janee.io/docs
Step 6: Test It
Ask your agent to make an API call through Janee.
Example prompt for Claude Desktop:
"Can you check my Stripe account balance using Janee?"
Claude will:
- Discover the
executetool from Janee's MCP server - Call
executewith capabilitystripe, methodGET, path/v1/balance - Janee decrypts your Stripe key, makes the request, logs it
- Returns the balance data to Claude
Check the audit log:
janee logs
You'll see:
2025-02-11 14:32:15 | stripe | GET /v1/balance | 200 | User asked for account balance
Understanding Request Policies
Request rules use this format: METHOD PATH
Examples:
| Rule | Meaning |
|---|---|
GET * |
Allow all GET requests |
POST /v1/charges/* |
Allow POST to /v1/charges/ and subpaths |
DELETE * |
Deny all DELETE requests |
* /v1/customers |
Any method to /v1/customers |
How rules work:
- Deny rules checked first — explicit deny always wins
- Then allow rules checked — must match to proceed
- No rules defined → allow all (backward compatible)
- Rules defined but no match → denied by default
Common Use Cases
Use Case 1: Read-only GitHub access
services:
github:
baseUrl: https://api.github.com
auth:
type: bearer
key: ghp_xxx
capabilities:
github_readonly:
service: github
ttl: 2h
rules:
allow: [GET *]
deny: [POST *, DELETE *, PUT *, PATCH *]
Your agent can read repos, issues, PRs — but can't create, update, or delete anything.
Use Case 2: OpenAI API with usage limits
services:
openai:
baseUrl: https://api.openai.com
auth:
type: bearer
key: sk-xxx
capabilities:
openai:
service: openai
ttl: 30m
requiresReason: true
Short TTL + requires reason = you can monitor usage and revoke if needed.
Use Case 3: Internal API with strict controls
services:
internal_api:
baseUrl: https://api.yourcompany.com
auth:
type: bearer
key: internal_xxx
capabilities:
internal_readonly:
service: internal_api
ttl: 10m
autoApprove: false # Manual approval required
rules:
allow: [GET /v1/users/*, GET /v1/analytics/*]
Very short TTL, manual approval, specific endpoints only.
Managing Sessions
List active sessions:
janee sessions
Revoke a session:
janee revoke <session-id>
View audit log in real-time:
janee logs -f
Security Best Practices
Use specific capabilities — Don't give broad access. Create
stripe_readonlyvsstripe_billingvsstripe_admin.Set appropriate TTLs — Exploratory work: 1-2h. Sensitive operations: 5-15m.
Enable
requiresReason— For sensitive services, make agents provide a reason (logged for audit).Use request rules — Default deny, explicitly allow only what's needed.
Monitor audit logs — Regularly review
janee logsto see what was accessed.Rotate keys periodically — Janee makes this easy (update config once, all agents use new key).
Backup your config —
~/.janee/config.yamlis encrypted but back it up securely.
Troubleshooting
Issue: Agent can't see Janee tools
Solution: Make sure janee serve is running and your agent's MCP config points to it. Restart the agent.
Issue: "Permission denied" or "Capability not found"
Solution: Check that the capability name in your config matches what the agent is requesting.
Issue: Requests blocked by rules
Solution: Check janee logs to see which rule blocked it. Adjust your allow/deny patterns in config.
Issue: Keys not encrypted
Solution: Keys are encrypted when Janee reads/writes the config. If you manually edit config.yaml, run janee serve to trigger encryption.
Advanced: HTTP Transport for Containers
If you're running agents in Docker/Kubernetes, use HTTP transport:
janee serve --transport http --port 9100
Configure your containerized agent to connect via HTTP:
# docker-compose.yml
services:
janee:
build: .
ports:
- "9100:9100"
command: janee serve --transport http --port 9100
agent:
depends_on:
- janee
environment:
- JANEE_HTTP_URL=http://janee:9100
Full guide: https://janee.io/docs/container-openclaw
Conclusion
You've successfully set up Janee to manage API keys for your AI agents.
What you've gained:
- Encrypted credential storage
- Zero-knowledge agents (they never see your keys)
- Full audit trail
- Policy enforcement
- One config for all your agents
Next steps:
- Add more services (
janee add) - Experiment with request policies
- Set up integrations for all your agent tools
- Monitor audit logs (
janee logs -f)
Resources:
- Docs: https://janee.io
- GitHub: https://github.com/true-and-useful/janee
- Issues/Support: https://github.com/true-and-useful/janee/issues
If you found this useful, give Janee a star on GitHub!
Top comments (0)