Authentication

Agent700 API Authentication Guide

Overview

The Agent700 Platform API uses multiple authentication methods to provide secure access to its resources. This guide covers all authentication methods, token management, security features, and best practices.

Base URL: https://api.agent700.ai/api

Table of Contents

  1. Authentication Methods
  2. JWT Bearer Token Authentication
  3. App Password Authentication
  4. MCP Service Authentication
  5. Google OAuth Authentication
  6. Token Management
  7. Security Features
  8. Code Examples
  9. Best Practices

Authentication Methods

The Agent700 API supports three primary authentication methods:

  1. JWT Bearer Tokens - Primary method for web and mobile applications
  2. App Passwords - For programmatic access and API integrations
  3. MCP Service API Keys - For internal MCP service communication

Additionally, users can authenticate via:

  • Google OAuth - Social login integration

JWT Bearer Token Authentication

JWT (JSON Web Token) Bearer authentication is the primary method for accessing the Agent700 API. All authenticated endpoints require a valid JWT access token in the Authorization header.

Obtaining Access Tokens

Access tokens are obtained through one of three login endpoints:

1. Email/Password Login

Endpoint: POST /api/auth/login

Request:

{
  "email": "[email protected]",
  "password": "SecurePass123!"
}

Response:

{
  "email": "[email protected]",
  "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "expiresIn": 28800,
  "organizationsRoles": [
    {
      "name": "Public",
      "id": "org-uuid",
      "role": "consumer"
    }
  ],
  "defaultOrganization": {
    "id": "org-uuid",
    "name": "Public"
  }
}

Security Headers (automatically set):

  • Set-Cookie: refreshToken=...; HttpOnly; Secure; SameSite=Strict

2. Google OAuth Login

Endpoint: POST /api/auth/googleauth

Request:

{
  "token": "google-id-token-from-oauth"
}

Response: Same format as email/password login

3. App Password Login

Endpoint: POST /api/auth/app-login

Request:

