GaiaExGaiaEx
API

Security Best Practices

Secure your GaiaEx API integration: credential management, IP whitelisting, key rotation intervals, and audit logging for production systems.

Security Best Practices

API key security is your responsibility. A compromised key can execute trades against your deposited balance and read your account data. It cannot move funds off the platform — withdrawals, deposits, and on-chain transfers all require the user's embedded-wallet signature plus a passkey step-up, which are only available in the mobile app. This guide covers battle-tested practices used by institutional trading desks.

NEVER HARDCODE CREDENTIALS

Never paste API keys or secrets directly into source code, scripts, notebooks, or commit them to version control. A single leaked credential in a public GitHub repo can be exploited within minutes by automated scanners.

Credential Separation with config.json

The recommended approach is to store credentials in a separate config.json file that is never committed to version control.

Step 1: Create config.json

{
    "api_key": "a1b2c3d4e5f6789012345678abcdef00",
    "api_secret": "s3cr3t_k3y_n3v3r_sh4r3_th1s_w1th_4ny0n3",
    "user_address": "0xA6E3c04eF78427b5B53F43CDBA881d7E15B0bccD",
    "base_url": "https://openapi.gaiaex.com/v1/trade"
}

Step 2: Add to .gitignore

# .gitignore
config.json
*.secret
.env
.env.*

Step 3: Load in Your Code

Python:

import json

with open("config.json") as f:
    config = json.load(f)

API_KEY = config["api_key"]
API_SECRET = config["api_secret"]
ADDRESS = config["user_address"]

JavaScript / Node.js:

const fs = require('fs');
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'));

const API_KEY = config.api_key;
const API_SECRET = config.api_secret;
const ADDRESS = config.user_address;

Rust:

use serde::Deserialize;
use std::fs;

#[derive(Deserialize)]
struct Config {
    api_key: String,
    api_secret: String,
    user_address: String,
}

let cfg: Config = serde_json::from_str(
    &fs::read_to_string("config.json")?
)?;

PROVIDE A TEMPLATE

Distribute a config.example.json with placeholder values so collaborators know the expected format without exposing real credentials.

{
    "api_key": "PASTE_YOUR_API_KEY_HERE",
    "api_secret": "PASTE_YOUR_API_SECRET_HERE",
    "user_address": "0xYOUR_WALLET_ADDRESS",
    "base_url": "https://openapi.gaiaex.com/v1/trade"
}

Environment Variables

For CI/CD pipelines, Docker containers, and cloud deployments, environment variables are the standard approach.

# Set in your shell profile, .env file, or CI secrets
export GAIAEX_API_KEY="a1b2c3d4e5f6789012345678abcdef00"
export GAIAEX_API_SECRET="s3cr3t_k3y_n3v3r_sh4r3_th1s"
export GAIAEX_ADDRESS="0xA6E3c04eF78427b5B53F43CDBA881d7E15B0bccD"

Python:

import os

API_KEY = os.environ["GAIAEX_API_KEY"]
API_SECRET = os.environ["GAIAEX_API_SECRET"]
MethodBest ForRisk Level
config.jsonLocal development, personal botsLow (if .gitignore'd)
Environment variablesCI/CD, Docker, cloud serversLow
Hardcoded in sourceNeverCritical — never do this

IP Whitelisting

Lock your API key to specific IP addresses. Even if the key leaks, it cannot be used from unauthorized locations.

{
    "ip_whitelist": ["203.0.113.50", "198.51.100.0/24"]
}

Configure IP whitelisting when creating an API key via the GaiaEx mobile app or the POST /api-keys endpoint.

ScenarioRecommendation
VPS/dedicated serverWhitelist the server's static IP
Home connectionUse a VPN with a static IP, then whitelist that
CI/CD pipelineWhitelist your CI provider's IP range
Development (dynamic IP)Use a separate dev key with read-only permissions

TIP

If your IP changes frequently, create two API keys: one locked-down key for production (with IP whitelist + trade permission), and one read-only key for development (no IP restriction, read-only permission).

Permission Scoping (Principle of Least Privilege)

GaiaEx API keys support granular permissions. Only grant the minimum permissions needed.

PermissionAllowsUse Case
readView balances, positions, orders, market dataMonitoring dashboards, analytics bots
tradePlace, cancel, modify orders; close positionsTrading bots, strategy execution

Recommendation:

  • Monitoring scripts → ["read"] only
  • Trading bots → ["read", "trade"]
  • Never create "all permissions" keys unless absolutely necessary

Key Rotation

Rotate API keys regularly — especially after team member departures, suspected leaks, or security incidents.

Rotation Procedure

  1. Create a new key via the GaiaEx app or POST /api-keys
  2. Update your config.json or environment variables with the new key
  3. Verify the new key works (call GET /time or GET /health)
  4. Revoke the old key via DELETE /api-keys/{key_id}

Recommended rotation schedule:

ScenarioFrequency
Production trading botEvery 30–90 days
After team member leavesImmediately
After suspected leakImmediately
Development / testing keyEvery 90 days

Audit & Monitoring

Monitor your API key activity for unauthorized access.

  • Check the audit log via GET /api-keys/{key_id}/audit — shows all API calls made with that key
  • Monitor order history — unexpected orders may indicate compromised keys
  • Set up alerts — use User Data Stream WebSocket to get real-time notifications of trades and balance changes

What to Watch For

SignalAction
API calls from unknown IPsRotate key immediately, enable IP whitelist
Orders you didn't placeRevoke key, cancel all orders, secure wallet
Authentication failures spikeSomeone may be brute-forcing — enable IP whitelist
Rate limit hits you didn't causeYour key may be in use elsewhere — rotate

Security Checklist

#ItemStatus
1Credentials in config.json or environment variables — never hardcoded
2config.json is in .gitignore
3IP whitelist enabled for production keys
4Minimum permissions granted (read-only where possible)
5API keys rotated every 30–90 days
6Separate keys for production and development
7Audit logs reviewed weekly
8config.example.json template committed for team reference
9WebSocket user stream connected for real-time trade monitoring