diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d3dc9f51..988e843f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.115.0" + ".": "0.116.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fb89f8f..416063a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.116.0](https://github.com/kernel/kernel-python-sdk/compare/v0.115.0...v0.116.0) (2026-10-01) + + +### Features + +* chore(stlc): seal custom-code tracking files ([c053ce4](https://github.com/kernel/kernel-python-sdk/commit/c053ce45e5d6bfaa4577310d28b3ecf0a7c16f4e)) + ## [0.115.0](https://github.com/kernel/kernel-python-sdk/compare/v0.114.0...v0.115.0) (2026-09-30) diff --git a/pyproject.toml b/pyproject.toml index 36366e3d..4e31e28e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.115.0" +version = "0.116.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 19bf404c..ba815a7f 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.115.0" # x-release-please-version +__version__ = "0.116.0" # x-release-please-version diff --git a/src/kernel/resources/credentials.py b/src/kernel/resources/credentials.py index f1a3ac01..47eb0aad 100644 --- a/src/kernel/resources/credentials.py +++ b/src/kernel/resources/credentials.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Dict, Optional +from typing_extensions import Literal import httpx @@ -54,6 +55,9 @@ def create( name: str, values: Dict[str, str], sso_provider: str | Omit = omit, + totp_algorithm: Literal["SHA1", "SHA256", "SHA512"] | Omit = omit, + totp_digits: int | Omit = omit, + totp_period: int | Omit = omit, totp_secret: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -77,8 +81,20 @@ def create( button, it will be clicked first before filling credential values on the identity provider's login page. - totp_secret: Base32-encoded TOTP secret for generating one-time passwords. Used for automatic - 2FA during login. + totp_algorithm: HMAC algorithm used to generate TOTP codes. Defaults to SHA1 and is ignored when + an `otpauth://` URI supplies the algorithm. + + totp_digits: Number of digits in generated TOTP codes. Defaults to 6 and is ignored when an + `otpauth://` URI supplies the digit count. + + totp_period: TOTP rotation period in seconds. Defaults to 30 and is ignored when an + `otpauth://` URI supplies the period. + + totp_secret: Accepts a 16-128 character base32-encoded TOTP secret or an `otpauth://totp/...` + URI. The range accepts existing shorter seeds and longer seeds regardless of + HMAC algorithm; RFC 6238 recommends unpadded base32 lengths of 32/52/103 for + SHA1/SHA256/SHA512. Only URI parameters present override the corresponding + explicit TOTP fields. Used for automatic 2FA during login. extra_headers: Send extra headers @@ -96,6 +112,9 @@ def create( "name": name, "values": values, "sso_provider": sso_provider, + "totp_algorithm": totp_algorithm, + "totp_digits": totp_digits, + "totp_period": totp_period, "totp_secret": totp_secret, }, credential_create_params.CredentialCreateParams, @@ -147,6 +166,9 @@ def update( name: str | Omit = omit, remove_value_keys: SequenceNotStr[str] | Omit = omit, sso_provider: Optional[str] | Omit = omit, + totp_algorithm: Literal["SHA1", "SHA256", "SHA512"] | Omit = omit, + totp_digits: int | Omit = omit, + totp_period: int | Omit = omit, totp_secret: str | Omit = omit, values: Dict[str, str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -170,8 +192,20 @@ def update( sso_provider: If set, indicates this credential should be used with the specified SSO provider. Set to empty string or null to remove. - totp_secret: Base32-encoded TOTP secret for generating one-time passwords. Spaces and - formatting are automatically normalized. Set to empty string to remove. + totp_algorithm: HMAC algorithm used to generate TOTP codes. Requires totp_secret and is ignored + when an `otpauth://` URI supplies the algorithm. + + totp_digits: Number of digits in generated TOTP codes. Requires totp_secret and is ignored + when an `otpauth://` URI supplies the digit count. + + totp_period: TOTP rotation period in seconds. Requires totp_secret and is ignored when an + `otpauth://` URI supplies the period. + + totp_secret: Accepts a 16-128 character base32-encoded TOTP secret or an `otpauth://totp/...` + URI. Only URI parameters present override the corresponding explicit TOTP + fields. When rotating a raw secret, omitted fields preserve their existing + values; a new URI defaults unspecified fields to SHA1/6/30. Set to empty string + to remove the secret and its metadata. values: Field name to value mapping. Values are merged with existing values (new keys added, existing keys overwritten). @@ -193,6 +227,9 @@ def update( "name": name, "remove_value_keys": remove_value_keys, "sso_provider": sso_provider, + "totp_algorithm": totp_algorithm, + "totp_digits": totp_digits, + "totp_period": totp_period, "totp_secret": totp_secret, "values": values, }, @@ -360,6 +397,9 @@ async def create( name: str, values: Dict[str, str], sso_provider: str | Omit = omit, + totp_algorithm: Literal["SHA1", "SHA256", "SHA512"] | Omit = omit, + totp_digits: int | Omit = omit, + totp_period: int | Omit = omit, totp_secret: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -383,8 +423,20 @@ async def create( button, it will be clicked first before filling credential values on the identity provider's login page. - totp_secret: Base32-encoded TOTP secret for generating one-time passwords. Used for automatic - 2FA during login. + totp_algorithm: HMAC algorithm used to generate TOTP codes. Defaults to SHA1 and is ignored when + an `otpauth://` URI supplies the algorithm. + + totp_digits: Number of digits in generated TOTP codes. Defaults to 6 and is ignored when an + `otpauth://` URI supplies the digit count. + + totp_period: TOTP rotation period in seconds. Defaults to 30 and is ignored when an + `otpauth://` URI supplies the period. + + totp_secret: Accepts a 16-128 character base32-encoded TOTP secret or an `otpauth://totp/...` + URI. The range accepts existing shorter seeds and longer seeds regardless of + HMAC algorithm; RFC 6238 recommends unpadded base32 lengths of 32/52/103 for + SHA1/SHA256/SHA512. Only URI parameters present override the corresponding + explicit TOTP fields. Used for automatic 2FA during login. extra_headers: Send extra headers @@ -402,6 +454,9 @@ async def create( "name": name, "values": values, "sso_provider": sso_provider, + "totp_algorithm": totp_algorithm, + "totp_digits": totp_digits, + "totp_period": totp_period, "totp_secret": totp_secret, }, credential_create_params.CredentialCreateParams, @@ -453,6 +508,9 @@ async def update( name: str | Omit = omit, remove_value_keys: SequenceNotStr[str] | Omit = omit, sso_provider: Optional[str] | Omit = omit, + totp_algorithm: Literal["SHA1", "SHA256", "SHA512"] | Omit = omit, + totp_digits: int | Omit = omit, + totp_period: int | Omit = omit, totp_secret: str | Omit = omit, values: Dict[str, str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -476,8 +534,20 @@ async def update( sso_provider: If set, indicates this credential should be used with the specified SSO provider. Set to empty string or null to remove. - totp_secret: Base32-encoded TOTP secret for generating one-time passwords. Spaces and - formatting are automatically normalized. Set to empty string to remove. + totp_algorithm: HMAC algorithm used to generate TOTP codes. Requires totp_secret and is ignored + when an `otpauth://` URI supplies the algorithm. + + totp_digits: Number of digits in generated TOTP codes. Requires totp_secret and is ignored + when an `otpauth://` URI supplies the digit count. + + totp_period: TOTP rotation period in seconds. Requires totp_secret and is ignored when an + `otpauth://` URI supplies the period. + + totp_secret: Accepts a 16-128 character base32-encoded TOTP secret or an `otpauth://totp/...` + URI. Only URI parameters present override the corresponding explicit TOTP + fields. When rotating a raw secret, omitted fields preserve their existing + values; a new URI defaults unspecified fields to SHA1/6/30. Set to empty string + to remove the secret and its metadata. values: Field name to value mapping. Values are merged with existing values (new keys added, existing keys overwritten). @@ -499,6 +569,9 @@ async def update( "name": name, "remove_value_keys": remove_value_keys, "sso_provider": sso_provider, + "totp_algorithm": totp_algorithm, + "totp_digits": totp_digits, + "totp_period": totp_period, "totp_secret": totp_secret, "values": values, }, diff --git a/src/kernel/types/credential.py b/src/kernel/types/credential.py index fb2ff6e1..3b54587c 100644 --- a/src/kernel/types/credential.py +++ b/src/kernel/types/credential.py @@ -2,6 +2,7 @@ from typing import List, Optional from datetime import datetime +from typing_extensions import Literal from .._models import BaseModel @@ -40,8 +41,14 @@ class Credential(BaseModel): identity provider's login page. """ + totp_algorithm: Optional[Literal["SHA1", "SHA256", "SHA512"]] = None + """HMAC algorithm used to generate TOTP codes. + + Defaults to SHA1 for credentials created before this metadata was stored. + """ + totp_code: Optional[str] = None - """Current 6-digit TOTP code. + """Current TOTP code. Only included in create/update responses when totp_secret was just set. """ @@ -49,6 +56,18 @@ class Credential(BaseModel): totp_code_expires_at: Optional[datetime] = None """When the totp_code expires. Only included when totp_code is present.""" + totp_digits: Optional[int] = None + """Number of digits in generated TOTP codes. + + Defaults to 6 for credentials created before this metadata was stored. + """ + + totp_period: Optional[int] = None + """TOTP rotation period in seconds. + + Defaults to 30 for credentials created before this metadata was stored. + """ + value_keys: Optional[List[str]] = None """The field names stored in this credential's values (e.g., username, password). diff --git a/src/kernel/types/credential_create_params.py b/src/kernel/types/credential_create_params.py index 9d306844..526b7149 100644 --- a/src/kernel/types/credential_create_params.py +++ b/src/kernel/types/credential_create_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Dict -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["CredentialCreateParams"] @@ -26,8 +26,29 @@ class CredentialCreateParams(TypedDict, total=False): identity provider's login page. """ - totp_secret: str - """Base32-encoded TOTP secret for generating one-time passwords. + totp_algorithm: Literal["SHA1", "SHA256", "SHA512"] + """HMAC algorithm used to generate TOTP codes. + + Defaults to SHA1 and is ignored when an `otpauth://` URI supplies the algorithm. + """ + + totp_digits: int + """Number of digits in generated TOTP codes. + + Defaults to 6 and is ignored when an `otpauth://` URI supplies the digit count. + """ - Used for automatic 2FA during login. + totp_period: int + """TOTP rotation period in seconds. + + Defaults to 30 and is ignored when an `otpauth://` URI supplies the period. + """ + + totp_secret: str + """ + Accepts a 16-128 character base32-encoded TOTP secret or an `otpauth://totp/...` + URI. The range accepts existing shorter seeds and longer seeds regardless of + HMAC algorithm; RFC 6238 recommends unpadded base32 lengths of 32/52/103 for + SHA1/SHA256/SHA512. Only URI parameters present override the corresponding + explicit TOTP fields. Used for automatic 2FA during login. """ diff --git a/src/kernel/types/credential_update_params.py b/src/kernel/types/credential_update_params.py index 9da3f09c..976c62c4 100644 --- a/src/kernel/types/credential_update_params.py +++ b/src/kernel/types/credential_update_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Dict, Optional -from typing_extensions import TypedDict +from typing_extensions import Literal, TypedDict from .._types import SequenceNotStr @@ -28,11 +28,34 @@ class CredentialUpdateParams(TypedDict, total=False): Set to empty string or null to remove. """ - totp_secret: str - """Base32-encoded TOTP secret for generating one-time passwords. + totp_algorithm: Literal["SHA1", "SHA256", "SHA512"] + """HMAC algorithm used to generate TOTP codes. + + Requires totp_secret and is ignored when an `otpauth://` URI supplies the + algorithm. + """ + + totp_digits: int + """Number of digits in generated TOTP codes. + + Requires totp_secret and is ignored when an `otpauth://` URI supplies the digit + count. + """ - Spaces and formatting are automatically normalized. Set to empty string to - remove. + totp_period: int + """TOTP rotation period in seconds. + + Requires totp_secret and is ignored when an `otpauth://` URI supplies the + period. + """ + + totp_secret: str + """ + Accepts a 16-128 character base32-encoded TOTP secret or an `otpauth://totp/...` + URI. Only URI parameters present override the corresponding explicit TOTP + fields. When rotating a raw secret, omitted fields preserve their existing + values; a new URI defaults unspecified fields to SHA1/6/30. Set to empty string + to remove the secret and its metadata. """ values: Dict[str, str] diff --git a/src/kernel/types/vaults/card_vault_item_spec.py b/src/kernel/types/vaults/card_vault_item_spec.py index 0c73d9bf..880ce111 100644 --- a/src/kernel/types/vaults/card_vault_item_spec.py +++ b/src/kernel/types/vaults/card_vault_item_spec.py @@ -96,7 +96,7 @@ class LinkCardVaultItemSpec(BaseModel): class AgentCardCardVaultItemSpec(BaseModel): """AgentCard reusable live payment card. - Test-mode card creation is not supported. Each checkout creates an approval-gated authorization for spec.merchant / spec.amount. The card stays ready after each authorization. + Test-mode card creation is not supported. Each checkout creates an authorization for spec.merchant / spec.amount that the cardholder approves, unless AgentCard runs it under one of the cardholder's autopilot rules. The card stays ready after each authorization. """ amount: int @@ -119,6 +119,18 @@ class AgentCardCardVaultItemSpec(BaseModel): cardholder picks on the approval screen. """ + checkout_origin: Optional[str] = None + """ + Origin of the top-level checkout page, such as https://shop.example.com: https, + a lowercase host, a port only when it is not 443, and no path. http is accepted + only for localhost test pages. Checkouts without a preparation send it to + AgentCard, which uses it to match the cardholder's autopilot rules; prepared + checkouts send the preparation's merchant_origin instead. Kernel sends the + declared value and does not compare it with the page the browser has open. + Omitted, those checkouts ask the cardholder to approve. Card updates replace the + whole spec, so an update that omits it removes it. + """ + CardVaultItemSpec: TypeAlias = Annotated[ Union[LinkCardVaultItemSpec, AgentCardCardVaultItemSpec], PropertyInfo(discriminator="provider") 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 7172d066..3f27771a 100644 --- a/src/kernel/types/vaults/card_vault_item_spec_param.py +++ b/src/kernel/types/vaults/card_vault_item_spec_param.py @@ -95,7 +95,7 @@ class LinkCardVaultItemSpec(TypedDict, total=False): class AgentCardCardVaultItemSpec(TypedDict, total=False): """AgentCard reusable live payment card. - Test-mode card creation is not supported. Each checkout creates an approval-gated authorization for spec.merchant / spec.amount. The card stays ready after each authorization. + Test-mode card creation is not supported. Each checkout creates an authorization for spec.merchant / spec.amount that the cardholder approves, unless AgentCard runs it under one of the cardholder's autopilot rules. The card stays ready after each authorization. """ amount: Required[int] @@ -118,5 +118,17 @@ class AgentCardCardVaultItemSpec(TypedDict, total=False): cardholder picks on the approval screen. """ + checkout_origin: str + """ + Origin of the top-level checkout page, such as https://shop.example.com: https, + a lowercase host, a port only when it is not 443, and no path. http is accepted + only for localhost test pages. Checkouts without a preparation send it to + AgentCard, which uses it to match the cardholder's autopilot rules; prepared + checkouts send the preparation's merchant_origin instead. Kernel sends the + declared value and does not compare it with the page the browser has open. + Omitted, those checkouts ask the cardholder to approve. Card updates replace the + whole spec, so an update that omits it removes it. + """ + CardVaultItemSpecParam: TypeAlias = Union[LinkCardVaultItemSpec, AgentCardCardVaultItemSpec] diff --git a/tests/api_resources/test_credentials.py b/tests/api_resources/test_credentials.py index 9fddf1c0..b2079b5b 100644 --- a/tests/api_resources/test_credentials.py +++ b/tests/api_resources/test_credentials.py @@ -45,6 +45,9 @@ def test_method_create_with_all_params(self, client: Kernel) -> None: "password": "mysecretpassword", }, sso_provider="google", + totp_algorithm="SHA1", + totp_digits=6, + totp_period=30, totp_secret="JBSWY3DPEHPK3PXP", ) assert_matches_type(Credential, credential, path=["response"]) @@ -143,6 +146,9 @@ def test_method_update_with_all_params(self, client: Kernel) -> None: name="my-updated-login", remove_value_keys=["old_field"], sso_provider="google", + totp_algorithm="SHA1", + totp_digits=6, + totp_period=30, totp_secret="JBSWY3DPEHPK3PXP", values={ "username": "user@example.com", @@ -338,6 +344,9 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) -> "password": "mysecretpassword", }, sso_provider="google", + totp_algorithm="SHA1", + totp_digits=6, + totp_period=30, totp_secret="JBSWY3DPEHPK3PXP", ) assert_matches_type(Credential, credential, path=["response"]) @@ -436,6 +445,9 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> name="my-updated-login", remove_value_keys=["old_field"], sso_provider="google", + totp_algorithm="SHA1", + totp_digits=6, + totp_period=30, totp_secret="JBSWY3DPEHPK3PXP", values={ "username": "user@example.com",