Skip to content

Commit b740930

Browse files
feat: Arm vault passkeys in browsers and sign WebAuthn requests in metro-api
Stainless-Generated-From: ce1c14a7a377dd429ec177ca938d2905751a4303
1 parent e043c7a commit b740930

17 files changed

Lines changed: 1070 additions & 60 deletions

‎api.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ from kernel.types.vaults import (
572572
AgentcardCheckoutAuthorization,
573573
AgentcardCheckoutPreparation,
574574
AgentcardPreparedProcessor,
575+
ArmPasskeyVaultItemOperationRequest,
575576
AuthorizeVaultItemOperationRequest,
576577
CardVaultItemSpec,
577578
CardVaultItemState,
@@ -593,6 +594,7 @@ from kernel.types.vaults import (
593594
CredentialVaultItemSpecUpdate,
594595
CredentialVaultItemState,
595596
CredentialVaultItemUpdateRequest,
597+
DisarmPasskeyVaultItemOperationRequest,
596598
FillVaultItemOperationRequest,
597599
FillVaultItemOperationResult,
598600
KernelCardState,
@@ -618,7 +620,9 @@ from kernel.types.vaults import (
618620
OnePasswordOAuthAction,
619621
OnePasswordRecoverVaultItemOperationRequest,
620622
OnePasswordRequestAccessVaultItemOperationRequest,
623+
PasskeyVaultItemOperationResult,
621624
PrepareCheckoutVaultItemOperationRequest,
625+
RegisterPasskeyVaultItemOperationRequest,
622626
RestartVerificationVaultItemOperationRequest,
623627
VaultCardAliases,
624628
VaultCardFillField,

‎src/kernel/resources/vaults/items.py‎

Lines changed: 356 additions & 0 deletions
Large diffs are not rendered by default.

‎src/kernel/types/vaults/__init__.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from .credential_vault_item_request_param import CredentialVaultItemRequestParam as CredentialVaultItemRequestParam
5252
from .kernel_wallet_vault_item_spec_param import KernelWalletVaultItemSpecParam as KernelWalletVaultItemSpecParam
5353
from .managed_auth_credential_vault_field import ManagedAuthCredentialVaultField as ManagedAuthCredentialVaultField
54+
from .passkey_vault_item_operation_result import PasskeyVaultItemOperationResult as PasskeyVaultItemOperationResult
5455
from .one_password_credential_account_spec import OnePasswordCredentialAccountSpec as OnePasswordCredentialAccountSpec
5556
from .one_password_credential_account_state import (
5657
OnePasswordCredentialAccountState as OnePasswordCredentialAccountState,
@@ -103,9 +104,15 @@
103104
from .one_password_fill_vault_item_operation_result import (
104105
OnePasswordFillVaultItemOperationResult as OnePasswordFillVaultItemOperationResult,
105106
)
107+
from .arm_passkey_vault_item_operation_request_param import (
108+
ArmPasskeyVaultItemOperationRequestParam as ArmPasskeyVaultItemOperationRequestParam,
109+
)
106110
from .webmcp_invoke_vault_item_operation_request_param import (
107111
WebmcpInvokeVaultItemOperationRequestParam as WebmcpInvokeVaultItemOperationRequestParam,
108112
)
113+
from .disarm_passkey_vault_item_operation_request_param import (
114+
DisarmPasskeyVaultItemOperationRequestParam as DisarmPasskeyVaultItemOperationRequestParam,
115+
)
109116
from .managed_auth_credential_vault_item_spec_input_param import (
110117
ManagedAuthCredentialVaultItemSpecInputParam as ManagedAuthCredentialVaultItemSpecInputParam,
111118
)
@@ -115,6 +122,9 @@
115122
from .prepare_checkout_vault_item_operation_request_param import (
116123
PrepareCheckoutVaultItemOperationRequestParam as PrepareCheckoutVaultItemOperationRequestParam,
117124
)
125+
from .register_passkey_vault_item_operation_request_param import (
126+
RegisterPasskeyVaultItemOperationRequestParam as RegisterPasskeyVaultItemOperationRequestParam,
127+
)
118128
from .one_password_fill_vault_item_operation_request_param import (
119129
OnePasswordFillVaultItemOperationRequestParam as OnePasswordFillVaultItemOperationRequestParam,
120130
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Literal, Required, TypedDict
6+
7+
__all__ = ["ArmPasskeyVaultItemOperationRequestParam"]
8+
9+
10+
class ArmPasskeyVaultItemOperationRequestParam(TypedDict, total=False):
11+
"""
12+
Let a browser attached to the item's vault sign in with a stored passkey.
13+
Only invoke when the item advertises `arm_passkey`. Returns immediately;
14+
there is no time limit. While armed, when a page in that browser whose
15+
origin matches the passkey's relying party asks for a passkey
16+
(`navigator.credentials.get`, including autofill requests made at page
17+
load), Kernel answers with this passkey. The private key never enters the
18+
browser: Kernel signs on its servers, using the origin Chrome reports for
19+
the requesting frame. Arming a passkey for a relying party replaces any
20+
passkey armed earlier in the browser for the same relying party. The arm
21+
lasts until `disarm_passkey`, the browser ends, the vault is detached, or
22+
the item or field is deleted. Drive the sign-in with your own browser
23+
tools and inspect the page to confirm it. A page opened in a new tab
24+
or window can run its first scripts before Kernel's handler attaches;
25+
if such a page asks for a passkey as soon as it loads, reload it. While
26+
armed, any script running on the relying party's pages can obtain a
27+
sign-in without user interaction, as with a password manager that
28+
fills automatically; disarm when the task is done. Passkeys report a
29+
signature counter of 0 and backup flags, as synced passkeys do.
30+
"""
31+
32+
browser_id: Required[str]
33+
"""Browser session ID, not a reusable browser name."""
34+
35+
type: Required[Literal["arm_passkey"]]
36+
37+
field: str
38+
"""Passkey field to arm.
39+
40+
Required when more than one passkey field holds a passkey.
41+
"""

‎src/kernel/types/vaults/credential_account_vault_item.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class AvailableOperation(BaseModel):
3737
"collect",
3838
"prepare_checkout",
3939
"fill",
40+
"arm_passkey",
41+
"register_passkey",
42+
"disarm_passkey",
4043
"1pw_create_access_request",
4144
"1pw_access_request_status",
4245
"1pw_fill",

‎src/kernel/types/vaults/credential_vault_field_definition.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class CredentialVaultFieldDefinition(BaseModel):
3737
`credentialId`, `userHandle` (at most 64 bytes), and `key` (a PKCS#8 ECDSA P-256
3838
private key), a lowercase `rpId` domain, and optional `username` and
3939
`userDisplayName`. Other CXF members are ignored. Passkeys are never filled into
40-
pages.
40+
pages; use arm_passkey to sign in with one and register_passkey to create one.
4141
"""
4242

4343
label: Optional[str] = None

‎src/kernel/types/vaults/credential_vault_field_definition_input_param.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class CredentialVaultFieldDefinitionInputParam(TypedDict, total=False):
3232
`credentialId`, `userHandle` (at most 64 bytes), and `key` (a PKCS#8 ECDSA P-256
3333
private key), a lowercase `rpId` domain, and optional `username` and
3434
`userDisplayName`. Other CXF members are ignored. Passkeys are never filled into
35-
pages.
35+
pages; use arm_passkey to sign in with one and register_passkey to create one.
3636
"""
3737

3838
label: str

‎src/kernel/types/vaults/credential_vault_field_input_param.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class CredentialVaultFieldInputParam(TypedDict, total=False):
2727
`credentialId`, `userHandle` (at most 64 bytes), and `key` (a PKCS#8 ECDSA P-256
2828
private key), a lowercase `rpId` domain, and optional `username` and
2929
`userDisplayName`. Other CXF members are ignored. Passkeys are never filled into
30-
pages.
30+
pages; use arm_passkey to sign in with one and register_passkey to create one.
3131
"""
3232

3333
encrypted_value: str

‎src/kernel/types/vaults/credential_vault_item.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class AvailableOperation(BaseModel):
4444
"collect",
4545
"prepare_checkout",
4646
"fill",
47+
"arm_passkey",
48+
"register_passkey",
49+
"disarm_passkey",
4750
"1pw_create_access_request",
4851
"1pw_access_request_status",
4952
"1pw_fill",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import Literal, Required, TypedDict
6+
7+
__all__ = ["DisarmPasskeyVaultItemOperationRequestParam"]
8+
9+
10+
class DisarmPasskeyVaultItemOperationRequestParam(TypedDict, total=False):
11+
"""
12+
Stop a browser from using this item's passkeys: removes its armed
13+
passkeys and its pending registration into this item. Pages that already
14+
loaded keep Kernel's WebAuthn handler but get the browser's own behavior.
15+
"""
16+
17+
browser_id: Required[str]
18+
"""Browser session ID, not a reusable browser name."""
19+
20+
type: Required[Literal["disarm_passkey"]]
21+
22+
field: str
23+
"""Limit disarming to one passkey field.
24+
25+
Omit to disarm every passkey field of the item.
26+
"""

0 commit comments

Comments
 (0)