Skip to content

Commit ece76c2

Browse files
feat: Enhance managed authentication with CUA support and new features
1 parent 9b55d2b commit ece76c2

File tree

9 files changed

+448
-11
lines changed

9 files changed

+448
-11
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 103
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-17e50cf93d8052ff655c160fc0f156621d9029b041526d4e2e3317b13f80822f.yml
3-
openapi_spec_hash: f7dadc8d93e77983936eb18a8080ce15
4-
config_hash: cff4d43372b6fa66b64e2d4150f6aa76
1+
configured_endpoints: 104
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-bb2ac8e0d3a1c08e8afcbcbad7cb733d0f84bd22a8d233c1ec3100a01ee078ae.yml
3+
openapi_spec_hash: a83f7d1c422c85d6dc6158af7afe1d09
4+
config_hash: 16e4457a0bb26e98a335a1c2a572290a

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ from kernel.types.auth import (
245245
LoginResponse,
246246
ManagedAuth,
247247
ManagedAuthCreateRequest,
248+
ManagedAuthUpdateRequest,
248249
SubmitFieldsRequest,
249250
SubmitFieldsResponse,
250251
ConnectionFollowResponse,
@@ -255,6 +256,7 @@ Methods:
255256

256257
- <code title="post /auth/connections">client.auth.connections.<a href="./src/kernel/resources/auth/connections.py">create</a>(\*\*<a href="src/kernel/types/auth/connection_create_params.py">params</a>) -> <a href="./src/kernel/types/auth/managed_auth.py">ManagedAuth</a></code>
257258
- <code title="get /auth/connections/{id}">client.auth.connections.<a href="./src/kernel/resources/auth/connections.py">retrieve</a>(id) -> <a href="./src/kernel/types/auth/managed_auth.py">ManagedAuth</a></code>
259+
- <code title="patch /auth/connections/{id}">client.auth.connections.<a href="./src/kernel/resources/auth/connections.py">update</a>(id, \*\*<a href="src/kernel/types/auth/connection_update_params.py">params</a>) -> <a href="./src/kernel/types/auth/managed_auth.py">ManagedAuth</a></code>
258260
- <code title="get /auth/connections">client.auth.connections.<a href="./src/kernel/resources/auth/connections.py">list</a>(\*\*<a href="src/kernel/types/auth/connection_list_params.py">params</a>) -> <a href="./src/kernel/types/auth/managed_auth.py">SyncOffsetPagination[ManagedAuth]</a></code>
259261
- <code title="delete /auth/connections/{id}">client.auth.connections.<a href="./src/kernel/resources/auth/connections.py">delete</a>(id) -> None</code>
260262
- <code title="get /auth/connections/{id}/events">client.auth.connections.<a href="./src/kernel/resources/auth/connections.py">follow</a>(id) -> <a href="./src/kernel/types/auth/connection_follow_response.py">ConnectionFollowResponse</a></code>

src/kernel/resources/auth/connections.py

Lines changed: 177 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
connection_login_params,
2424
connection_create_params,
2525
connection_submit_params,
26+
connection_update_params,
2627
)
2728
from ..._base_client import AsyncPaginator, make_request_options
2829
from ...types.auth.managed_auth import ManagedAuth
@@ -186,6 +187,76 @@ def retrieve(
186187
cast_to=ManagedAuth,
187188
)
188189

