Authentication

MangroveAI supports multiple authentication methods to accommodate different use cases.

Authentication Methods

MethodBest ForFlow
Firebase OAuthWeb apps, mobile appsFirebase SSO -> Exchange for JWT -> Use JWT
API KeysScripts, server-to-server, agentsGenerate key via portal -> Use in Authorization header
GCP IAM TokensCloud infrastructuregcloud auth print-identity-token -> Use in header

Step 1: Client-Side Firebase Authentication

import { initializeApp } from 'firebase/app';
import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "your-project.firebaseapp.com",
  projectId: "your-firebase-project"
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

const provider = new GoogleAuthProvider();
const result = await signInWithPopup(auth, provider);
const firebaseToken = await result.user.getIdToken();

Step 2: Exchange for MangroveAI JWT

curl -X POST https://api.mangrovedeveloper.ai/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "firebase_token": "YOUR_FIREBASE_TOKEN"
  }'
Response:
{
  "success": true,
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "user": {
    "id": "uuid",
    "name": "John Doe",
    "email": "john@example.com",
    "org_id": "uuid"
  }
}
Token Lifetimes:
  • Access token: 1 hour
  • Refresh token: 30 days

Step 3: Use JWT for API Requests

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://api.mangrovedeveloper.ai/api/v1/signals

Generate an API Key

Requires an active JWT session first:
curl -X POST https://api.mangrovedeveloper.ai/api/v1/auth/api-keys \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Server Key",
    "scopes": ["strategy:read", "strategy:create", "backtest:create"],
    "expires_days": 365
  }'
Response:
{
  "success": true,
  "key": "dev_a1b2c3d4e5f6...",
  "key_id": "uuid-here",
  "key_prefix": "dev_a1b2c3d4",
  "name": "Production Server Key",
  "created_at": "2025-12-01T10:00:00Z",
  "expires_at": "2026-12-01T10:00:00Z"
}
Save the key value immediately. It is only shown once and cannot be retrieved later.

Use the API Key

curl -H "Authorization: Bearer dev_a1b2c3d4e5f6..." \
  https://api.mangrovedeveloper.ai/api/v1/signals

Token Refresh

When your access token expires, use the refresh token to obtain a new one:
curl -X POST https://api.mangrovedeveloper.ai/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "YOUR_REFRESH_TOKEN"
  }'

API Endpoints

MethodEndpointDescription
POST/api/v1/auth/loginExchange Firebase token for JWT
POST/api/v1/auth/refreshRefresh access token
GET/api/v1/auth/profileGet current user profile
PUT/api/v1/auth/profileUpdate user profile
POST/api/v1/auth/api-keysGenerate new API key
GET/api/v1/auth/api-keysList all API keys
DELETE/api/v1/auth/api-keys/{key_id}Revoke an API key

Authorization Levels

LevelRequiredAccess
Authenticated UserValid JWT or API keyOwn data (strategies, backtests, conversations) within your tier limits
UnauthenticatedNoneHealth checks, Swagger docs, the x402-gated wallet-paid surface (no signup)

API Key Scopes

Every authenticated endpoint requires a specific scope. When you mint a key with a non-empty scopes array, each request is checked against that list and a missing scope returns 403 INSUFFICIENT_PERMISSIONS with the exact scope it needed (for example, API key does not have scope: strategy:update_status). Two rules govern what a key can actually do:
  • Empty scopes: [] means full role-based access — the key inherits every scope its organization role permits. Pass an explicit list only to restrict a key below its role.
  • Scopes are baked at mint time and your role gates them. A viewer role only ever gets the read scopes below, regardless of what you request; to write you need a member (or higher) key. Changing a role later does not re-scope an already-minted key — revoke and re-mint.
Scope strings use the resource:action form (note: strategy:read, not read:strategies). Required scope by endpoint:
EndpointMethodRequired scope
/api/v1/strategiesPOSTstrategy:create
/api/v1/strategies, /api/v1/strategies/{id}GETstrategy:read
/api/v1/strategies/{id} (update, incl. execution_config)PUTstrategy:update_status
/api/v1/strategies/{id}/statusPATCHstrategy:update_status
/api/v1/strategies/{id}/execution-statePATCHstrategy:update_status
/api/v1/strategies/{id}DELETEstrategy:delete
/api/v1/execution/evaluate/{id}, /evaluate, /evaluate/bulkPOSTstrategy:read
/api/v1/execution/portfolioGETstrategy:read
/api/v1/execution/accounts, /positions, /tradesGETposition:read
/api/v1/execution/accountsPOSTposition:create
/api/v1/backtesting/backtest, /backtest/bulkPOSTbacktest:create
/api/v1/backtesting/backtest/{id}GETbacktest:read
/api/v1/signals/...GETsignal:read
/api/v1/signals/evaluatePOSTsignal:evaluate
/api/v1/oracle/backtest/...POSToracle:backtest
/api/v1/oracle/experiments/...POSToracle:sweep
/api/v1/oracle/data/queryPOSTdata:query
Updating a strategy’s execution_config (a PUT /strategies/{id}) requires the strategy:update_status scope — the same scope that guards status changes. A read-only (viewer) key cannot perform it. If you only need to evaluate a saved strategy, strategy:read is sufficient.

Error Responses

401 Unauthorized — Token missing, invalid, or expired. The response carries a hint with the expected header format and a docs link so the failure is self-explanatory:
{
  "error": "Unauthorized",
  "message": "Invalid or expired token",
  "hint": "Include 'Authorization: Bearer <API_KEY>' in the request header",
  "docs": "https://docs.mangrovedeveloper.ai/authentication"
}
A request sent with no credentials returns the same shape with "message": "Missing or invalid authentication token". 403 Forbidden — Insufficient permissions. The code is INSUFFICIENT_PERMISSIONS and the message names the exact scope (or role permission) that was missing, so you know which scope to add when re-minting the key (see API Key Scopes):
{
  "error": "authorization_error",
  "message": "API key does not have scope: strategy:update_status",
  "code": "INSUFFICIENT_PERMISSIONS"
}

Security Best Practices

  1. Never commit tokens or API keys to version control
  2. Use environment variables for API keys in production
  3. Rotate API keys regularly — generate new keys, revoke old ones
  4. Use minimal scopes — only request the permissions you need
  5. Set expiration dates on API keys
  6. Store access tokens in memory (not localStorage) for frontend apps
  7. Store refresh tokens in httpOnly secure cookies or secure storage