{
  "token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Response: Same format as email/password login, with additional fields:

{
  "email": "[email protected]",
  "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "expiresIn": 43200,
  "organizationsRoles": [...],
  "defaultOrganization": {...},
  "authType": "app_password",
  "appPasswordName": "My API Integration"
}

Using Access Tokens

Include the access token in the Authorization header of all authenticated requests:

Authorization: Bearer <your_access_token>

Example:

curl -X GET https://api.agent700.ai/api/agents \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

Token Structure

JWT tokens contain the following claims:

  • sub (subject): User ID
  • exp (expiration): Token expiration timestamp
  • iat (issued at): Token issuance timestamp
  • auth_type: Authentication method used (password, google_oauth, app_password)
  • app_password_id: App password ID (if using app password authentication)

Token Expiration

  • Login tokens: 8 hours (configurable via ACCESS_TOKEN_LOGIN_TIMEOUT_HOURS)
  • Refresh tokens: 4 hours (configurable via ACCESS_TOKEN_REFRESH_TIMEOUT_HOURS)
  • App password tokens: 12 hours (configurable via APP_PASSWORD_JWT_EXPIRY_HOURS)

When a token expires, you'll receive a 401 Unauthorized response. Use the refresh token mechanism to obtain a new access token.


App Password Authentication

App passwords provide a secure way to authenticate programmatic access without using your primary account password. They're ideal for:

  • API integrations
  • CI/CD pipelines
  • Third-party applications
  • Automated scripts

Creating App Passwords

Endpoint: POST /api/auth/app-passwords

Authentication: Requires JWT Bearer token

Request:

{
  "name": "My API Integration",
  "permissions": {}
}

Response:

{
  "id": "app-password-uuid",
  "name": "My API Integration",
  "token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "createdAt": "2025-01-15T10:00:00Z",
  "expiresAt": "2026-01-15T10:00:00Z",
  "isActive": true,
  "warning": "This token will only be shown once. Store it securely."
}

Important: The full token is only displayed once during creation. Store it securely immediately.

App Password Format

App passwords follow this format:

  • Prefix: app_a7_
  • Total length: 39 characters
  • Format: app_a7_ + 32 hexadecimal characters

Example: app_a7_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

Using App Passwords

App passwords can be used in two ways:

1. As Bearer Token (Direct Authentication)

Use the app password directly as a Bearer token:

curl -X GET https://api.agent700.ai/api/agents \
  -H "Authorization: Bearer app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

2. Via App Login Endpoint

Exchange the app password for a JWT access token:

curl -X POST https://api.agent700.ai/api/auth/app-login \
  -H "Content-Type: application/json" \
  -d '{"token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'

Managing App Passwords

List App Passwords: GET /api/auth/app-passwords

  • Returns all active app passwords (without full tokens)

Delete App Password: DELETE /api/auth/app-passwords/<password_id>

  • Revokes an app password immediately

App Password Security

  • Expiration: App passwords have a default expiration (typically 1 year)
  • Rate Limiting: App password authentication is rate-limited (30 requests per 60 seconds by default)
  • Lockout: Failed authentication attempts can temporarily lock an app password
  • Revocation: App passwords can be revoked at any time

MCP Service Authentication

The MCP (Model Context Protocol) service uses API key authentication for internal service-to-service communication.

API Key Format

MCP service authentication uses the X-API-Key header:

X-API-Key: <your-api-key>

When to Use

MCP service authentication is used when:

  • The Flask application communicates with the MCP service
  • Internal service-to-service requests are made
  • MCP endpoints are accessed directly

Configuration

MCP API keys are configured via environment variables:

# MCP Service
export MCP_API_KEY="your-secure-api-key-here"

# Flask Application
export MCP_SERVICE_URL="http://localhost:8000"
export MCP_API_KEY="your-secure-api-key-here"

Google OAuth Authentication

Agent700 supports Google OAuth for social login integration.

OAuth Flow

  1. Initiate OAuth: Redirect user to Google OAuth consent screen
  2. User Consent: User grants permissions
  3. Token Exchange: Exchange Google ID token for Agent700 access token
  4. Authentication: Use Agent700 access token for API requests

Token Exchange

Endpoint: POST /api/auth/googleauth

Request:

{
  "token": "google-id-token-from-oauth-flow"
}

Response: Same format as email/password login

Example:

curl -X POST https://api.agent700.ai/api/auth/googleauth \
  -H "Content-Type: application/json" \
  -d '{"token": "google-id-token-here"}'

OAuth Configuration

Google OAuth requires the following configuration:

  • Google Client ID
  • Google Client Secret
  • Redirect URI
  • JavaScript origins

These are configured via environment variables (see shared/config.py).


Token Management

Access Token Lifecycle

  1. Obtain Token: Login via one of the authentication methods
  2. Use Token: Include in Authorization header for API requests
  3. Token Expiration: Token expires after configured timeout
  4. Refresh Token: Use refresh token to obtain new access token
  5. Token Rotation: New refresh token issued on each refresh

Refresh Token Mechanism

Refresh tokens are stored in httpOnly cookies and automatically managed by the client. The refresh endpoint handles token rotation automatically.

Endpoint: POST /api/auth/refresh

Request: No body required (refresh token from cookie)

Response:

{
  "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "expiresIn": 14400,
  "message": "Token refreshed successfully"
}

Security Headers (automatically set):

  • Set-Cookie: refreshToken=...; HttpOnly; Secure; SameSite=Strict

Device Fingerprinting

The Agent700 API uses device fingerprinting to enhance security:

Fingerprint Components:

  • User-Agent header
  • Accept-Language header
  • Accept-Encoding header
  • Screen resolution (via X-Screen-Resolution header)
  • Timezone offset (via X-Timezone-Offset header)

Fingerprint Matching:

  • Exact match: 100% fingerprint match
  • Fuzzy match: 85% similarity threshold for legitimate device changes
  • Trusted devices: Up to 5 trusted device fingerprints per user

Client-Side Headers (optional but recommended):

X-Screen-Resolution: 1920x1080
X-Timezone-Offset: -300

Token Rotation

Token rotation is automatic and occurs on every refresh:

  • Old refresh token is invalidated
  • New refresh token is issued
  • New access token is issued
  • Device fingerprint is validated

This prevents token reuse and enhances security.


Security Features

Device Fingerprinting

Device fingerprinting binds tokens to specific device characteristics, preventing unauthorized access from different devices.

Benefits:

  • Prevents token theft and cross-device usage
  • Allows legitimate device changes (fuzzy matching)
  • Maintains up to 5 trusted devices per user

Token Rotation

Every token refresh issues a new refresh token, invalidating the previous one:

  • Prevents token replay attacks
  • Limits exposure window if token is compromised
  • Maintains session continuity for legitimate users

Rate Limiting

Authentication endpoints are rate-limited to prevent abuse:

  • App password authentication: 30 requests per 60 seconds (configurable)
  • Login attempts: Monitored and logged
  • Token refresh: Rate-limited to prevent abuse

Security Event Logging

All authentication events are logged for security auditing:

  • user_login - Successful login
  • token_refresh_success - Successful token refresh
  • refresh_token_validation_failed - Failed refresh attempt
  • app_password_auth_success - Successful app password authentication
  • app_password_auth_failed - Failed app password authentication
  • user_logout - Explicit logout

httpOnly Cookies

Refresh tokens are stored in httpOnly cookies:

  • httpOnly: Prevents JavaScript access (XSS protection)
  • Secure: Only sent over HTTPS
  • SameSite=Strict: CSRF protection

Code Examples

JavaScript/TypeScript

Login and Store Token

async function login(email, password) {
  const response = await fetch('https://api.agent700.ai/api/auth/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email, password }),
    credentials: 'include' // Important for cookies
  });
  
  if (!response.ok) {
    throw new Error('Login failed');
  }
  
  const data = await response.json();
  // Store access token in memory (not localStorage for security)
  sessionStorage.setItem('accessToken', data.accessToken);
  return data;
}

