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.