Skip to main content
The Gateway API provides authentication endpoints for admin login and guest token generation.

Endpoints

POST /auth/login

Authenticate an admin user and receive a JWT token.
Admin credentials are stored in R2 bucket (metacogna-accounts) with SHA-256 hashed passwords.

Request Body

{
  "username": "admin",
  "password": "plaintext-password"
}

Response (Success)

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "username": "admin",
    "role": "admin"
  }
}

Response (Error)

{
  "route": "AUTH",
  "status": 401,
  "code": "INVALID_CREDENTIALS",
  "message": "Invalid credentials",
  "requestId": "uuid",
  "timestamp": "2024-01-01T00:00:00.000Z"
}

Authentication Flow

POST /auth/guest

Generate a guest token for unauthenticated access to certain routes.

Request Body

{
  "route": "BUILD" // Optional: "BUILD", "KV", "CORE" (defaults to "BUILD")
}

Response

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "route": "BUILD"
}

JWT Token Structure

Tokens are signed JWTs with the following claims:
interface GatewayTokenClaims {
  projectId: string;        // User ID or "guest"
  route: ProjectRoute;      // "AUTH" | "KV" | "BUILD" | "CORE"
  scopes: string[];         // ["admin"] | ["guest"]
  environment: string;      // "staging" | "production"
  issuedBy: string;         // "gateway.metacogna.ai"
}

Default Values

  • Issuer: gateway.metacogna.ai
  • Audience: metacogna-clients
  • Algorithm: HS256
  • Expiration: 1h (configurable)

Credential Storage

Admin credentials are stored in R2 bucket metacogna-accounts: Path: auth/admins/{username}.json Structure:
{
  "username": "admin",
  "salt": "random-salt-string",
  "hash": "sha256-hash-of-salt+password",
  "role": "admin"
}

Password Hashing

Passwords are hashed using SHA-256:
// Pseudocode
const salt = generateRandomSalt();
const hash = SHA256(salt + password);
// Store {salt, hash} in R2
During login, the gateway:
  1. Retrieves {salt, hash} from R2
  2. Computes SHA256(salt + providedPassword)
  3. Compares computed hash with stored hash

Token Usage

Include the token in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Route Access Rules

RouteToken RequiredToken Scopes
/buildAlwaysadmin or guest
/kvOptionalAny (if provided, must match route)
/coreOptionalAny (if provided, must match route)

Error Codes

CodeStatusDescription
INVALID_REQUEST400Missing username or password
INVALID_CREDENTIALS401Invalid username/password combination
MISSING_TOKEN401Required token not provided
INVALID_TOKEN403Token invalid or expired
ROUTE_MISMATCH403Token route doesn’t match requested route

Code Examples

Admin Login

const response = await fetch('https://api.metacogna.ai/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'admin',
    password: 'secure-password'
  })
});

const { token, user } = await response.json();
// Store token for subsequent requests

Guest Token Generation

const response = await fetch('https://api.metacogna.ai/auth/guest', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ route: 'BUILD' })
});

const { token } = await response.json();

Authenticated Request

const response = await fetch('https://api.metacogna.ai/build/projects', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});