Skip to content

fix: enforce API key model restrictions across all /v1/* endpoints - #131

Merged
diegosouzapw merged 1 commit into
diegosouzapw:mainfrom
ersintarhan:fix/api-key-model-restriction
Feb 25, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:mainfrom
ersintarhan:fix/api-key-model-restriction

Conversation

@ersintarhan

Copy link
Copy Markdown
Contributor

Summary

Fixes #130 — isModelAllowedForKey() existed but was never called. API keys with allowedModels restrictions could access any model through any endpoint.

Changes

New: src/shared/utils/apiKeyPolicy.ts

Shared middleware that enforces two checks:

  1. Model restriction — if the API key has allowedModels configured, verify the requested model is in the allowed list (supports exact match, prefix match like openai/*, and wildcard patterns)
  2. Budget limit — if the API key has a budget configured, verify it hasn't been exceeded

Usage in any endpoint:

import { enforceApiKeyPolicy } from "@/shared/utils/apiKeyPolicy";

const policy = await enforceApiKeyPolicy(request, body.model);
if (policy.rejection) return policy.rejection;

Modified endpoints

Endpoint Change
src/sse/handlers/chat.ts Replaced inline budget-only check with enforceApiKeyPolicy()
src/app/api/v1/embeddings/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/images/generations/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/audio/speech/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/audio/transcriptions/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/moderations/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/rerank/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/providers/[provider]/embeddings/route.ts Added enforceApiKeyPolicy()
src/app/api/v1/providers/[provider]/images/generations/route.ts Added enforceApiKeyPolicy()

Not modified (already covered)

  • /v1/responses and /v1/providers/[provider]/chat/completions — these call handleChat() which now includes the policy check
  • /v1/chat/completions — same as above

Behavior

  • No API key → skip policy checks (local mode, backward compatible)
  • API key with no allowedModels → all models allowed (backward compatible)
  • API key with allowedModels set → returns 403 if model not in list
  • API key over budget → returns 429
  • Metadata fetch error → degrades gracefully, doesn't block

Testing

  1. Create an API key with allowedModels: ["gpt-4o-mini"]
  2. Request claude-sonnet-4-20250514 via any endpoint → 403 Forbidden
  3. Request gpt-4o-mini → passes through normally
  4. API key without allowedModels → all models work (no regression)

…endpoints

isModelAllowedForKey() existed in src/lib/db/apiKeys.ts but was never
called anywhere. API keys with allowedModels restrictions could access
any model through any endpoint.

Changes:
- Add shared enforceApiKeyPolicy() middleware (model restriction + budget)
- Wire it into chat handler (replacing inline budget-only check)
- Wire it into all /v1/* endpoints: embeddings, images/generations,
  audio/speech, audio/transcriptions, moderations, rerank
- Wire it into provider-specific endpoints: /v1/providers/[provider]/embeddings,
  /v1/providers/[provider]/images/generations

The middleware checks:
1. Model restriction — if key has allowedModels, verify the model is permitted
2. Budget limit — if key has budget configured, verify it hasn't been exceeded

Fixes diegosouzapw#130
Copilot AI review requested due to automatic review settings February 25, 2026 03:44
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @ersintarhan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical security and resource management gap by implementing a robust API key policy enforcement mechanism. It centralizes model restriction and budget limit checks into a single, reusable middleware and integrates it across all relevant /v1/* API endpoints. This ensures that API keys with specific model allowances or budget constraints are properly respected, preventing unauthorized model access and uncontrolled resource usage.

Highlights

  • New API Key Policy Enforcement Middleware: Introduced a new shared middleware, enforceApiKeyPolicy, located at src/shared/utils/apiKeyPolicy.ts. This middleware centralizes the logic for enforcing API key policies, including model restrictions and budget limits.
  • Model Restriction Enforcement: The new policy middleware verifies if a requested model is allowed for a given API key, supporting exact matches, prefix matches (e.g., openai/*), and wildcard patterns. Requests for unauthorized models will now return a 403 Forbidden error.
  • Budget Limit Enforcement: The middleware also checks if an API key's configured budget has been exceeded. If so, requests will be rejected with a 429 Rate Limited error.
  • Integration Across /v1/ Endpoints*: The enforceApiKeyPolicy middleware has been integrated into numerous /v1/* endpoints, including audio, embeddings, image generations, moderations, and rerank routes, ensuring consistent policy application. The existing budget-only check in src/sse/handlers/chat.ts was replaced with this comprehensive policy enforcement.
  • Graceful Degradation: The policy enforcement mechanism is designed to degrade gracefully, skipping checks if no API key is provided (local mode), if the key has no allowedModels configured, or if metadata fetching or budget checks encounter errors.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/app/api/v1/audio/speech/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/audio/transcriptions/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/embeddings/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/images/generations/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/moderations/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/providers/[provider]/embeddings/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/providers/[provider]/images/generations/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/app/api/v1/rerank/route.ts
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Applied enforceApiKeyPolicy to enforce model restrictions and budget limits before processing the request.
  • src/shared/utils/apiKeyPolicy.ts
    • Added a new file defining the enforceApiKeyPolicy function.
    • Implemented logic for checking API key model restrictions using isModelAllowedForKey.
    • Implemented logic for checking API key budget limits using checkBudget.
    • Defined ApiKeyPolicyResult interface for consistent return values.
  • src/sse/handlers/chat.ts
    • Removed the import of getApiKeyMetadata as its functionality is now encapsulated.
    • Removed the direct checkBudget call and associated logic.
    • Imported enforceApiKeyPolicy from shared/utils/apiKeyPolicy.
    • Replaced the inline budget check with a call to enforceApiKeyPolicy to handle both model restrictions and budget limits.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR closes a policy enforcement gap by introducing a shared API-key policy helper and wiring it into the various /v1/* endpoints so that API keys with allowedModels and/or budget limits are consistently enforced.

Changes:

  • Added enforceApiKeyPolicy() shared utility to enforce model allowlists and budget limits for API-keyed requests.
  • Replaced/augmented endpoint-specific logic across chat + multiple /v1/* routes to call the shared policy helper.
  • Centralized the model restriction + budget rejection behavior to reduce drift across endpoints.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/shared/utils/apiKeyPolicy.ts New shared policy helper that fetches API key metadata and enforces model allowlists + budget limits.
src/sse/handlers/chat.ts Replaces inline budget-only checks with enforceApiKeyPolicy() during the chat pipeline.
src/app/api/v1/embeddings/route.ts Enforces API key policy before forwarding embedding requests.
src/app/api/v1/images/generations/route.ts Enforces API key policy before forwarding image generation requests.
src/app/api/v1/audio/speech/route.ts Enforces API key policy before forwarding TTS requests.
src/app/api/v1/audio/transcriptions/route.ts Enforces API key policy for multipart transcription requests.
src/app/api/v1/moderations/route.ts Enforces API key policy for moderation requests (including default model behavior).
src/app/api/v1/rerank/route.ts Enforces API key policy for rerank requests.
src/app/api/v1/providers/[provider]/embeddings/route.ts Enforces API key policy after provider-prefix normalization for provider-specific embeddings.
src/app/api/v1/providers/[provider]/images/generations/route.ts Enforces API key policy after provider-prefix normalization for provider-specific image generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +79 to +82
// Enforce API key policies (model restrictions + budget limits)
const policy = await enforceApiKeyPolicy(request, body.model);
if (policy.rejection) return policy.rejection;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Policy enforcement runs before parsing/normalizing the image model. Since parseImageModel supports bare model IDs, a restricted key may be incorrectly denied when the client omits the provider prefix (while allowedModels typically uses provider/model). Consider normalizing (parseImageModel -> provider/model) before calling enforceApiKeyPolicy.

Copilot uses AI. Check for mistakes.
Comment on lines 41 to +45
const model = body.model || "omni-moderation-latest";

// Enforce API key policies (model restrictions + budget limits)
const policy = await enforceApiKeyPolicy(request, model);
if (policy.rejection) return policy.rejection;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Policy enforcement runs before parsing/normalizing the moderation model. parseModerationModel supports both "openai/model" and bare model IDs; /v1/models returns provider/model IDs. Consider building a canonical provider/model string (e.g., from parseModerationModel) before calling enforceApiKeyPolicy so allowedModels checks behave consistently.

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +47
// Enforce API key policies (model restrictions + budget limits)
const policy = await enforceApiKeyPolicy(request, body.model);
if (policy.rejection) return policy.rejection;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Policy enforcement runs before parsing/normalizing the speech model. parseSpeechModel supports bare model IDs; if allowedModels is stored as provider/model (as in /v1/models), restricted keys may be incorrectly denied when clients omit the provider prefix. Consider normalizing (parseSpeechModel -> provider/model) before calling enforceApiKeyPolicy.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +61
} catch {
// If metadata fetch fails, don't block — degrade gracefully
return { apiKey, apiKeyInfo: null, rejection: null };

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If getApiKeyMetadata() throws (DB unavailable/transient error), this helper currently fails open and skips both model and budget enforcement. That can reintroduce the original bypass during outages. Consider at least logging the error and/or failing closed (e.g., 503) when an API key is presented, or making fail-open vs fail-closed configurable.

Suggested change
} catch {
// If metadata fetch fails, don't block — degrade gracefully
return { apiKey, apiKeyInfo: null, rejection: null };
} catch (err) {
// If metadata fetch fails, fail closed to avoid bypassing policy checks
console.error("Failed to fetch API key metadata", err);
return {
apiKey,
apiKeyInfo: null,
rejection: errorResponse(
HTTP_STATUS.SERVICE_UNAVAILABLE,
"Unable to validate API key metadata. Please try again later."
),
};

Copilot uses AI. Check for mistakes.
Comment on lines +44 to +48
export async function enforceApiKeyPolicy(
request: Request,
modelStr: string | null
): Promise<ApiKeyPolicyResult> {
const apiKey = extractApiKey(request);

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new shared policy layer introduces security-critical behavior (model allowlist patterns + budget rejection) but currently has no automated tests. Adding unit tests covering exact match, prefix (provider/*), wildcard patterns, and budget-exceeded responses would help prevent regressions as more /v1 endpoints adopt this helper.

Copilot uses AI. Check for mistakes.

// ── Check 1: Model restriction ──
if (modelStr && apiKeyInfo.allowedModels && apiKeyInfo.allowedModels.length > 0) {
const allowed = await isModelAllowedForKey(apiKey, modelStr);

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enforceApiKeyPolicy already fetched apiKeyInfo (including allowedModels), but isModelAllowedForKey() will fetch metadata again internally. Even with caching, this is duplicated work for restricted keys. Consider refactoring the model-allowed check to reuse the already-fetched allowedModels/metadata.

Suggested change
const allowed = await isModelAllowedForKey(apiKey, modelStr);
const allowed =
Array.isArray(apiKeyInfo.allowedModels) &&
apiKeyInfo.allowedModels.includes(modelStr);

Copilot uses AI. Check for mistakes.
Comment thread src/sse/handlers/chat.ts
Comment on lines +126 to +133
// Pipeline: API key policy enforcement (model restrictions + budget limits)
telemetry.startPhase("policy");
if (apiKeyInfo?.id) {
try {
const budgetOk = checkBudget(apiKeyInfo.id);
if (!budgetOk.allowed) {
log.warn("BUDGET", `API key ${apiKeyInfo.id} exceeded budget: ${budgetOk.reason}`);
return errorResponse(429, budgetOk.reason || "Budget limit exceeded");
}
} catch {
// Budget check is best-effort — don't block on errors
}
const policy = await enforceApiKeyPolicy(request, modelStr);
if (policy.rejection) {
log.warn("POLICY", `API key policy rejected: ${modelStr} (key=${policy.apiKeyInfo?.id || "unknown"})`);
return policy.rejection;
}
const apiKeyInfo = policy.apiKeyInfo;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Model strings can be provided without a provider prefix (e.g. "whisper-1", "text-embedding-3-large"), but allowedModels are typically stored as provider/model (as returned by /v1/models). Since policy enforcement runs before model normalization, restricted keys may be incorrectly rejected (or require clients to change model format). Consider normalizing to a canonical provider/model string (via getModelInfo) before calling enforceApiKeyPolicy, while still allowing combo names to pass through.

Copilot uses AI. Check for mistakes.
Comment on lines +82 to +85
// Enforce API key policies (model restrictions + budget limits)
const policy = await enforceApiKeyPolicy(request, body.model);
if (policy.rejection) return policy.rejection;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Policy enforcement runs before parsing/normalizing the embedding model. Because parseEmbeddingModel supports bare model IDs (no provider prefix), a restricted key with allowedModels like "openai/text-embedding-3-large" will be denied if the client sends "text-embedding-3-large". Consider parsing first and passing a normalized provider/model string into enforceApiKeyPolicy.

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +50
// Enforce API key policies (model restrictions + budget limits)
const policy = await enforceApiKeyPolicy(request, body.model);
if (policy.rejection) return policy.rejection;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Policy enforcement runs before parsing/normalizing the rerank model. Since parseRerankModel supports bare model IDs, allowedModels entries stored as provider/model may not match when clients omit the provider prefix. Consider parsing first and passing a normalized provider/model string into enforceApiKeyPolicy.

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +49
// Enforce API key policies (model restrictions + budget limits)
const policy = await enforceApiKeyPolicy(request, model as string);
if (policy.rejection) return policy.rejection;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Policy enforcement runs before parsing/normalizing the transcription model. parseTranscriptionModel supports bare model IDs; if allowedModels is stored as provider/model, restricted keys may be incorrectly denied when clients omit the provider prefix. Consider normalizing (parseTranscriptionModel -> provider/model) before calling enforceApiKeyPolicy.

Copilot uses AI. Check for mistakes.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a centralized API key policy enforcement mechanism, which is a significant improvement for ensuring consistent security and usage limits across endpoints. The new enforceApiKeyPolicy middleware is well-designed to handle model restrictions and budget checks, and it has been correctly integrated into the various /v1/* routes. My feedback focuses on enhancing the new middleware's robustness by adding logging for suppressed errors and improving type safety, which will aid in future maintenance and debugging.

/** API key string (null if no key provided) */
apiKey: string | null;
/** Metadata from DB (null if no key or key not found) */
apiKeyInfo: any | null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The apiKeyInfo property is typed as any. To leverage TypeScript's type safety and improve code clarity, consider defining a specific interface for the API key metadata (e.g., ApiKeyMetadata) and using it here. This would help prevent potential runtime errors and make the code easier to understand and maintain.

