Janee Setup Guide: Secure API Key Management for OpenClaw, Claude, and Other AI Agents
Source: Dev.to
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
.envfiles - 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
- Store API keys in
~/.janee/config.yaml(encrypted at rest). - 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 without ever seeing your actual key.
Key benefits
| ✅ Feature | Description |
|---|---|
| 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, …)
Installation
npm install -g @true-and-useful/janee
Verify the installation:
janee --version
Run the init command to set up your Janee configuration:
janee init
This creates ~/.janee/config.yaml with example 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
Defining Capabilities
Capabilities define what agents can do with each service. They include policies such as TTL, auto‑approval, and request rules.
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 *
Note: Policies are enforced server‑side. Even if an agent tries to bypass them, Janee blocks unauthorized requests.
Starting the Server
janee serve
You should see something like:
Janee MCP server running on stdio
Config: /Users/yourname/.janee/config.yaml
Logs: /Users/yourname/.janee/logs/
Keep this process running – Janee is now ready to accept requests from MCP clients.
Integrating with AI Agents
Claude Desktop (macOS example)
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (or the equivalent on your OS):
{
"mcpServers": {
"janee": {
"command": "janee",
"args": ["serve"]
}
}
}
Restart Claude Desktop.
Cursor
- Open Settings → Extensions → MCP.
- Paste the same JSON snippet as above.
OpenClaw (native plugin)
npm install -g @true-and-useful/janee-openclaw
openclaw plugins install @true-and-useful/janee-openclaw
Enable it in your agent config:
{
"agents": {
"list": [
{
"id": "main",
"tools": { "allow": ["janee"] }
}
]
}
}
Using Janee in a Prompt
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.
Viewing the audit log
janee logs
Sample output:
2025-02-11 14:32:15 | stripe | GET /v1/balance | 200 | User asked for account balance
Request‑Rule Syntax
Rules are expressed as METHOD PATH. Below is a quick reference.
| 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 are evaluated
- Deny rules are checked first – an explicit deny always wins.
- Allow rules are checked next – a match is required to proceed.
- If no rules are defined → allow all (backward compatible).
- If rules exist but no match → request is denied by default.
Sample Service & Capability Configurations
GitHub (read‑only)
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.
OpenAI
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 lets you monitor usage and revoke access quickly.
Internal API (very short TTL, manual approval)
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/*]
Recap
- Install Janee globally (
npm i -g @true-and-useful/janee). - Initialize (
janee init) and add your services (janee add). - Define capabilities with appropriate TTLs and request rules.
- Run
janee serveand configure your AI agents to use the MCP server. - Prompt your agents to perform API calls – Janee handles the keys, logs, and policy enforcement.
You now have a secure, auditable, and policy‑driven way to give AI coding agents access to your APIs without ever exposing raw secrets. Happy coding!
Janee Quick‑Reference Guide
Core Commands
| Action | Command |
|---|---|
| List active sessions | janee sessions |
| Revoke a session | janee revoke <id> |
| View audit log in real‑time | janee logs -f |
Policy Recommendations
-
Use specific capabilities – Don’t grant broad access.
Examples:stripe_readonly,stripe_billing,stripe_admin. -
Set appropriate TTLs
- Exploratory work: 1–2 h
- Sensitive operations: 5–15 min
-
Enable
requiresReason– For sensitive services, agents must supply 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 the config once and all agents pick up the new key.
-
Backup your config –
~/.janee/config.yamlis encrypted; back it up securely.
Troubleshooting
| Issue | Solution |
|---|---|
| Agent can’t see Janee tools | Ensure janee serve is running and the agent’s MCP config points to it. Restart the agent. |
| “Permission denied” or “Capability not found” | Verify the capability name in your config matches what the agent is requesting. |
| Requests blocked by rules | Check janee logs to see which rule blocked the request. Adjust your allow/deny patterns in the config. |
| Keys not encrypted | Keys are encrypted when Janee reads/writes the config. If you edit config.yaml manually, run janee serve to trigger encryption. |
Running Janee in Docker / Kubernetes
If you’re containerising agents, use the HTTP transport:
janee serve --transport http --port 9100
Example 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
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:
- GitHub:
- Issues / Support:
If you found this useful, give Janee a ⭐ on GitHub!