Skip to content

[BUG] No per-user cap on API key creation in /api/local-coding/keys — storage exhaustion and auth performance degradation #981

@anshul23102

Description

@anshul23102

Describe the Bug

The POST /api/local-coding/keys handler inserts a new API key row for the authenticated user with no limit on how many keys a single user can create. There is no count check anywhere in the handler before the insert call.

Relevant code in src/app/api/local-coding/keys/route.ts:

// No count guard — insert runs unconditionally
const { data: keyRecord, error } = await supabaseAdmin
  .from('local_coding_api_keys')
  .insert({
    user_id: user.id,
    api_key: apiKeyHash,
    name
  })

This is inconsistent with the local-coding/sync route which enforces both MAX_SESSIONS_PER_REQUEST = 100 and MAX_SESSIONS_PER_USER = 365 before any insert.

Impact:

  1. Storage exhaustion: Any authenticated user can script unlimited POST /api/local-coding/keys calls, inserting thousands of rows in seconds.
  2. Auth performance degradation for all users: The authenticateApiKey function used on every /api/local-coding/sync request does a full-table lookup via .eq('api_key_hash', hash). As a single user's key count grows into the thousands, that table scan slows down for every user hitting the sync endpoint.

Steps to Reproduce

# Authenticated session cookie required
for i in $(seq 1 500); do
  curl -X POST https://<your-devtrack>/api/local-coding/keys \
    -H 'Content-Type: application/json' \
    -H 'Cookie: <session>' \
    -d "{\"name\": \"key-$i\"}"
done

After this loop, the local_coding_api_keys table will have 500 rows for a single user and the sync endpoint's authentication will visibly slow down.

Expected Behavior

The endpoint should enforce a reasonable per-user cap (e.g. 10 keys) and return HTTP 400 with a message like "Maximum of 10 API keys allowed per user" when the limit is reached.

Screenshots / Logs

No immediate error — the bug manifests as silent table bloat and gradual performance degradation.

Environment

  • OS: Any
  • Node version: 18+
  • Browser: Any

Additional Context

The fix mirrors the pattern already in src/app/api/local-coding/sync/route.ts:

  1. Add const MAX_KEYS_PER_USER = 10 constant
  2. Before the insert: query SELECT count(*) FROM local_coding_api_keys WHERE user_id = user.id
  3. Return 400 if count meets the cap

I am happy to work on this if it can be assigned to me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions