Labsco
rsdouglas logo

Janee API Security

β˜… 28

from rsdouglas

MCP server that sits between AI agents and APIs. Agents request access, Janee makes the call with the real credentials, agents never see the secrets.

πŸ”₯πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedPaid serviceAdvanced setup

Janee πŸ”

Secrets management for AI agents via MCP

npm version npm downloads License: MIT GitHub stars

Your AI agents need API access to be useful. But they shouldn't have your raw API keys. Janee sits between your agents and your APIs β€” injecting credentials, enforcing policies, and logging everything.

✨ Features

πŸ”’ Zero-knowledge agentsAgents call APIs without ever seeing keys
πŸ“‹ Full audit trailEvery request logged with timestamp, method, path, status
πŸ›‘οΈ Request policiesAllow/deny rules per capability (e.g., read-only Stripe)
⏱️ Session TTLsTime-limited access with instant revocation
πŸ”Œ Works with any MCP clientClaude Desktop, Cursor, OpenClaw, and more
🏠 Local-firstKeys encrypted on your machine, never sent to a cloud
πŸ–₯️ Exec modeRun CLI tools with injected credentials β€” agents never see the keys
πŸ€– GitHub App authShort-lived tokens for autonomous agents β€” no static PATs
🐦 Twitter/X OAuth 1.0aPer-request OAuth signing β€” 4 secrets stay encrypted
☁️ AWS SigV4Sign AWS API requests server-side β€” SES, S3, and more
πŸ”§ Automatic git authgit push/pull just works when credentials include GitHub tokens

The Problem

AI agents need API access to be useful. The current approach is to give them your keys and hope they behave.

  • πŸ”“ Agents have full access to Stripe, Gmail, databases
  • πŸ“Š No audit trail of what was accessed or why
  • 🚫 No kill switch when things go wrong
  • πŸ’‰ One prompt injection away from disaster

The Solution

Janee is an MCP server that manages API secrets for AI agents:

  1. Store your API keys β€” encrypted locally in ~/.janee/
  2. Run janee serve β€” starts MCP server
  3. Agent requests access β€” via execute MCP tool
  4. Janee injects the real key β€” agent never sees it
  5. Everything is logged β€” full audit trail

Your keys stay on your machine. Agents never see them. You stay in control.


Configure Once, Use Everywhere

Set up your APIs in Janee once:

services:
  stripe:
    baseUrl: https://api.stripe.com
    auth: { type: bearer, key: sk_live_xxx }
  github:
    baseUrl: https://api.github.com
    auth: { type: bearer, key: ghp_xxx }
  openai:
    baseUrl: https://api.openai.com
    auth: { type: bearer, key: sk-xxx }

Now every agent that connects to Janee can use them:

  • Claude Desktop β€” access your APIs
  • Cursor β€” access your APIs
  • OpenClaw β€” access your APIs
  • Any MCP client β€” access your APIs

No more copying keys between tools. No more "which agent has which API configured?" Add a new agent? It already has access to everything. Revoke a key? Update it once in Janee.

One config. Every agent. Full audit trail.


Integrations

Works with any agent that speaks MCP:


OpenClaw Integration

If you're using OpenClaw, install the plugin for native tool support:

npm install -g @true-and-useful/janee
janee init
# Edit ~/.janee/config.yaml with your services

# Install the OpenClaw plugin
openclaw plugins install @true-and-useful/janee-openclaw

Enable in your agent config:

{
  agents: {
    list: [{
      id: "main",
      tools: { allow: ["janee"] }
    }]
  }
}

Your agent now has these tools:

  • janee_list_services β€” Discover available APIs
  • janee_execute β€” Make API requests through Janee

The plugin spawns janee serve automatically. All requests are logged to ~/.janee/logs/.


MCP Tools

Janee exposes three MCP tools:

ToolDescription
list_servicesDiscover available APIs and their policies
executeMake an API request through Janee (HTTP proxy mode)
execRun a CLI command with injected credentials (exec mode)
manage_credentialView, grant, or revoke access to agent-scoped credentials
reload_configReload config from disk after adding/removing services (available when started with janee serve)

Agents discover what's available, then call APIs through Janee. Same audit trail, same protection.


Request Policies

Control exactly what requests each capability can make using rules:

capabilities:
  stripe_readonly:
    service: stripe
    ttl: 1h
    rules:
      allow:
        - GET *
      deny:
        - POST *
        - PUT *
        - DELETE *

  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 *

How rules work:

  1. deny patterns are checked first β€” explicit deny always wins
  2. Then allow patterns are checked β€” must match to proceed
  3. No rules defined β†’ allow all (backward compatible)
  4. Rules defined but no match β†’ denied by default

