Repository navigation
fix(proxy): authorize key model aliases the same way as team aliases #43049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
881b1cd
fix(proxy): authorize key model aliases the same way as team aliases
mateo-berri 7a912f5
test(proxy): cover can_key_call_model key alias path
mateo-berri 6633c31
fix(proxy): honor key aliases after the global rewrite and in narrowe…
mateo-berri 4cd9616
fix(proxy): authorize only the dispatched target when a key alias res…
mateo-berri 387d60a
fix(proxy): resolve team, key and global aliases in dispatch order be…
mateo-berri b6ee048
fix(proxy): pass key aliases to the agent caller team model check
mateo-berri cf63470
fix(proxy): pass key aliases to the agent access group model check
mateo-berri d2d6c65
fix(proxy): resolve team aliases in the agent access group model check
mateo-berri 58eb2d4
fix(proxy): check the team alias target against the agent model ceiling
mateo-berri 86d5c5c
fix(proxy): keep the requested name when a team alias targets a delet…
mateo-berri File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
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
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
72 changes: 72 additions & 0 deletions
72
tests/integration/authorization/test_key_alias_model_access.py
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| import uuid | ||
| from typing import Final | ||
|
|
||
| import httpx | ||
|
|
||
| from tests.integration._support.client import Gateway, eventually, object_value, string_value | ||
|
|
||
|
|
||
| def _listed_model_ids(response: httpx.Response) -> frozenset[str]: | ||
| entries: Final = response.json()["data"] | ||
| assert isinstance(entries, list), response.text | ||
| return frozenset(string_value(object_value(entry)["id"]) for entry in entries) | ||
|
|
||
|
|
||
| def _listed_and_callable(gateway: Gateway, key: str, model: str, alias: str) -> None: | ||
| """Every id /v1/models lists for this key must be callable by the same key.""" | ||
| response: Final = eventually( | ||
| lambda: gateway.request("GET", "/v1/models", key=key), | ||
| lambda value: value.status_code == 200 and _listed_model_ids(value) == frozenset({model, alias}), | ||
| return_last_on_timeout=True, | ||
| ) | ||
| assert response.status_code == 200, response.text | ||
| listed: Final = _listed_model_ids(response) | ||
| assert listed == frozenset({model, alias}), response.text | ||
| for model_id in sorted(listed): | ||
| called: Final = gateway.request( | ||
| "POST", | ||
| "/v1/chat/completions", | ||
| {"model": model_id, "messages": [{"role": "user", "content": "ping"}]}, | ||
| key=key, | ||
| ) | ||
| assert called.status_code == 200, f"listed id {model_id} is not callable: {called.status_code} {called.text}" | ||
|
|
||
|
|
||
| def test_key_alias_listed_by_v1_models_is_callable(gateway: Gateway) -> None: | ||
| with gateway.scenario() as scenario: | ||
| model: Final = scenario.model() | ||
| alias: Final = f"integration-alias-{uuid.uuid4().hex}" | ||
| key: Final = scenario.key(models=[model], aliases={alias: model}) | ||
| _listed_and_callable(gateway, key, model, alias) | ||
|
|
||
|
|
||
| def test_team_key_alias_listed_by_v1_models_is_callable(gateway: Gateway) -> None: | ||
| with gateway.scenario() as scenario: | ||
| model: Final = scenario.model() | ||
| team_id: Final = scenario.team(models=[model]) | ||
| alias: Final = f"integration-alias-{uuid.uuid4().hex}" | ||
| key: Final = scenario.key(team_id=team_id, aliases={alias: model}) | ||
| _listed_and_callable(gateway, key, model, alias) | ||
|
|
||
|
|
||
| def test_key_alias_to_model_outside_key_allowlist_is_hidden_and_denied(gateway: Gateway) -> None: | ||
| with gateway.scenario() as scenario: | ||
| allowed: Final = scenario.model() | ||
| hidden: Final = scenario.model() | ||
| alias: Final = f"integration-alias-{uuid.uuid4().hex}" | ||
| key: Final = scenario.key(models=[allowed], aliases={alias: hidden}) | ||
| response: Final = eventually( | ||
| lambda: gateway.request("GET", "/v1/models", key=key), | ||
| lambda value: value.status_code == 200 and _listed_model_ids(value) == frozenset({allowed}), | ||
| return_last_on_timeout=True, | ||
| ) | ||
| assert response.status_code == 200, response.text | ||
| assert _listed_model_ids(response) == frozenset({allowed}), response.text | ||
| called: Final = gateway.request( | ||
| "POST", | ||
| "/v1/chat/completions", | ||
| {"model": alias, "messages": [{"role": "user", "content": "ping"}]}, | ||
| key=key, | ||
| ) | ||
| assert called.status_code == 403, called.text | ||
| assert "key_model_access_denied" in called.text, called.text |
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.