DEV Community

Ross Douglas
Ross Douglas

Posted on

Janee Setup Guide: Secure API Key Management for OpenClaw, Claude, and Other AI Agents

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:

  1. You store API keys in ~/.janee/config.yaml (encrypted at rest)
  2. You run janee serve to start the MCP server
  3. Your AI agents connect to Janee via MCP
  4. When an agent needs to call an API, it requests access through Janee
  5. Janee injects the real key server-side, makes the request, and logs everything
  6. 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
Enter fullscreen mode Exit fullscreen mode

Verify installation:

janee --version
Enter fullscreen mode Exit fullscreen mode

Step 1: Initialize Janee

Run the init command to set up your Janee configuration:

janee init
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 *
Enter fullscreen mode Exit fullscreen mode

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 *
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You should see:

Janee MCP server running on stdio
Config: /Users/yourname/.janee/config.yaml
Logs: /Users/yourname/.janee/logs/
Enter fullscreen mode Exit fullscreen mode

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"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude Desktop.

For Cursor

Edit Cursor's MCP settings (Settings → Extensions → MCP):

{
  "mcpServers": {
    "janee": {
      "command": "janee",
      "args": ["serve"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

For OpenClaw

Install the native plugin:

npm install -g @true-and-useful/janee-openclaw
openclaw plugins install @true-and-useful/janee-openclaw
Enter fullscreen mode Exit fullscreen mode

Enable in your agent config:

{
  agents: {
    list: [{
      id: "main",
      tools: { allow: ["janee"] }
    }]
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. Discover the execute tool from Janee's MCP server
  2. Call execute with capability stripe, method GET, path /v1/balance
  3. Janee decrypts your Stripe key, makes the request, logs it
  4. Returns the balance data to Claude

Check the audit log:

janee logs
Enter fullscreen mode Exit fullscreen mode

You'll see:

2025-02-11 14:32:15 | stripe | GET /v1/balance | 200 | User asked for account balance
Enter fullscreen mode Exit fullscreen mode

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:

  1. Deny rules checked first — explicit deny always wins
  2. Then allow rules checked — must match to proceed
  3. No rules defined → allow all (backward compatible)
  4. 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 *]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/*]
Enter fullscreen mode Exit fullscreen mode

Very short TTL, manual approval, specific endpoints only.


Managing Sessions

List active sessions:

janee sessions
Enter fullscreen mode Exit fullscreen mode

Revoke a session:

janee revoke <session-id>
Enter fullscreen mode Exit fullscreen mode

View audit log in real-time:

janee logs -f
Enter fullscreen mode Exit fullscreen mode

Security Best Practices

  1. Use specific capabilities — Don't give broad access. Create stripe_readonly vs stripe_billing vs stripe_admin.

  2. Set appropriate TTLs — Exploratory work: 1-2h. Sensitive operations: 5-15m.

  3. Enable requiresReason — For sensitive services, make agents provide a reason (logged for audit).

  4. Use request rules — Default deny, explicitly allow only what's needed.

  5. Monitor audit logs — Regularly review janee logs to see what was accessed.

  6. Rotate keys periodically — Janee makes this easy (update config once, all agents use new key).

  7. Backup your config~/.janee/config.yaml is 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

If you found this useful, give Janee a star on GitHub!

Top comments (0)