190+
def update(
191+
self,
192+
id: str,
193+
*,
194+
allowed_domains: SequenceNotStr[str] | Omit = omit,
195+
credential: connection_update_params.Credential | Omit = omit,
196+
health_check_interval: int | Omit = omit,
197+
login_url: str | Omit = omit,
198+
proxy: connection_update_params.Proxy | Omit = omit,
199+
save_credentials: bool | Omit = omit,
200+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
201+
# The extra values given here take precedence over values defined on the client or passed to this method.
202+
extra_headers: Headers | None = None,
203+
extra_query: Query | None = None,
204+
extra_body: Body | None = None,
205+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
206+
) -> ManagedAuth:
207+
"""Update an auth connection's configuration.
208+
209+
Only the fields provided will be
210+
updated.
211+
212+
Args:
213+
allowed_domains: Additional domains valid for this auth flow (replaces existing list)
214+
215+
credential:
216+
Reference to credentials for the auth connection. Use one of:
217+
218+
- { name } for Kernel credentials
219+
- { provider, path } for external provider item
220+
- { provider, auto: true } for external provider domain lookup
221+
222+
health_check_interval: Interval in seconds between automatic health checks
223+
224+
login_url: Login page URL. Set to empty string to clear.
225+
226+
proxy: Proxy selection. Provide either id or name. The proxy must belong to the
227+
caller's org.
228+
229+
save_credentials: Whether to save credentials after every successful login
230+
231+
extra_headers: Send extra headers
232+
233+
extra_query: Add additional query parameters to the request
234+
235+
extra_body: Add additional JSON properties to the request
236+
237+
timeout: Override the client-level default timeout for this request, in seconds
238+
"""
239+
if not id:
240+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
241+
return self._patch(
242+
path_template("/auth/connections/{id}", id=id),
243+
body=maybe_transform(
244+
{
245+
"allowed_domains": allowed_domains,
246+
"credential": credential,
247+
"health_check_interval": health_check_interval,
248+
"login_url": login_url,
249+
"proxy": proxy,
250+
"save_credentials": save_credentials,
251+
},
252+
connection_update_params.ConnectionUpdateParams,
253+
),
254+
options=make_request_options(
255+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
256+
),
257+
cast_to=ManagedAuth,
258+
)
259+
189260
def list(
190261
self,
191262
*,
@@ -367,7 +438,9 @@ def submit(
367438
*,
368439
fields: Dict[str, str] | Omit = omit,
369440
mfa_option_id: str | Omit = omit,
441+
sign_in_option_id: str | Omit = omit,
370442
sso_button_selector: str | Omit = omit,
443+
sso_provider: str | Omit = omit,
371444
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
372445
# The extra values given here take precedence over values defined on the client or passed to this method.
373446
extra_headers: Headers | None = None,
@@ -383,9 +456,15 @@ def submit(
383456
Args:
384457
fields: Map of field name to value
385458
386-
mfa_option_id: Optional MFA option ID if user selected an MFA method
459+
mfa_option_id: The MFA method type to select (when mfa_options were returned)
460+
461+
sign_in_option_id: The sign-in option ID to select (when sign_in_options were returned)
387462
388-
sso_button_selector: Optional XPath selector if user chose to click an SSO button instead
463+
sso_button_selector: XPath selector for the SSO button to click (ODA). Use sso_provider instead for
464+
CUA.
465+
466+
sso_provider: SSO provider to click, matching the provider field from pending_sso_buttons
467+
(e.g., "google", "github"). Cannot be used with sso_button_selector.
389468
390469
extra_headers: Send extra headers
391470
@@ -403,7 +482,9 @@ def submit(
403482
{
404483
"fields": fields,
405484
"mfa_option_id": mfa_option_id,
485+
"sign_in_option_id": sign_in_option_id,
406486
"sso_button_selector": sso_button_selector,
487+
"sso_provider": sso_provider,
407488
},
408489
connection_submit_params.ConnectionSubmitParams,
409490
),
@@ -567,6 +648,76 @@ async def retrieve(
567648
cast_to=ManagedAuth,
568649
)
569650

651+
async def update(
652+
self,
653+
id: str,
654+
*,
655+
allowed_domains: SequenceNotStr[str] | Omit = omit,
656+
credential: connection_update_params.Credential | Omit = omit,
657+
health_check_interval: int | Omit = omit,
658+
login_url: str | Omit = omit,
659+
proxy: connection_update_params.Proxy | Omit = omit,
660+
save_credentials: bool | Omit = omit,
661+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
662+
# The extra values given here take precedence over values defined on the client or passed to this method.
663+
extra_headers: Headers | None = None,
664+
extra_query: Query | None = None,
665+
extra_body: Body | None = None,
666+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
667+
) -> ManagedAuth:
668+
"""Update an auth connection's configuration.
669+
670+
Only the fields provided will be
671+
updated.
672+
673+
Args:
674+
allowed_domains: Additional domains valid for this auth flow (replaces existing list)
675+
676+
credential:
677+
Reference to credentials for the auth connection. Use one of:
678+
679+
- { name } for Kernel credentials
680+
- { provider, path } for external provider item
681+
- { provider, auto: true } for external provider domain lookup
682+
683+
health_check_interval: Interval in seconds between automatic health checks
684+
685+
login_url: Login page URL. Set to empty string to clear.
686+
687+
proxy: Proxy selection. Provide either id or name. The proxy must belong to the
688+
caller's org.
689+
690+
save_credentials: Whether to save credentials after every successful login
691+
692+
extra_headers: Send extra headers
693+
694+
extra_query: Add additional query parameters to the request
695+
696+
extra_body: Add additional JSON properties to the request
697+
698+
timeout: Override the client-level default timeout for this request, in seconds
699+
"""
700+
if not id:
701+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
702+
return await self._patch(
703+
path_template("/auth/connections/{id}", id=id),
704+
body=await async_maybe_transform(
705+
{
706+
"allowed_domains": allowed_domains,
707+
"credential": credential,
708+
"health_check_interval": health_check_interval,
709+
"login_url": login_url,
710+
"proxy": proxy,
711+
"save_credentials": save_credentials,
712+
},
713+
connection_update_params.ConnectionUpdateParams,
714+
),
715+
options=make_request_options(
716+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
717+
),
718+
cast_to=ManagedAuth,
719+
)
720+
570721
def list(
571722
self,
572723
*,
@@ -748,7 +899,9 @@ async def submit(
748899
*,
749900
fields: Dict[str, str] | Omit = omit,
750901
mfa_option_id: str | Omit = omit,
902+
sign_in_option_id: str | Omit = omit,
751903
sso_button_selector: str | Omit = omit,
904+
sso_provider: str | Omit = omit,
752905
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
753906
# The extra values given here take precedence over values defined on the client or passed to this method.
754907
extra_headers: Headers | None = None,
@@ -764,9 +917,15 @@ async def submit(
764917
Args:
765918
fields: Map of field name to value
766919
767-
mfa_option_id: Optional MFA option ID if user selected an MFA method
920+
mfa_option_id: The MFA method type to select (when mfa_options were returned)
921+
922+
sign_in_option_id: The sign-in option ID to select (when sign_in_options were returned)
768923
769-
sso_button_selector: Optional XPath selector if user chose to click an SSO button instead
924+
sso_button_selector: XPath selector for the SSO button to click (ODA). Use sso_provider instead for
925+
CUA.
926+
927+
sso_provider: SSO provider to click, matching the provider field from pending_sso_buttons
928+
(e.g., "google", "github"). Cannot be used with sso_button_selector.
770929
771930
extra_headers: Send extra headers
772931
@@ -784,7 +943,9 @@ async def submit(
784943
{
785944
"fields": fields,
786945
"mfa_option_id": mfa_option_id,
946+
"sign_in_option_id": sign_in_option_id,
787947
"sso_button_selector": sso_button_selector,
948+
"sso_provider": sso_provider,
788949
},
789950
connection_submit_params.ConnectionSubmitParams,
790951
),
@@ -805,6 +966,9 @@ def __init__(self, connections: ConnectionsResource) -> None:
805966
self.retrieve = to_raw_response_wrapper(
806967
connections.retrieve,
807968
)
969+
self.update = to_raw_response_wrapper(
970+
connections.update,
971+
)
808972
self.list = to_raw_response_wrapper(
809973
connections.list,
810974
)
@@ -832,6 +996,9 @@ def __init__(self, connections: AsyncConnectionsResource) -> None:
832996
self.retrieve = async_to_raw_response_wrapper(
833997
connections.retrieve,
834998
)
999+
self.update = async_to_raw_response_wrapper(
1000+
connections.update,
1001+
)
8351002
self.list = async_to_raw_response_wrapper(
8361003
connections.list,
8371004
)
@@ -859,6 +1026,9 @@ def __init__(self, connections: ConnectionsResource) -> None:
8591026
self.retrieve = to_streamed_response_wrapper(
8601027
connections.retrieve,
8611028
)
1029+
self.update = to_streamed_response_wrapper(
1030+
connections.update,
1031+
)
8621032
self.list = to_streamed_response_wrapper(
8631033
connections.list,
8641034
)
@@ -886,6 +1056,9 @@ def __init__(self, connections: AsyncConnectionsResource) -> None:
8861056
self.retrieve = async_to_streamed_response_wrapper(
8871057
connections.retrieve,
8881058
)
1059+
self.update = async_to_streamed_response_wrapper(
1060+
connections.update,
1061+
)
8891062
self.list = async_to_streamed_response_wrapper(
8901063
connections.list,
8911064
)

src/kernel/types/auth/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
from .connection_login_params import ConnectionLoginParams as ConnectionLoginParams
1010
from .connection_create_params import ConnectionCreateParams as ConnectionCreateParams
1111
from .connection_submit_params import ConnectionSubmitParams as ConnectionSubmitParams
12+
from .connection_update_params import ConnectionUpdateParams as ConnectionUpdateParams
1213
from .connection_follow_response import ConnectionFollowResponse as ConnectionFollowResponse

src/kernel/types/auth/connection_follow_response.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"ManagedAuthStateEventDiscoveredField",
1616
"ManagedAuthStateEventMfaOption",
1717
"ManagedAuthStateEventPendingSSOButton",
18+
"ManagedAuthStateEventSignInOption",
1819
]
1920

2021

@@ -77,6 +78,22 @@ class ManagedAuthStateEventPendingSSOButton(BaseModel):
7778
"""XPath selector for the button"""
7879

7980

81+
class ManagedAuthStateEventSignInOption(BaseModel):
82+
"""A non-MFA choice presented during the auth flow (e.g.
83+
84+
account selection, org picker)
85+
"""
86+
87+
id: str
88+
"""Unique identifier for this option (used to submit selection back)"""
89+
90+
label: str
91+
"""Display text for the option"""
92+
93+
description: Optional[str] = None
94+
"""Additional context such as email address or org name"""
95+
96+
8097
class ManagedAuthStateEvent(BaseModel):
8198
"""An event representing the current state of a managed auth flow."""
8299

@@ -128,6 +145,12 @@ class ManagedAuthStateEvent(BaseModel):
128145
post_login_url: Optional[str] = None
129146
"""URL where the browser landed after successful login."""
130147

148+
sign_in_options: Optional[List[ManagedAuthStateEventSignInOption]] = None
149+
"""
150+
Non-MFA choices presented during the auth flow, such as account selection or org
151+
pickers (present when flow_step=AWAITING_INPUT).
152+
"""
153+
131154
website_error: Optional[str] = None
132155
"""Visible error message from the website (e.g., 'Incorrect password').
133156

src/kernel/types/auth/connection_submit_params.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,19 @@ class ConnectionSubmitParams(TypedDict, total=False):
1313
"""Map of field name to value"""
1414

1515
mfa_option_id: str
16-
"""Optional MFA option ID if user selected an MFA method"""
16+
"""The MFA method type to select (when mfa_options were returned)"""
17+
18+
sign_in_option_id: str
19+
"""The sign-in option ID to select (when sign_in_options were returned)"""
1720

1821
sso_button_selector: str
19-
"""Optional XPath selector if user chose to click an SSO button instead"""
22+
"""XPath selector for the SSO button to click (ODA).
23+
24+
Use sso_provider instead for CUA.
25+
"""
26+
27+
sso_provider: str
28+
"""
29+
SSO provider to click, matching the provider field from pending_sso_buttons
30+
(e.g., "google", "github"). Cannot be used with sso_button_selector.
31+
"""

0 commit comments

Comments
 (0)