Menu

Authentication Overview

ApiCharge uses a token-based authentication system where access tokens are obtained through the Purchase Flow and then used to authenticate API requests. The authentication system enforces both route access and rate limiting based on the purchased ApiCharge Subscription.

Note: ApiCharge authentication requires that clients first complete the Purchase Flow to obtain a valid access token before accessing protected resources.

Authentication Flow Steps

  1. Client completes purchase flow and receives an unsigned access token
  2. Client signs the access token with their private key
  3. Client includes the signed token in API requests
  4. ApiCharge validates the token and enforces rate limits
  5. Request is forwarded to backend if authentication succeeds

Access Token Structure

After completing a purchase, clients receive an access token with this structure:

{
  "signableEntity": {
    "signingPubkey": "GBXDGHXCQVZUDDD4NNGBOGCXYQFKNBPIMJWW7GMUCQ2OJCPO7B3GIXWA",
    "signature": null,
    "expirationUnixTimeStamp": 1716384000,
    "signableEntity": {
      "signingPubkey": "GATCBZKXPNCVBKY5KLXSWLNUAXMUPARGW5JBSP75XYU6P3AK4JUMNXQ5",
      "signature": "J8KpLzrDCF7Y4kqt9DLZLsCNapQ7SiwsCXf6EPfCxmD2kZEhf9m2LjNPFSiYpRj2Y9TUKJSgNr9ivLnJdjwwMRDk",
      "signableEntity": {
        "routeId": "basic-api",
        "expirationUnixTimeStamp": 1716387600,
        "rateLimiterStrategies": [
          {
            "$type": "CallCount",
            "Count": 100
          }
        ],
        "clientAccount": "GBXDGHXCQVZUDDD4NNGBOGCXYQFKNBPIMJWW7GMUCQ2OJCPO7B3GIXWA",
        "sequenceNumber": 7283947621,
        "scaleOutVirtualNode": 42
      }
    }
  }
}

Token Structure

The AccessToken has a nested structure with dual expiration controls:

Dual Expiration Model

ApiCharge implements a dual expiration system for enhanced security:

The effective expiration is the earlier of these two times, allowing clients to create short-lived tokens from longer ApiCharge Subscriptions.

GrantedAccessToken Fields

Client Token Signing

Before using the access token, the client must add their own expiration time and sign the combined data with their private key.

Signing Process

  1. Client receives an AccessToken containing a server-signed GrantedAccessToken
  2. Client sets their desired expirationUnixTimeStamp (must not exceed subscription expiration)
  3. Client creates a data structure containing both their expiration and the server's signature
  4. Client signs this combined data with their ED25519 private key
  5. Client sets their signature in the outer AccessToken.Signature field

Security Benefits

The client-supplied expiration provides several security advantages:

Using Access Tokens

Include the signed access token in API requests using one of these methods:

Method 1: apicharge Header (Recommended)

GET /api/protected-resource
apicharge: {URL-encoded-token}

Method 2: Cookie

GET /api/protected-resource
Cookie: apicharge={URL-encoded-token}

Token URL Encoding

The token must be URL-encoded before transmission. This is critical for load balancing scenarios where the scaleOutVirtualNode is used for session affinity.

// URL encode the complete signed token
var tokenJson = JsonSerializer.Serialize(accessToken, JsonConfig.DefaultOptions);
var urlEncodedToken = HttpUtility.UrlEncode(tokenJson);

// Use in header
request.Headers.Add("apicharge", urlEncodedToken);

Token Validation Process

When ApiCharge receives a request with an access token, it performs these validation steps:

  1. Token Parsing - URL decode and deserialize the token
  2. Route Matching - Verify token is valid for the requested route
  3. Dual Expiration Check - Ensure both client and subscription expirations are valid
  4. Signature Verification - Validate both server and client signatures
  5. Rate Limit Enforcement - Check and update rate limiter state

Expiration Validation

ApiCharge enforces the earlier of the two expiration times:

If either expiration has passed, the token is rejected with a 402 Payment Required response.

Signature Chain Validation

The validation verifies the complete signature chain:

  1. Server Signature - Confirms the GrantedAccessToken was issued by the server
  2. Client Signature - Verifies the client signed their expiration + server signature
  3. Binding Check - Ensures the client public key matches the subscription owner

Route Probe Feature

Clients can discover the route ID for a path by sending a special probe request:

GET /some/api/path
apicharge: probe

This returns the route ID without requiring authentication, allowing clients to determine which route quotes they need.

Rate Limiting Integration

The authentication system automatically enforces rate limits specified in the access token:

Rate limiter state is maintained per token and persists across API calls and server restarts (when using Redis).

Authentication Errors

ApiCharge returns standard HTTP error codes for authentication failures:

401 Unauthorized - Missing Token

HTTP/1.1 401 Unauthorized
Content-Type: text/plain

Unauthorized

400 Bad Request - Invalid Token Format

HTTP/1.1 400 Bad Request
Content-Type: text/plain

Invalid token format

402 Payment Required - Invalid Token

HTTP/1.1 402 Payment Required
Content-Type: text/plain

Payment Required

429 Too Many Requests - Rate Limit Exceeded

HTTP/1.1 429 Too Many Requests
Content-Type: text/plain

Too Many Requests

Token Persistence and Clustering

In clustered deployments, ApiCharge uses a hybrid caching strategy for optimal rate limiting performance:

Hybrid Rate Limiter Caching

Load Balancer Configuration

The scaleOutVirtualNode field is critical for performance in clustered deployments. Configure your load balancer to use this value for session affinity to ensure:

Session Affinity Implementation

Most load balancers can be configured to route based on the scaleOutVirtualNode value. For example:

Fallback Behavior

When a request hits a different server (due to failover or load balancer misconfiguration):

  1. ApiCharge checks the local in-memory cache (cache miss)
  2. Loads rate limiter state from Redis
  3. Initializes the local cache with the Redis data
  4. Continues processing with potentially higher latency

While this fallback ensures correctness, optimal performance requires proper session affinity configuration.

Security Considerations

Token Security

Clock Synchronization

Token expiration validation depends on accurate system time. Ensure clocks are synchronized within the configured tolerance (default: 2 minutes).

Key Management

Client Implementation

To implement ApiCharge authentication in your client:

  1. Complete the purchase flow to obtain an access token
  2. Sign the token with your client's private key
  3. URL-encode the signed token
  4. Include the token in the apicharge header or cookie
  5. Handle authentication errors appropriately
  6. Monitor token expiration and renew as needed

Token Renewal

ApiCharge supports two types of token renewal:

Clients should:

Next Steps