Comment on lines +57 to +62
try {
apiKeyInfo = await getApiKeyMetadata(apiKey);
} catch {
// If metadata fetch fails, don't block — degrade gracefully
return { apiKey, apiKeyInfo: null, rejection: null };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The try...catch block for getApiKeyMetadata currently suppresses errors. While degrading gracefully is the correct behavior for the user, logging the error is crucial for maintainability. It would help you debug issues with the database or the metadata retrieval logic. You'll need to import the logger: import * as log from "@/sse/utils/logger";

Suggested change
try {
apiKeyInfo = await getApiKeyMetadata(apiKey);
} catch {
// If metadata fetch fails, don't block — degrade gracefully
return { apiKey, apiKeyInfo: null, rejection: null };
}
try {
apiKeyInfo = await getApiKeyMetadata(apiKey);
} catch (error) {
// If metadata fetch fails, don't block — degrade gracefully but log it
log.warn("API_POLICY", "Failed to fetch API key metadata. Policies will not be applied.", { error });
return { apiKey, apiKeyInfo: null, rejection: null };
}

Comment on lines +98 to +100
} catch {
// Budget check is best-effort — don't block on errors
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the metadata fetch, this catch block suppresses errors from the budget check. To help with debugging and monitoring, it's best to log these errors, even if the request is allowed to proceed. This requires importing the logger if you haven't already: import * as log from "@/sse/utils/logger";

} catch (error) {
      // Budget check is best-effort — don't block on errors, but log them.
      log.warn("API_POLICY", "Budget check failed. Request will be allowed.", { error });
    }

