Skip to content

Store and manage API keys using a production-ready persistence model #3

Description

@quwin

Overview

API keys are currently configured through environment variables as SHA-256 hashes. This is safer than storing raw API keys, but it is still not a production-grade API key management model.

A production gateway should support durable key storage, key rotation, revocation, metadata, auditing, and safer hash handling.

Current behavior

The gateway loads API key records from API_KEY_HASHES using the format:

sha256hash:principal_id:plan,sha256hash:principal_id:plan

The raw API keys are not stored, and incoming API keys are hashed and compared in constant time.

This is a good baseline for a portfolio implementation, but it has limitations:

  • Keys require redeploying or restarting the gateway to add/remove.
  • There is no key rotation flow.
  • There is no key expiration.
  • There is no revocation list.
  • There is no per-key metadata beyond principal ID and plan.
  • SHA-256 without a dedicated secret/keyed hashing strategy is not ideal if hashes leak and API keys have insufficient entropy.
  • There is no admin API for creating or disabling keys.

Expected behavior

API keys should be managed through a production-oriented persistence layer.

The system should support:

  • Creating new API keys.
  • Storing only a secure hash of the key.
  • Looking up keys by prefix or ID.
  • Revoking keys without redeploying.
  • Associating keys with a principal, plan, status, creation time, and optional expiration.
  • Rotating keys.
  • Auditing key usage.
  • Proposed implementation

Add a persistent API key store backed by PostgreSQL, Redis, or another durable database.

Example schema:

CREATE TABLE api_keys (
    id TEXT PRIMARY KEY,
    key_prefix TEXT NOT NULL,
    key_hash TEXT NOT NULL,
    principal_id TEXT NOT NULL,
    plan TEXT NOT NULL,
    status TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    expires_at TIMESTAMPTZ,
    last_used_at TIMESTAMPTZ,
    revoked_at TIMESTAMPTZ
);

Use generated API keys with high entropy, such as:

qwin_live_<public_prefix>_

Store only the hash of the secret portion. The public prefix can be used to locate the candidate key record efficiently before constant-time hash verification.

Acceptance criteria

API keys are stored in a durable backing store instead of only environment variables.
Raw API keys are never stored.
API keys can be revoked without redeploying the gateway.
API keys include metadata: principal ID, plan, status, created time, and optional expiration.
Authentication supports key prefix lookup plus constant-time hash verification.
Tests cover valid, missing, invalid, expired, and revoked keys.
Documentation explains how to generate, store, rotate, and revoke API keys.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions