Authentication

The Geog API uses token-based authentication. API tokens are self-issued JWTs signed with RSA keys.

API Tokens

API tokens are self-issued JWTs signed with RSA keys managed through JWKS:

ClaimDescription
subToken ID (tok_*)
org_idOrganization ID
scopeGranted permission scopes
token_typeapi_token
audAPI URL (audience)
issAPI URL (issuer)

Example decoded payload:

{
  "sub": "tok_a1b2c3d4e5f6",
  "org_id": "org_xyz789",
  "scope": "tiles:read",
  "token_type": "api_token",
  "aud": "https://api.geog.dev",
  "iss": "https://api.geog.dev",
  "iat": 1699999999,
  "exp": 1731535999
}

Short-Lived Access Tokens (Token Exchange)

For frontend applications (MapLibre, Leaflet, etc.), exchange long-lived API tokens for short-lived access tokens (1-4 hours) to avoid exposing credentials in client-side code.

See the Token Exchange reference for the full endpoint specification, or the Token Exchange Guide for implementation examples.

Permission Scopes

The API uses scopes to control access to specific resources:

ScopeDescriptionEndpoints
tiles:readRead vector tilesGET /v1/tiles/*
billing:manageManage organization billingGET/POST /v1/billing/*
admin:accessAccess admin endpointsGET /v1/admin/*

Authentication Flow

sequenceDiagram
    participant Client
    participant API as Geog API

    Client->>API: Request with Authorization: Bearer {token}
    Note over API: Verify JWT signature + claims
    alt Valid token
        API->>Client: 200 Response
    else Invalid / expired
        API->>Client: 401 Unauthorized
    else Insufficient scope
        API->>Client: 403 Forbidden
    end

Error Responses

401 Unauthorized

Returned when authentication fails:

{
  "error": "Unauthorized",
  "message": "Missing or invalid authorization header",
  "code": "AUTH_REQUIRED"
}

Common causes:

  • Missing Authorization header
  • Invalid or malformed JWT
  • Expired token

403 Forbidden

Returned when authorization fails:

{
  "error": "Forbidden",
  "message": "Insufficient permissions",
  "code": "INSUFFICIENT_SCOPE"
}

Common causes:

  • Token lacks required scope

Security Best Practices

Token Storage

  • API tokens: Store long-lived tokens securely on backend servers
  • Frontend: Use short-lived tokens from token exchange endpoint
  • Never store tokens in localStorage or expose in URLs

Scope Management

Request only the scopes your application needs:

  • Minimizes security exposure
  • Follows principle of least privilege

See Also