@nyatoru

nyatoru commented Feb 25, 2026

Copy link
Copy Markdown
Contributor

this pull very nice

@diegosouzapw
diegosouzapw merged commit 827a040 into diegosouzapw:main Feb 25, 2026
diegosouzapw added a commit that referenced this pull request Feb 25, 2026
…atch in usage.ts

- Added ApiKeyMetadata interface to replace 'any' types in apiKeyPolicy.ts
- Added error logging in catch blocks for getApiKeyMetadata() and checkBudget()
- Fixed claude-sonnet-4-6-thinking → claude-sonnet-4-6 mismatch in usage.ts importantModels

Follow-up fixes for merged PRs #131 and #128
diegosouzapw added a commit that referenced this pull request Mar 7, 2026
Approved: Critical security fix for API key model restrictions. Minor improvements (error logging, type safety) will be applied in a follow-up commit.
diegosouzapw added a commit that referenced this pull request Mar 7, 2026
…atch in usage.ts

- Added ApiKeyMetadata interface to replace 'any' types in apiKeyPolicy.ts
- Added error logging in catch blocks for getApiKeyMetadata() and checkBudget()
- Fixed claude-sonnet-4-6-thinking → claude-sonnet-4-6 mismatch in usage.ts importantModels

Follow-up fixes for merged PRs #131 and #128
diegosouzapw added a commit that referenced this pull request Jul 22, 2026
- fast-uri ^3.1.3 (root + electron overrides) — GHSA host confusion via IDN (#131, #126, high)
- hono ^4.12.27 (bump existing 4.12.25 override) — JSX context isolation / cx() XSS / v1 adapter req drop (#128/#129/#130, medium)
- @hono/node-server ^2.0.5 — serve-static path traversal (#127, medium); major bump, MCP transport verified
- body-parser ^2.3.0 — DoS on invalid limit (#125, low), via express 5

All four packages now clear in `npm audit`; lockfile-lint OK; vuln-ratchet advisory count reduced.
Electron lockfile updated for the second fast-uri site.
diegosouzapw added a commit that referenced this pull request Jul 22, 2026
- fast-uri ^3.1.3 (root + electron) — host confusion via IDN (#131/#126, high)
- hono ^4.12.27 — JSX ctx isolation / cx() XSS / v1 adapter req drop (#128/#129/#130, medium)
- @hono/node-server ^2.0.5 — serve-static path traversal (#127, medium); MCP uses only getRequestListener, not serve-static
- body-parser ^2.3.0 — DoS on invalid limit (#125, low)

Resolved: fast-uri 3.1.4, hono 4.12.31, @hono/node-server 2.0.11, body-parser 2.3.0. All clear in npm audit; lockfile-lint OK.
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…osouzapw#8066)

- fast-uri ^3.1.3 (root + electron overrides) — GHSA host confusion via IDN (diegosouzapw#131, diegosouzapw#126, high)
- hono ^4.12.27 (bump existing 4.12.25 override) — JSX context isolation / cx() XSS / v1 adapter req drop (diegosouzapw#128/diegosouzapw#129/diegosouzapw#130, medium)
- @hono/node-server ^2.0.5 — serve-static path traversal (diegosouzapw#127, medium); major bump, MCP transport verified
- body-parser ^2.3.0 — DoS on invalid limit (diegosouzapw#125, low), via express 5

All four packages now clear in `npm audit`; lockfile-lint OK; vuln-ratchet advisory count reduced.
Electron lockfile updated for the second fast-uri site.
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…osouzapw#8067)

- fast-uri ^3.1.3 (root + electron) — host confusion via IDN (diegosouzapw#131/diegosouzapw#126, high)
- hono ^4.12.27 — JSX ctx isolation / cx() XSS / v1 adapter req drop (diegosouzapw#128/diegosouzapw#129/diegosouzapw#130, medium)
- @hono/node-server ^2.0.5 — serve-static path traversal (diegosouzapw#127, medium); MCP uses only getRequestListener, not serve-static
- body-parser ^2.3.0 — DoS on invalid limit (diegosouzapw#125, low)

Resolved: fast-uri 3.1.4, hono 4.12.31, @hono/node-server 2.0.11, body-parser 2.3.0. All clear in npm audit; lockfile-lint OK.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…l-restriction

Approved: Critical security fix for API key model restrictions. Minor improvements (error logging, type safety) will be applied in a follow-up commit.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…atch in usage.ts

- Added ApiKeyMetadata interface to replace 'any' types in apiKeyPolicy.ts
- Added error logging in catch blocks for getApiKeyMetadata() and checkBudget()
- Fixed claude-sonnet-4-6-thinking → claude-sonnet-4-6 mismatch in usage.ts importantModels

Follow-up fixes for merged PRs diegosouzapw#131 and diegosouzapw#128
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…osouzapw#8067)

- fast-uri ^3.1.3 (root + electron) — host confusion via IDN (diegosouzapw#131/diegosouzapw#126, high)
- hono ^4.12.27 — JSX ctx isolation / cx() XSS / v1 adapter req drop (diegosouzapw#128/diegosouzapw#129/diegosouzapw#130, medium)
- @hono/node-server ^2.0.5 — serve-static path traversal (diegosouzapw#127, medium); MCP uses only getRequestListener, not serve-static
- body-parser ^2.3.0 — DoS on invalid limit (diegosouzapw#125, low)

Resolved: fast-uri 3.1.4, hono 4.12.31, @hono/node-server 2.0.11, body-parser 2.3.0. All clear in npm audit; lockfile-lint OK.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…osouzapw#8066)

- fast-uri ^3.1.3 (root + electron overrides) — GHSA host confusion via IDN (diegosouzapw#131, diegosouzapw#126, high)
- hono ^4.12.27 (bump existing 4.12.25 override) — JSX context isolation / cx() XSS / v1 adapter req drop (diegosouzapw#128/diegosouzapw#129/diegosouzapw#130, medium)
- @hono/node-server ^2.0.5 — serve-static path traversal (diegosouzapw#127, medium); major bump, MCP transport verified
- body-parser ^2.3.0 — DoS on invalid limit (diegosouzapw#125, low), via express 5

All four packages now clear in `npm audit`; lockfile-lint OK; vuln-ratchet advisory count reduced.
Electron lockfile updated for the second fast-uri site.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] API key model restrictions (allowedModels) are never enforced — affects ALL endpoints

4 participants