diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 334d1c13..47d19c42 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -7,6 +7,8 @@ on: permissions: contents: read pull-requests: write + # semgrep exchanges the job's OIDC token for short-lived model credentials. + id-token: write jobs: scan: diff --git a/.github/workflows/vuln-remediation.yml b/.github/workflows/vuln-remediation.yml index 07d8f360..eedbc2bc 100644 --- a/.github/workflows/vuln-remediation.yml +++ b/.github/workflows/vuln-remediation.yml @@ -8,6 +8,8 @@ on: permissions: contents: write pull-requests: write + # vuln-remediation exchanges the job's OIDC token for short-lived model credentials. + id-token: write jobs: remediate: diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ac481180..2fb68e4d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.144.0" + ".": "0.145.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d2c65f1d..4f8a7241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.145.0](https://github.com/kernel/kernel-python-sdk/compare/v0.144.0...v0.145.0) (2026-11-10) + + +### Features + +* Discard browser sessions on immediate API key revocation ([#5272](https://github.com/kernel/kernel-python-sdk/issues/5272)) ([ff3251e](https://github.com/kernel/kernel-python-sdk/commit/ff3251ee88c932e4588c4941059231a475a6e33a)) +* Expose Link card credential_type and explain pay token fill rejections ([a556758](https://github.com/kernel/kernel-python-sdk/commit/a5567585e70582cbf165408682903b95f56da8e7)) + ## [0.144.0](https://github.com/kernel/kernel-python-sdk/compare/v0.143.0...v0.144.0) (2026-11-09) diff --git a/pyproject.toml b/pyproject.toml index a1655c12..e6e3a686 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.144.0" +version = "0.145.0" description = "The official Python library for the kernel API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/kernel/_version.py b/src/kernel/_version.py index d0bc22fa..41491b0b 100644 --- a/src/kernel/_version.py +++ b/src/kernel/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "kernel" -__version__ = "0.144.0" # x-release-please-version +__version__ = "0.145.0" # x-release-please-version diff --git a/src/kernel/resources/api_keys.py b/src/kernel/resources/api_keys.py index 0365fd1e..cba032fe 100644 --- a/src/kernel/resources/api_keys.py +++ b/src/kernel/resources/api_keys.py @@ -303,10 +303,10 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, idempotency_key: str | None = None, ) -> None: - """Delete an API key. - - A key cannot delete itself; use a different key to delete - this one. + """ + Delete an API key and asynchronously end browser sessions attributed to it, + discarding unsaved profile changes. A key cannot delete itself; use a different + key to delete this one. If cleanup cannot be registered, the key is not deleted. Args: extra_headers: Send extra headers @@ -352,7 +352,11 @@ def rotate( Issues a new key that copies the name and project of the rotated key, and schedules the rotated key to expire after a grace period so - in-flight callers can swap over. The new plaintext key is returned once. + in-flight callers can swap over. The new plaintext key is returned once. With + expire_in_days set to 0, browser sessions attributed to the old key are ended + asynchronously and unsaved profile changes are discarded. Grace-period and + natural expiry do not end existing browsers. If cleanup cannot be registered, an + immediate rotation is not committed. Args: days_to_expire: Lifetime in days for the new key, up to 3650. Omit to reuse the rotated key's @@ -663,10 +667,10 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, idempotency_key: str | None = None, ) -> None: - """Delete an API key. - - A key cannot delete itself; use a different key to delete - this one. + """ + Delete an API key and asynchronously end browser sessions attributed to it, + discarding unsaved profile changes. A key cannot delete itself; use a different + key to delete this one. If cleanup cannot be registered, the key is not deleted. Args: extra_headers: Send extra headers @@ -712,7 +716,11 @@ async def rotate( Issues a new key that copies the name and project of the rotated key, and schedules the rotated key to expire after a grace period so - in-flight callers can swap over. The new plaintext key is returned once. + in-flight callers can swap over. The new plaintext key is returned once. With + expire_in_days set to 0, browser sessions attributed to the old key are ended + asynchronously and unsaved profile changes are discarded. Grace-period and + natural expiry do not end existing browsers. If cleanup cannot be registered, an + immediate rotation is not committed. Args: days_to_expire: Lifetime in days for the new key, up to 3650. Omit to reuse the rotated key's diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py index 35400c02..4cbd2c63 100644 --- a/src/kernel/resources/vaults/items.py +++ b/src/kernel/resources/vaults/items.py @@ -166,8 +166,8 @@ def update( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -218,8 +218,8 @@ def update( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -1928,8 +1928,8 @@ def upsert( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -1977,8 +1977,8 @@ def upsert( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -2257,8 +2257,8 @@ async def update( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -2309,8 +2309,8 @@ async def update( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -4019,8 +4019,8 @@ async def upsert( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers @@ -4068,8 +4068,8 @@ async def upsert( be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a - virtual card otherwise. Callers never receive or choose how the credential is - delivered. + virtual card otherwise. Callers do not choose how the credential is delivered; + after authorize, state.credential_type reports it. extra_headers: Send extra headers diff --git a/src/kernel/types/vaults/card_vault_item_spec.py b/src/kernel/types/vaults/card_vault_item_spec.py index 4061f86a..de02f8d2 100644 --- a/src/kernel/types/vaults/card_vault_item_spec.py +++ b/src/kernel/types/vaults/card_vault_item_spec.py @@ -74,7 +74,7 @@ class LinkCardVaultItemSpecTotal(BaseModel): class LinkCardVaultItemSpec(BaseModel): """Live Link card request. - Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers never receive or choose how the credential is delivered. + Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers do not choose how the credential is delivered; after authorize, state.credential_type reports it. """ amount: int diff --git a/src/kernel/types/vaults/card_vault_item_spec_param.py b/src/kernel/types/vaults/card_vault_item_spec_param.py index 24dbe47b..0db17a03 100644 --- a/src/kernel/types/vaults/card_vault_item_spec_param.py +++ b/src/kernel/types/vaults/card_vault_item_spec_param.py @@ -74,7 +74,7 @@ class LinkCardVaultItemSpecTotal(TypedDict, total=False): class LinkCardVaultItemSpec(TypedDict, total=False): """Live Link card request. - Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers never receive or choose how the credential is delivered. + Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers do not choose how the credential is delivered; after authorize, state.credential_type reports it. """ amount: Required[int] diff --git a/src/kernel/types/vaults/card_vault_item_state.py b/src/kernel/types/vaults/card_vault_item_state.py index 9e43ec26..a0cc86fb 100644 --- a/src/kernel/types/vaults/card_vault_item_state.py +++ b/src/kernel/types/vaults/card_vault_item_state.py @@ -58,6 +58,15 @@ class LinkCardState(BaseModel): and should approve only the new one. """ + credential_type: Optional[Literal["card", "link_pay_token"]] = None + """ + The Link spend request's credential_type, set when authorize sends the request + to Link. Absent before authorize and after Link rejects the request; a ready + card without it fills like card. card is a Link virtual card; fill it with field + bindings. link_pay_token is a Link Pay Token that Kernel supplies through the + checkout's Link WebMCP tool; fill it without fields. + """ + domains: Optional[List[str]] = None masks: Optional[LinkCardStateMasks] = None diff --git a/src/kernel/types/vaults/item_update_params.py b/src/kernel/types/vaults/item_update_params.py index 6a8b4e7a..62b61f9b 100644 --- a/src/kernel/types/vaults/item_update_params.py +++ b/src/kernel/types/vaults/item_update_params.py @@ -27,7 +27,8 @@ class CardVaultItemUpdateRequest(TypedDict, total=False): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ type: Literal["card"] @@ -43,7 +44,8 @@ class PaymentRequestVaultItemUpdateRequest(TypedDict, total=False): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ type: Required[Literal["payment_request"]] diff --git a/src/kernel/types/vaults/item_upsert_params.py b/src/kernel/types/vaults/item_upsert_params.py index 20a3b8f9..a6be3725 100644 --- a/src/kernel/types/vaults/item_upsert_params.py +++ b/src/kernel/types/vaults/item_upsert_params.py @@ -219,7 +219,8 @@ class CardVaultItemRequest(TypedDict, total=False): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ type: Required[Literal["card"]] @@ -235,7 +236,8 @@ class PaymentRequestVaultItemRequest(TypedDict, total=False): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ type: Required[Literal["payment_request"]] diff --git a/src/kernel/types/vaults/payment_request_vault_item.py b/src/kernel/types/vaults/payment_request_vault_item.py index 65106c8d..3fb3518e 100644 --- a/src/kernel/types/vaults/payment_request_vault_item.py +++ b/src/kernel/types/vaults/payment_request_vault_item.py @@ -76,7 +76,8 @@ class PaymentRequestVaultItem(BaseModel): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ state: PaymentRequestVaultItemState diff --git a/src/kernel/types/vaults/payment_request_vault_item_spec.py b/src/kernel/types/vaults/payment_request_vault_item_spec.py index a06517ad..3f660943 100644 --- a/src/kernel/types/vaults/payment_request_vault_item_spec.py +++ b/src/kernel/types/vaults/payment_request_vault_item_spec.py @@ -71,7 +71,7 @@ class LinkCardVaultItemSpecTotal(BaseModel): class LinkCardVaultItemSpec(BaseModel): """Live Link card request. - Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers never receive or choose how the credential is delivered. + Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers do not choose how the credential is delivered; after authorize, state.credential_type reports it. """ amount: int diff --git a/src/kernel/types/vaults/payment_request_vault_item_spec_param.py b/src/kernel/types/vaults/payment_request_vault_item_spec_param.py index 9fa58699..41042802 100644 --- a/src/kernel/types/vaults/payment_request_vault_item_spec_param.py +++ b/src/kernel/types/vaults/payment_request_vault_item_spec_param.py @@ -71,7 +71,7 @@ class LinkCardVaultItemSpecTotal(TypedDict, total=False): class LinkCardVaultItemSpec(TypedDict, total=False): """Live Link card request. - Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers never receive or choose how the credential is delivered. + Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers do not choose how the credential is delivered; after authorize, state.credential_type reports it. """ amount: Required[int] diff --git a/src/kernel/types/vaults/payment_request_vault_item_state.py b/src/kernel/types/vaults/payment_request_vault_item_state.py index 016a547b..f68c7c04 100644 --- a/src/kernel/types/vaults/payment_request_vault_item_state.py +++ b/src/kernel/types/vaults/payment_request_vault_item_state.py @@ -53,6 +53,15 @@ class LinkCardState(BaseModel): and should approve only the new one. """ + credential_type: Optional[Literal["card", "link_pay_token"]] = None + """ + The Link spend request's credential_type, set when authorize sends the request + to Link. Absent before authorize and after Link rejects the request; a ready + card without it fills like card. card is a Link virtual card; fill it with field + bindings. link_pay_token is a Link Pay Token that Kernel supplies through the + checkout's Link WebMCP tool; fill it without fields. + """ + domains: Optional[List[str]] = None masks: Optional[LinkCardStateMasks] = None diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py index 43f81ab3..253e2f03 100644 --- a/src/kernel/types/vaults/vault_item.py +++ b/src/kernel/types/vaults/vault_item.py @@ -197,7 +197,8 @@ class CardVaultItem(BaseModel): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ state: CardVaultItemState diff --git a/src/kernel/types/vaults/vault_item_operation_response.py b/src/kernel/types/vaults/vault_item_operation_response.py index 31a923e4..220906fb 100644 --- a/src/kernel/types/vaults/vault_item_operation_response.py +++ b/src/kernel/types/vaults/vault_item_operation_response.py @@ -202,7 +202,8 @@ class CardVaultItem(BaseModel): until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card - otherwise. Callers never receive or choose how the credential is delivered. + otherwise. Callers do not choose how the credential is delivered; after + authorize, state.credential_type reports it. """ state: CardVaultItemState