Making Authenticated Requests

async function getAgents() {
  const token = sessionStorage.getItem('accessToken');
  
  const response = await fetch('https://api.agent700.ai/api/agents', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    credentials: 'include'
  });
  
  if (response.status === 401) {
    // Token expired, refresh it
    await refreshToken();
    return getAgents(); // Retry request
  }
  
  return response.json();
}

Token Refresh

async function refreshToken() {
  const response = await fetch('https://api.agent700.ai/api/auth/refresh', {
    method: 'POST',
    credentials: 'include' // Sends httpOnly cookie
  });
  
  if (!response.ok) {
    // Refresh failed, redirect to login
    window.location.href = '/login';
    return;
  }
  
  const data = await response.json();
  sessionStorage.setItem('accessToken', data.accessToken);
  return data;
}

Using App Password

async function authenticateWithAppPassword(appPassword) {
  const response = await fetch('https://api.agent700.ai/api/auth/app-login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ token: appPassword }),
  });
  
  const data = await response.json();
  sessionStorage.setItem('accessToken', data.accessToken);
  return data;
}

// Or use directly as Bearer token
async function useAppPasswordDirectly(appPassword) {
  const response = await fetch('https://api.agent700.ai/api/agents', {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${appPassword}`,
    },
  });
  
  return response.json();
}

Python

Login and Store Token

import requests

def login(email, password):
    response = requests.post(
        'https://api.agent700.ai/api/auth/login',
        json={'email': email, 'password': password}
    )
    response.raise_for_status()
    data = response.json()
    return data['accessToken'], response.cookies

# Usage
access_token, cookies = login('[email protected]', 'password123')

Making Authenticated Requests

def get_agents(access_token, cookies=None):
    headers = {
        'Authorization': f'Bearer {access_token}',
        'Content-Type': 'application/json'
    }
    
    response = requests.get(
        'https://api.agent700.ai/api/agents',
        headers=headers,
        cookies=cookies
    )
    
    if response.status_code == 401:
        # Token expired, refresh it
        new_token = refresh_token(cookies)
        return get_agents(new_token, cookies)
    
    response.raise_for_status()
    return response.json()

Token Refresh

def refresh_token(cookies):
    response = requests.post(
        'https://api.agent700.ai/api/auth/refresh',
        cookies=cookies
    )
    response.raise_for_status()
    data = response.json()
    return data['accessToken']

Using App Password

def authenticate_with_app_password(app_password):
    # Method 1: Exchange for JWT token
    response = requests.post(
        'https://api.agent700.ai/api/auth/app-login',
        json={'token': app_password}
    )
    response.raise_for_status()
    return response.json()['accessToken']

# Method 2: Use directly as Bearer token
def use_app_password_directly(app_password):
    headers = {
        'Authorization': f'Bearer {app_password}',
        'Content-Type': 'application/json'
    }
    
    response = requests.get(
        'https://api.agent700.ai/api/agents',
        headers=headers
    )
    response.raise_for_status()
    return response.json()

cURL Examples

Email/Password Login

curl -X POST https://api.agent700.ai/api/auth/login \
  -H "Content-Type: application/json" \
  -H "X-Screen-Resolution: 1920x1080" \
  -H "X-Timezone-Offset: -300" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!"
  }' \
  -c cookies.txt

Making Authenticated Request

curl -X GET https://api.agent700.ai/api/agents \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  -b cookies.txt

Token Refresh

curl -X POST https://api.agent700.ai/api/auth/refresh \
  -H "Content-Type: application/json" \
  -H "X-Screen-Resolution: 1920x1080" \
  -H "X-Timezone-Offset: -300" \
  -b cookies.txt

App Password Login

curl -X POST https://api.agent700.ai/api/auth/app-login \
  -H "Content-Type: application/json" \
  -d '{
    "token": "app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }'

Using App Password Directly

curl -X GET https://api.agent700.ai/api/agents \
  -H "Authorization: Bearer app_a7_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

MCP Service Authentication

curl -X GET http://localhost:8000/mcp/servers \
  -H "X-API-Key: your-api-key-here"

Best Practices

Token Storage

DO:

  • Store access tokens in memory (sessionStorage) for web applications
  • Use httpOnly cookies for refresh tokens (handled automatically)
  • Clear tokens on logout
  • Implement token refresh logic

DON'T:

  • Store tokens in localStorage (vulnerable to XSS)
  • Store tokens in plain text files
  • Commit tokens to version control
  • Share tokens between users

Security Recommendations

  1. Always use HTTPS in production
  2. Implement token refresh before expiration
  3. Handle 401 responses by refreshing tokens
  4. Monitor security events for suspicious activity
  5. Rotate app passwords regularly
  6. Use device fingerprinting headers when available
  7. Implement proper error handling for authentication failures

Token Refresh Strategies

Proactive Refresh:

  • Refresh token 5 minutes before expiration
  • Prevents failed requests due to expired tokens

Reactive Refresh:

  • Refresh token when receiving 401 Unauthorized
  • Retry original request after refresh

Example Implementation:

// Proactive refresh
setInterval(async () => {
  const tokenExpiry = getTokenExpiry();
  const now = Date.now();
  const fiveMinutes = 5 * 60 * 1000;
  
  if (tokenExpiry - now < fiveMinutes) {
    await refreshToken();
  }
}, 60000); // Check every minute

App Password Best Practices

  1. Use descriptive names for app passwords
  2. Limit app password scope with permissions
  3. Revoke unused app passwords regularly
  4. Store app passwords securely (password manager, secrets manager)
  5. Never share app passwords between services
  6. Monitor app password usage for suspicious activity

Error Handling

Always handle authentication errors gracefully:

try {
  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });
  
  if (response.status === 401) {
    // Token expired or invalid
    await refreshToken();
    // Retry request
  } else if (response.status === 403) {
    // Insufficient permissions
    throw new Error('Access denied');
  }
  
  return response.json();
} catch (error) {
  // Handle error appropriately
  console.error('Request failed:', error);
}


Support

For authentication issues or questions: