Skip to content

Authentication ​

Go Bananas! supports two authentication methods: API keys for simple integrations and OAuth 2.1 for secure web and desktop applications.

Authentication Methods ​

MethodBest ForSetup Complexity
API KeysServer-to-server, scripts, CLI toolsSimple
OAuth 2.1Web apps, desktop apps, MCP clientsStandard

Quick Decision

  • Use API Keys for backend integrations and scripts
  • Use OAuth 2.1 for user-facing applications and third-party integrations

REST endpoints (/api/*) require API keys. OAuth access tokens are used for MCP endpoints (/mcp, and the legacy /sse transport kept for older clients; use /mcp).


Option 1: API Keys ​

API key authentication is the simplest way to authenticate. This section covers how it works and how to manage your credentials.

API Key Format ​

API keys follow a specific format:

TypeFormatPurpose
Livesk_live_xxxxx...Production use
Testsk_test_xxxxx...Development/testing

WARNING

Never expose your API keys in client-side code or public repositories.

Using Your API Key ​

MCP Requests ​

Remote HTTP OAuth is preferred when the client supports it:

bash
claude mcp add --transport http -s user go-bananas https://mcp.gobananasai.com

codex mcp add go-bananas --url https://mcp.gobananasai.com
codex mcp login go-bananas

Direct HTTP OAuth tokens are stored by the MCP client for https://mcp.gobananasai.com.

Local STDIO proxy works for Claude Desktop config files, older editors, and headless clients. Run browser login once:

bash
npx -y gobananas-cli auth login

Then configure:

json
{
  "mcpServers": {
    "go-bananas": {
      "command": "npx",
      "args": ["-y", "gobananas-mcp"],
      "env": {
        "GO_BANANAS_SERVER_URL": "https://your-server.workers.dev",
        "GO_BANANAS_MCP_TRANSPORT": "streamable-http"
      }
    }
  }
}

For CI/headless clients, add an API key to the same env object:

json
"GO_BANANAS_API_KEY": "sk_live_your_key_here"

Do not mix direct HTTP and STDIO configs under the same go-bananas server name/scope. gobananas-cli auth login only authenticates the STDIO proxy.

REST API Requests ​

For direct API calls, include the key in the X-API-Key header:

bash
curl https://your-server.workers.dev/api/images \
  -H "X-API-Key: sk_live_your_key_here"

Or use the Authorization header:

bash
curl https://your-server.workers.dev/api/images \
  -H "Authorization: Bearer sk_live_your_key_here"

Web Console ​

The web console authenticates via a login form that creates a session. For admin access, you'll need:

  1. A control plane user account (email/password)
  2. Appropriate role (admin or super_admin)

Authentication Flow ​

Authentication Flow

API key validation, tenant lookup, decryption, and limit checks

Multi-Tenant Isolation ​

Each API key belongs to exactly one tenant. When you authenticate:

  1. Data isolation: You can only access your tenant's images, characters, and settings
  2. Quota tracking: Usage is tracked against your tenant's limits
  3. Rate limiting: Your requests are rate-limited independently
Multi-Tenant Isolation

Complete data separation between tenants

Rate Limiting ​

Rate limits are enforced per-tenant:

Limit TypeDefaultCustomizable
Requests/minute60Yes (per tenant)
Concurrent requests10Yes

When rate limited, you'll receive a 429 Too Many Requests response:

json
{
  "error": "Rate limit exceeded",
  "retry_after": 30
}

Quotas ​

Tenants have configurable quotas:

QuotaDefaultDescription
Monthly storage1 GBTotal image storage per month
Images per request4Max images in single generation

When quota is exceeded:

json
{
  "error": "Storage quota exceeded",
  "used_mb": 1024,
  "limit_mb": 1024
}

Security Best Practices ​

Do's ​

✅ Store API keys in environment variables

bash
export NANO_BANANA_API_KEY="sk_live_xxx"

✅ Use different keys for development and production

# Development
sk_test_development_key

# Production
sk_live_production_key

✅ Rotate keys periodically

  • Request new keys from your administrator
  • Update all clients with new key
  • Deactivate old key

Don'ts ​

❌ Don't commit API keys to version control

bash
# Add to .gitignore
.env
**/secrets.json

❌ Don't expose keys in client-side code

javascript
// BAD - key exposed in browser
const apiKey = "sk_live_xxx";

// GOOD - call your backend instead
const response = await fetch("/api/generate");

❌ Don't share keys between tenants

Managing API Keys ​

For Users ​

Contact your administrator to:

  • Request new API keys
  • Rotate compromised keys
  • Increase quotas or rate limits

For Administrators ​

Use the Admin API to manage keys:

bash
# Create new API key for tenant
curl -X POST https://your-server/admin/tenants/tenant-id/api-keys \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"key_name": "Production Key", "type": "live"}'

Or use the web console Admin panel.

Control Plane Authentication ​

The web console uses session-based authentication:

Login Flow ​

Login Flow

Credential verification, session creation, and secure cookie storage

Login returns a sessionToken (used by the console) and sets an HttpOnly session cookie for OAuth authorization redirects.

Session Security ​

  • Sessions expire after 24 hours
  • Sessions are fingerprinted (IP + User-Agent)
  • Account lockout after 5 failed attempts (1 hour)

Roles ​

RoleCapabilities
adminManage own tenant, view users
super_adminCreate tenants, manage all users, full access

Error Responses ​

StatusErrorMeaning
401Invalid API keyKey not found or inactive
401Missing authenticationNo API key provided
402Quota exceededStorage or request limit reached
403ForbiddenInsufficient permissions
423Account lockedToo many failed login attempts
429Rate limit exceededToo many requests

Option 2: OAuth 2.1 ​

OAuth 2.1 provides secure, standards-compliant authentication for web applications, desktop apps, and MCP clients.

Key Features ​

  • PKCE Required: Proof Key for Code Exchange prevents authorization code interception
  • Dynamic Client Registration: Clients can register automatically without admin setup
  • Refresh Token Rotation: Enhanced security with automatic token rotation
  • Fine-grained Scopes: Request only the permissions your app needs

OAuth Flow Overview ​

┌──────────┐     ┌─────────────────┐     ┌────────────────┐
│  Client  │────▶│  /oauth/        │────▶│  MCP Resource  │
│   App    │     │  authorize      │     │  /mcp          │
└──────────┘     └─────────────────┘     └────────────────┘
     │                   │                      ▲
     │                   ▼                      │
     │           ┌─────────────┐               │
     │           │ User Login  │               │
     │           │ & Consent   │               │
     │           └─────────────┘               │
     │                   │                      │
     │           code + state                   │
     │◀──────────────────┘                      │
     │                                          │
     │         ┌─────────────────┐              │
     └────────▶│  /oauth/token   │──────────────┘
               │  (+ PKCE)       │   access_token
               └─────────────────┘

Quick Start ​

1. Register Your Client ​

bash
curl -X POST "https://gobananasai.com/oauth/register" \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My App",
    "redirect_uris": ["https://myapp.com/callback"]
  }'

