Skip to main content

API Key Authentication

Overview

ComponentDescription
SupabaseCloud database for storing hashed API keys, revocation status and metadata
Crypto (Node.js)Generates and hashes API keys securely using SHA-256
LRU CacheStores API key validation states in memory for a specified time to reduce database lookups
Rate LimiterRestricts API usage per key or IP to prevent abuse
Express MiddlewareAuthenticates requests using API keys via the abair-api-key header

Key Generation

Purpose

Generate a unique, secure, and hashed API key for each user and store it in Supabase.


Flow

  1. Generate a random 32-byte API key
  2. Hash it using SHA-256
  3. Ensure the hash is unique (no collision in Supabase)
  4. Insert the hashed key and metadata (e.g. description, is_revoked) into the api_authentication table in Supabase
  5. Return the plain, unhashed API key to the user (only once)

Security Notes

  • The plain api key is never stored in the database.
  • Only the SHA-256 hash is stored, ensuring that even if the database is compromised, the keys remain secure.
  • Key uniqueness is guarunteed by comparing hashed values in Supabase before insertion.

Middleware

Purpose

To authenticate incoming requests by verifying API keys against Supabase (with caching)


Header Example

Clients must send their key in the request header,

abair-api-key: 1e4c54e1c32a7e9bba3c4d78d71f4f35d7a4b812e73c...

Flow

  1. Extract API key from the abair-api-key header.
  2. Hash the key using SHA-256.
  3. Check the LRU cache for the hash state:
  • valid --> allow request.
  • revoked --> reject immediately.
  1. If not cached, query Supabase for:
  • Existence of the hashed key.
  • Revocation status.
  1. Update cache accordingly and proceed or reject.

Example Responses

StatusMessage
200Request proceeds normally
401{ "error": "API key missing" }
403{ "error": "Invalid API key" } or { "error": "API key revoked" }
500{ "error": "Error verifying API key" }

Performance Optimisation - Caching

Purpose

Reduce frequent lookups to Supabase by storing recent key validation results.


Mechanism

Uses LRUCache (Least Recently Used Cache)

Default TTL: 15 Minutes (Configurable via CACHE_MINUTES in .env)

Stores either "valid" or "revoked" status per hashed key

Rate Limiting

Purpose

Protect the API services from abuse by enforcing per-key or per-IP limiting.

const apiKeyRateLimiter = rateLimit({
windowMs: rateLimitMinutes * 60 * 1000,
max: process.env.RATE_LIMIT_REQUESTS || 100,
keyGenerator: req => req.headers["abair-api-key"] || ipKeyGenerator(req),
});

Behaviour

Limits the number of requests per minute (default: 100/minute)

Tracks rate limit hits in Prometheus.

Returns 429 Too Many Requests with a retry timer.

Example Response

{
"error": "Rate limit exceeded. Please wait 2 minute(s)."
}

Max number of requests and Rate limit wait time can be toggled in .env

Revocation Endpoints

Purpose

Allow administrators or users to revoke keys securely and immediately.


Single Key Revocation

Endpoint

DELETE /apikey/revoke

Body Example

{
"apiKey": "1e4c54e1c32a7e9bba3c4d78d71f4f35d7a4b812e73c..."
}

Response Examples

StatusMessage
200{ "success": true, "message": "API key revoked successfully" }
404{ "error": "API key not found" }
400{ "error": "Missing apiKey in body" }
500{ error: "Database error fetching API key" }

Revoked keys are marked in Supabase and removed from Cache.


Revoke All API-Keys (Admin-Only)

Endpoint

DELETE /apikey/revoke-all

Headers

x-admin-secret: <ADMIN_SECRET>

Response

{ "success": true, "message": "All active API keys revoked successfully" }

Security

  • Requires admin-secret matching process.env.ADMIN-SECRET.
  • Immediately invalidates all keys in both Supabase and Cache.

Supabase Schema

Table

api_authentication

ColumnTypeDescription
idINTUnique identifer
hashed_keyTEXTSHA-256 hashed API key
created_atTIMESTAMPTZCreation date
is_revokedBOOLEANWhether key is revoked
revoked_atTIMESTAMPTZRevocation date
descriptionTEXTOptional user-created identifer for key
last_used_atTIMESTAMPTZDate key was last used
usage_countINTNumber of times key has been used
ownerUUIDUser account associated with key

Security

  • Only hashed keys are stored.

  • Rate limiting prevents brute force attacks.

  • Cache invalidation ensures revoked keys are immediately recognised.

  • API key visibility is one-time at creation.

  • Admin-routes are protected via env-based secret.