Skip to content

Commit ecfa27c

Browse files
committed
fix(auth): classify TOS bucket conflicts by error code
1 parent c7a2fe5 commit ecfa27c

2 files changed

Lines changed: 103 additions & 2 deletions

File tree

agentkit/auth/admin.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@
4646
# create sandbox sessions (the session/tool-read actions come from the custom policy).
4747
SANDBOX_ACCESS_POLICY = "AgentKitSandboxAccess"
4848
WELL_KNOWN_KEY = ".well-known/agentkit-cli"
49+
_TOS_BUCKET_CONFLICT_CODES = frozenset(
50+
{
51+
"BucketAlreadyExists",
52+
"BucketAlreadyOwnedByYou",
53+
}
54+
)
4955
ROLE_ACTIONS = (
5056
"agentkit:CreateSession", "agentkit:GetSession", "agentkit:DeleteSession",
5157
"agentkit:GetSessionLogs", "agentkit:SetSessionTtl",
@@ -505,9 +511,10 @@ def publish_discovery(
505511
client = tos.TosClientV2(ak, sk, endpoint, coords.region, security_token=token)
506512
try:
507513
client.create_bucket(bucket, acl=tos.ACLType.ACL_Public_Read)
508-
except Exception as exc: # noqa: BLE001
514+
except Exception as exc:
509515
msg = str(exc)
510-
if not any(k in msg for k in ("Exist", "exist", "Owned", "owned", "Conflict", "conflict")):
516+
error_code = str(getattr(exc, "code", ""))
517+
if error_code not in _TOS_BUCKET_CONFLICT_CODES:
511518
raise AuthError(
512519
f"could not create the TOS bucket for the discovery doc: {msg[:120]}",
513520
hint="enable TOS on this account and allow public-read buckets, or pass an existing bucket.",

tests/auth/test_admin.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import sys
16+
from types import SimpleNamespace
17+
from unittest.mock import MagicMock
18+
19+
import pytest
20+
21+
from agentkit.auth.admin import CliAccessCoords, publish_discovery
22+
from agentkit.auth.errors import AuthError
23+
24+
25+
class TosError(Exception):
26+
def __init__(self, code: str, message: str):
27+
super().__init__(message)
28+
self.code = code
29+
30+
31+
def install_fake_tos(monkeypatch, create_bucket_error: Exception):
32+
client = MagicMock()
33+
client.create_bucket.side_effect = create_bucket_error
34+
tos_module = SimpleNamespace(
35+
ACLType=SimpleNamespace(ACL_Public_Read="public-read"),
36+
TosClientV2=MagicMock(return_value=client),
37+
)
38+
monkeypatch.setitem(sys.modules, "tos", tos_module)
39+
return client
40+
41+
42+
def make_coords() -> CliAccessCoords:
43+
return CliAccessCoords(
44+
account_id="account",
45+
region="cn-beijing",
46+
user_pool_uid="pool",
47+
issuer="https://issuer.example",
48+
client_id="client",
49+
role_trn="role",
50+
provider_trn="provider",
51+
)
52+
53+
54+
@pytest.mark.parametrize(
55+
"error_code",
56+
["BucketAlreadyExists", "BucketAlreadyOwnedByYou"],
57+
)
58+
def test_publish_discovery_ignores_explicit_bucket_conflicts(monkeypatch, error_code):
59+
client = install_fake_tos(
60+
monkeypatch,
61+
TosError(error_code, "bucket is already owned"),
62+
)
63+
64+
url = publish_discovery(
65+
make_coords(),
66+
bucket="existing-bucket",
67+
custom_domain="agent.example",
68+
access_key="ak",
69+
secret_key="sk",
70+
)
71+
72+
assert url == "https://agent.example"
73+
client.put_object.assert_called_once()
74+
75+
76+
def test_publish_discovery_does_not_swallow_authentication_errors(monkeypatch):
77+
client = install_fake_tos(
78+
monkeypatch,
79+
TosError(
80+
"InvalidAccessKeyId",
81+
"the specified access key does not exist",
82+
),
83+
)
84+
85+
with pytest.raises(AuthError, match="could not create the TOS bucket"):
86+
publish_discovery(
87+
make_coords(),
88+
bucket="new-bucket",
89+
custom_domain="agent.example",
90+
access_key="invalid-ak",
91+
secret_key="invalid-sk",
92+
)
93+
94+
client.put_object.assert_not_called()

0 commit comments

Comments
 (0)