2. Build Authorization URL ​

javascript
const authUrl = new URL('https://gobananasai.com/oauth/authorize');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', 'gobananas_abc123');
authUrl.searchParams.set('redirect_uri', 'https://myapp.com/callback');
authUrl.searchParams.set('code_challenge', codeChallenge);
authUrl.searchParams.set('code_challenge_method', 'S256');
authUrl.searchParams.set('scope', 'images:generate images:read');

If no session exists, browsers are redirected to the console login at /?return_to=.... Non-HTML clients receive a login_required JSON response with a login_url.

3. Exchange Code for Tokens ​

bash
curl -X POST "https://gobananasai.com/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "code_verifier=VERIFIER" \
  -d "client_id=gobananas_abc123" \
  -d "redirect_uri=https://myapp.com/callback"

4. Use Access Token ​

bash
curl "https://mcp.gobananasai.com" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method":"tools/list","params":{}}'

Available Scopes ​

ScopeDescription
images:generateGenerate new images
images:editEdit existing images
images:readRead image metadata
images:deleteDelete images
characters:manageCreate, update, delete characters
characters:readView character library
products:manageManage product references
products:readView product library
styles:manageManage style presets
styles:readView style presets
sessions:readView session history
analytics:readView usage analytics

Token Lifetimes ​

TokenLifetime
Authorization Code10 minutes
Access Token1 hour
Refresh Token30 days

For complete OAuth implementation details, see:

Next Steps ​

Released under the MIT License.