Pattern format: METHOD PATH

  • GET * β†’ any GET request
  • POST /v1/charges/* β†’ POST to /v1/charges/ and subpaths
  • * /v1/customers β†’ any method to /v1/customers
  • DELETE /v1/customers/* β†’ DELETE any customer

This makes security real: Even if an agent lies about its "reason", it can only access the endpoints the policy allows. Enforcement happens server-side.


CLI Reference

janee init                    # Set up ~/.janee/ with example config
janee add                     # Add a service (interactive)
janee add stripe -u https://api.stripe.com -k sk_xxx  # Add with args
janee remove <service>        # Remove a service
janee remove <service> --yes  # Remove without confirmation
janee list                    # List configured services
janee list --json             # Output as JSON (for integrations)
janee search [query]          # Search service directory
janee search stripe --json    # Search with JSON output
janee cap list                # List capabilities
janee cap list --json         # List capabilities as JSON
janee cap add <name> --service <service>  # Add capability
janee cap edit <name>         # Edit capability
janee cap remove <name>       # Remove capability
janee serve                   # Start MCP server (stdio, default)
janee serve --transport http --port 9100  # Start with HTTP transport (for containers)
janee serve --authority https://janee.example.com --runner-key $JANEE_RUNNER_KEY  # Runner mode
janee authority --runner-key $JANEE_RUNNER_KEY  # Start authority API
janee logs                    # View audit log
janee logs -f                 # Tail audit log
janee logs --json             # Output as JSON
janee sessions                # List active sessions
janee sessions --json         # Output as JSON
janee revoke <id>             # Kill a session

Non-interactive Setup (for AI agents)

AI agents can't respond to interactive prompts. Use --*-from-env flags to read credentials from environment variables β€” this keeps secrets out of the agent's context window:

# Bearer auth (Stripe, OpenAI, etc.)
janee add stripe -u https://api.stripe.com --auth-type bearer --key-from-env STRIPE_KEY

# HMAC auth (Bybit)
janee add bybit --auth-type hmac-bybit --key-from-env BYBIT_KEY --secret-from-env BYBIT_SECRET

# HMAC auth with passphrase (OKX)
janee add okx --auth-type hmac-okx --key-from-env OKX_KEY --secret-from-env OKX_SECRET --passphrase-from-env OKX_PASS

# GitHub App auth (short-lived tokens)
janee add github --auth-type github-app --app-id-from-env GH_APP_ID --pem-from-env GH_PEM --installation-id-from-env GH_INSTALL_ID

# Twitter/X OAuth 1.0a (per-request signing)
janee add twitter --consumer-key $TWITTER_CONSUMER_KEY --consumer-secret $TWITTER_CONSUMER_SECRET \
  --access-token $TWITTER_ACCESS_TOKEN --access-token-secret $TWITTER_ACCESS_TOKEN_SECRET

# AWS SigV4 (SES, S3, etc.)
janee add aws-ses --access-key-id $AWS_ACCESS_KEY_ID --secret-access-key $AWS_SECRET_ACCESS_KEY \
  --region us-east-1 --aws-service ses

When all required credentials are provided via flags, Janee:

  • Never opens readline (no hanging on stdin)
  • Auto-creates a capability with sensible defaults (1h TTL, auto-approve)

You can also edit ~/.janee/config.yaml directly if you prefer.


How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  AI Agent   │─────▢│  Janee   │─────▢│  Stripe β”‚
β”‚             β”‚ MCP  β”‚   MCP    β”‚ HTTP β”‚   API   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                   β”‚
   No key           Injects key
                    + logs request
  1. Agent calls execute MCP tool with capability, method, path
  2. Janee looks up service config, decrypts the real key
  3. Makes HTTP request to real API with key
  4. Logs: timestamp, service, method, path, status
  5. Returns response to agent

Agent never touches the real key.

πŸ“ Deep dive: See Architecture & Security Model for detailed diagrams, threat model, and comparison with alternatives.


Security

  • Encryption: Keys stored with AES-256-GCM
  • Agent identity: Derived from clientInfo.name in the MCP initialize handshake β€” no custom headers needed
  • Agent isolation: Each agent gets its own session with isolated identity (HTTP transport creates a Server+Transport per session)
  • Access control: Per-capability allowedAgents whitelist + server-wide defaultAccess policy
  • Credential scoping: Agent-created credentials default to agent-only
  • Audit log: Every request logged to ~/.janee/logs/
  • Sessions: Time-limited, revocable
  • Kill switch: janee revoke or delete config

Docker

Run Janee as a container β€” no local Node.js required:

# Build
docker build -t janee .

# Run in HTTP mode
docker run -d -p 3000:3000 \
  -v ~/.janee:/root/.janee:ro \
  janee --transport http --port 3000 --host 0.0.0.0

Or use Docker Compose:

mkdir -p config && cp ~/.janee/config.yaml config/
docker compose up -d

For Claude Desktop with Docker, see Docker docs.


Contributing

We welcome contributions! Please read CONTRIBUTING.md before submitting a PR β€” it includes the required PR checklist (tests, changelog, version bump, etc.).


License

MIT β€” Built by True and Useful LLC


Stop giving AI agents your keys. Start controlling access. πŸ”