Auth keys currently authenticate and attribute (user_path/labels), but any active key can call every model the gateway serves; the only allow-list is global (CONFIGURED_PROVIDER_MODELS_MODE=allowlist). Multi-team / multi-workload deployments need "this consumer subtree may only call these models" — the same shape budgets and rate-limit rules already solve for spend and throughput.
Proposal: a modelaccess policy resource mirroring budgets/rate-limits:
{scope: user_path|label, subject, allowed_models: [...]} — allowed_models entries provider-qualified or bare, matched with the same semantics as rate-limit model subjects (modelSubjectMatches).
- Enforcement as one gate in the shared admission sequence (
Subjects already carries UserPath/Provider/Model). If ≥1 policy applies to the request's subjects, the routed model must match the union of their allow-lists; otherwise unrestricted — fully backward-compatible, opt-in.
- Admin CRUD (
GET/PUT/DELETE /admin/model-access) plus SourceConfig seeding, consistent with rate limits.
403 with a distinct error code (model_access_denied) so operators can distinguish policy denials from unknown models.
Happy to implement this behind your design feedback — we'd use it in production (workload-scoped keys where each workload's allowed model set is declaratively seeded from config). If you'd rather see it as an allowed_models field on auth keys instead of a scoped policy resource.
Auth keys currently authenticate and attribute (user_path/labels), but any active key can call every model the gateway serves; the only allow-list is global (
CONFIGURED_PROVIDER_MODELS_MODE=allowlist). Multi-team / multi-workload deployments need "this consumer subtree may only call these models" — the same shape budgets and rate-limit rules already solve for spend and throughput.Proposal: a
modelaccesspolicy resource mirroring budgets/rate-limits:{scope: user_path|label, subject, allowed_models: [...]}—allowed_modelsentries provider-qualified or bare, matched with the same semantics as rate-limit model subjects (modelSubjectMatches).Subjectsalready carries UserPath/Provider/Model). If ≥1 policy applies to the request's subjects, the routed model must match the union of their allow-lists; otherwise unrestricted — fully backward-compatible, opt-in.GET/PUT/DELETE /admin/model-access) plusSourceConfigseeding, consistent with rate limits.403with a distinct error code (model_access_denied) so operators can distinguish policy denials from unknown models.Happy to implement this behind your design feedback — we'd use it in production (workload-scoped keys where each workload's allowed model set is declaratively seeded from config). If you'd rather see it as an
allowed_modelsfield on auth keys instead of a scoped policy resource.