feat: restrict model classes, quotas, and privacy per tenant - #29
Merged
Merged
Conversation
Section 7.1 makes resolving tenant quotas and permitted model classes a gateway responsibility and section 14 requires both to be restricted per tenant, but quota and model eligibility were global. Entitlements are governance and live in the catalog; the credential that binds a caller to a tenant stays in the environment (ROUTER_TENANT_KEYS). A tenant may restrict tiers or models, carry its own quota, set a privacy floor, deny external fallback, and raise the quality floor. An absent field defers to platform policy and never tightens an existing deployment. The entitlement is a hard filter applied before scoring. The privacy floor is applied before the cache lookup, so a tenant with a restricted floor cannot read an entry stored under public, and the route reason attributes the raise. Quota and cache are scoped to the tenant rather than the credential, so rotating a key resets neither. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second PR closing gaps between the design spec and the implementation.
Gap this closes
§7.1 "Resolve tenant quotas and permitted model classes" and §14 "Restrict model classes and quotas per tenant". Both were global.
What changed
TenantRecordin the catalog:permitted_tiers/permitted_models,quota_requests_per_minute,minimum_privacy,allow_external_fallback,quality_floor. An absent field defers to platform policy and never tightens an existing deployment.ROUTER_TENANT_KEYSin the environment; bareROUTER_API_KEYSkeys map to thedefaulttenant, so existing deployments are unchanged.422rather than downgraded.public. The route reason attributes the raise.Behaviour change to note
Quota is now per tenant rather than per key: several bare keys in
ROUTER_API_KEYSnow share thedefaulttenant's quota.Test plan
ruff format --check .,ruff check .,mypycleanpytest tests/unit tests/integration— 191 passed, coverage 97.5%; the 3 errors are the local Windows temp-dir permission issue ontmp_path, which does not occur on CI🤖 Generated with Claude Code