From ca0bdb1f663b89063e811cf053433c613f86c71b Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Thu, 26 Feb 2026 16:26:49 +0300 Subject: [PATCH 1/8] YCIAM-9516 oauth token deprecation --- README.md | 8 +------- examples/compute/main.py | 6 +++--- examples/dataproc/main.py | 6 +++--- examples/dataproc/using_wrapper.py | 6 +++--- examples/dataproc/using_wrapper_miminal.py | 6 +++--- examples/mdb/clickhouse/main.py | 6 +++--- examples/mdb/mongodb/main.py | 6 +++--- examples/mdb/mysql/main.py | 6 +++--- examples/mdb/postgresql/main.py | 6 +++--- examples/mdb/redis/main.py | 6 +++--- examples/spark/main.py | 6 +++--- tests/test_service_account_auth.py | 12 +++--------- yandexcloud/_auth_fabric.py | 5 +++++ 13 files changed, 39 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index b101b09a..c1e1ae6c 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,10 @@ Installation: ## Getting started -There are several options for authorization your requests - OAuth Token, +There are several options for authorization your requests - Metadata Service (if you're executing your code inside VMs or Cloud Functions running in Yandex.Cloud), Service Account Keys, and externally created IAM tokens. -### OAuth Token - -```python -sdk = yandexcloud.SDK(token='AQAD-.....') -``` - ### Metadata Service Don't forget to assign Service Account for your Instance or Function and grant required roles. diff --git a/examples/compute/main.py b/examples/compute/main.py index 2da5f3e4..0b104e56 100644 --- a/examples/compute/main.py +++ b/examples/compute/main.py @@ -77,8 +77,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_args() interceptor = yandexcloud.RetryInterceptor(max_retry_count=5, retriable_codes=[grpc.StatusCode.UNAVAILABLE]) - if arguments.token: - sdk = yandexcloud.SDK(interceptor=interceptor, token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(interceptor=interceptor, iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(interceptor=interceptor, service_account_key=json.load(infile)) @@ -125,7 +125,7 @@ def parse_args(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to.") parser.add_argument("--name", default="demo-instance", help="New instance name.") diff --git a/examples/dataproc/main.py b/examples/dataproc/main.py index 19bc1bf5..bb3c901b 100644 --- a/examples/dataproc/main.py +++ b/examples/dataproc/main.py @@ -25,8 +25,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token, user_agent=USER_AGENT) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token, user_agent=USER_AGENT) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile), user_agent=USER_AGENT) @@ -62,7 +62,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/dataproc/using_wrapper.py b/examples/dataproc/using_wrapper.py index 23a53fa1..bce72b15 100644 --- a/examples/dataproc/using_wrapper.py +++ b/examples/dataproc/using_wrapper.py @@ -14,8 +14,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token, user_agent=USER_AGENT) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token, user_agent=USER_AGENT) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile), user_agent=USER_AGENT) @@ -175,7 +175,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/dataproc/using_wrapper_miminal.py b/examples/dataproc/using_wrapper_miminal.py index c0c0e6ae..ffaa8265 100644 --- a/examples/dataproc/using_wrapper_miminal.py +++ b/examples/dataproc/using_wrapper_miminal.py @@ -13,8 +13,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token, user_agent=USER_AGENT) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token, user_agent=USER_AGENT) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile), user_agent=USER_AGENT) @@ -63,7 +63,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/mdb/clickhouse/main.py b/examples/mdb/clickhouse/main.py index 1fbfc8d8..b19d13ac 100644 --- a/examples/mdb/clickhouse/main.py +++ b/examples/mdb/clickhouse/main.py @@ -16,8 +16,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile)) @@ -44,7 +44,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/mdb/mongodb/main.py b/examples/mdb/mongodb/main.py index 1bdb363a..b67e8625 100644 --- a/examples/mdb/mongodb/main.py +++ b/examples/mdb/mongodb/main.py @@ -16,8 +16,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile)) @@ -44,7 +44,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/mdb/mysql/main.py b/examples/mdb/mysql/main.py index 672145c5..8f4e2b3f 100644 --- a/examples/mdb/mysql/main.py +++ b/examples/mdb/mysql/main.py @@ -16,8 +16,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile)) @@ -44,7 +44,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/mdb/postgresql/main.py b/examples/mdb/postgresql/main.py index dabdf22d..646697fa 100644 --- a/examples/mdb/postgresql/main.py +++ b/examples/mdb/postgresql/main.py @@ -16,8 +16,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile)) @@ -44,7 +44,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/mdb/redis/main.py b/examples/mdb/redis/main.py index d37261ab..ea28f074 100644 --- a/examples/mdb/redis/main.py +++ b/examples/mdb/redis/main.py @@ -15,8 +15,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile)) @@ -42,7 +42,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--zone", default="ru-central1-b", help="Compute Engine zone to deploy to") parser.add_argument("--network-id", default="", help="Your Yandex.Cloud network id") diff --git a/examples/spark/main.py b/examples/spark/main.py index fecc61dd..8707cce3 100644 --- a/examples/spark/main.py +++ b/examples/spark/main.py @@ -18,7 +18,7 @@ def parse_cmd(): help="Path to the service account key JSON file.\nThis file can be created using YC CLI:\n" "yc iam key create --output sa.json --service-account-id ", ) - auth.add_argument("--token", help="OAuth token") + auth.add_argument("--iam-token", help="Iam token") parser.add_argument("--folder-id", help="Your Yandex.Cloud folder id", required=True) parser.add_argument("--service-account-id", type=str, default="") @@ -43,8 +43,8 @@ def main(): logging.basicConfig(level=logging.INFO) arguments = parse_cmd() - if arguments.token: - sdk = yandexcloud.SDK(token=arguments.token) + if arguments.iam_token: + sdk = yandexcloud.SDK(iam_token=arguments.iam_token) else: with open(arguments.sa_json_path) as infile: sdk = yandexcloud.SDK(service_account_key=json.load(infile)) diff --git a/tests/test_service_account_auth.py b/tests/test_service_account_auth.py index 041a9895..deb99416 100644 --- a/tests/test_service_account_auth.py +++ b/tests/test_service_account_auth.py @@ -6,11 +6,11 @@ from yandexcloud._auth_fabric import get_auth_token_requester -def test_both_params_error(token, service_account_key): +def test_both_params_error(iam_token, service_account_key): with pytest.raises(RuntimeError) as e: - get_auth_token_requester(token=token, service_account_key=service_account_key).get_token_request() + get_auth_token_requester(iam_token=iam_token, service_account_key=service_account_key).get_token_request() - assert str(e.value) == "Conflicting API credentials properties are set: ['token', 'service_account_key']." + assert str(e.value) == "Conflicting API credentials properties are set: ['iam_token', 'service_account_key']." def test_invalid_service_account_type(): @@ -37,12 +37,6 @@ def test_service_account_no_id(service_account_key, key, error_msg): assert str(e.value) == error_msg -def test_oauth_token(token): - request_func = get_auth_token_requester(token=token).get_token_request - request = request_func() - assert token == request.yandex_passport_oauth_token - - def test_service_account_key(service_account_key): request_func = get_auth_token_requester(service_account_key=service_account_key).get_token_request request = request_func() diff --git a/yandexcloud/_auth_fabric.py b/yandexcloud/_auth_fabric.py index 95b795b0..682925ae 100644 --- a/yandexcloud/_auth_fabric.py +++ b/yandexcloud/_auth_fabric.py @@ -135,6 +135,11 @@ def get_auth_token_requester( raise RuntimeError(f"Conflicting API credentials properties are set: {[auth[0] for auth in auth_methods]}.") if token is not None: + warnings.warn( + "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", + DeprecationWarning, + stacklevel=2 + ) return TokenAuth(token=token) if iam_token is not None: return IamTokenAuth(iam_token) From e2f57aa84ec1044b07905c108243209b5d4abff2 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:06:00 +0300 Subject: [PATCH 2/8] fix checkstyle --- yandexcloud/_auth_fabric.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yandexcloud/_auth_fabric.py b/yandexcloud/_auth_fabric.py index 682925ae..90e735cd 100644 --- a/yandexcloud/_auth_fabric.py +++ b/yandexcloud/_auth_fabric.py @@ -1,5 +1,6 @@ import os import time +import warnings from datetime import datetime from typing import Dict, Optional, Union @@ -136,7 +137,8 @@ def get_auth_token_requester( if token is not None: warnings.warn( - "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", + "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. " + + "By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", DeprecationWarning, stacklevel=2 ) From 1f44dbc714c1c023d29293fb3fdaac8fbf9ed387 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:14:17 +0300 Subject: [PATCH 3/8] fix checkstyle --- yandexcloud/_auth_fabric.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yandexcloud/_auth_fabric.py b/yandexcloud/_auth_fabric.py index 90e735cd..687f15b5 100644 --- a/yandexcloud/_auth_fabric.py +++ b/yandexcloud/_auth_fabric.py @@ -137,10 +137,10 @@ def get_auth_token_requester( if token is not None: warnings.warn( - "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. " + - "By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", + "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. " + + "By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", DeprecationWarning, - stacklevel=2 + stacklevel=2, ) return TokenAuth(token=token) if iam_token is not None: From 48b7d760c035ebcfa1eb6c674c80415b37106668 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:15:32 +0300 Subject: [PATCH 4/8] fix checkstyle --- yandexcloud/_auth_fabric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yandexcloud/_auth_fabric.py b/yandexcloud/_auth_fabric.py index 687f15b5..7a9c5400 100644 --- a/yandexcloud/_auth_fabric.py +++ b/yandexcloud/_auth_fabric.py @@ -137,7 +137,7 @@ def get_auth_token_requester( if token is not None: warnings.warn( - "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. " + "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. " + "By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", DeprecationWarning, stacklevel=2, From 4419d77bbcacdee527658653af114bf5174a1997 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:18:04 +0300 Subject: [PATCH 5/8] fix checkstyle --- yandexcloud/_auth_fabric.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/yandexcloud/_auth_fabric.py b/yandexcloud/_auth_fabric.py index 7a9c5400..7b345933 100644 --- a/yandexcloud/_auth_fabric.py +++ b/yandexcloud/_auth_fabric.py @@ -137,8 +137,7 @@ def get_auth_token_requester( if token is not None: warnings.warn( - "The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. " - + "By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.", + "By the end of 2026 OAuthToken will be discontinued at Yandex Cloud. Please consider to use another credetials provider.", DeprecationWarning, stacklevel=2, ) From c63a1bef1c35ee6b6761d2d90c6ed22f72ade593 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:26:58 +0300 Subject: [PATCH 6/8] fix checkstyle --- yandexcloud/_auth_fabric.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yandexcloud/_auth_fabric.py b/yandexcloud/_auth_fabric.py index 7b345933..c9b50f4a 100644 --- a/yandexcloud/_auth_fabric.py +++ b/yandexcloud/_auth_fabric.py @@ -137,7 +137,8 @@ def get_auth_token_requester( if token is not None: warnings.warn( - "By the end of 2026 OAuthToken will be discontinued at Yandex Cloud. Please consider to use another credetials provider.", + """The 'token' argument corresponds to OAuthToken credential provider, which is deprecated at Yandex Cloud. + By the end of 2026 will be fully discontinued. Please consider to use another credetials provider.""", DeprecationWarning, stacklevel=2, ) From 97e6aab878f590a867fc2672e07de0107ea6d6a0 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:33:50 +0300 Subject: [PATCH 7/8] fix checkstyle --- README.md | 6 +++--- tests/test_service_account_auth.py | 2 +- yandexcloud/_channels.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c1e1ae6c..2b361b15 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ Installation: ## Getting started -There are several options for authorization your requests - -Metadata Service (if you're executing your code inside VMs or Cloud Functions -running in Yandex.Cloud), Service Account Keys, and externally created IAM tokens. +There are several options for authorization your requests - Metadata Service +(if you're executing your code inside VMs or Cloud Functions running in Yandex.Cloud), +Service Account Keys and externally created IAM tokens. ### Metadata Service diff --git a/tests/test_service_account_auth.py b/tests/test_service_account_auth.py index deb99416..ad01a592 100644 --- a/tests/test_service_account_auth.py +++ b/tests/test_service_account_auth.py @@ -10,7 +10,7 @@ def test_both_params_error(iam_token, service_account_key): with pytest.raises(RuntimeError) as e: get_auth_token_requester(iam_token=iam_token, service_account_key=service_account_key).get_token_request() - assert str(e.value) == "Conflicting API credentials properties are set: ['iam_token', 'service_account_key']." + assert str(e.value) == "Conflicting API credentials properties are set: ['service_account_key', 'iam_token']." def test_invalid_service_account_type(): diff --git a/yandexcloud/_channels.py b/yandexcloud/_channels.py index d23f96a4..51b7aaf4 100644 --- a/yandexcloud/_channels.py +++ b/yandexcloud/_channels.py @@ -65,7 +65,7 @@ def channel(self, service: str, endpoint: Optional[str] = None, insecure: bool = if insecure: logger.info("Insecure option is ON, no IAM endpoint used for verification") return grpc.insecure_channel(endpoint, options=self.channel_options) - logger.info("Insecure option is OFF,IAM endpoint %s used for verification") + logger.info("Insecure option is OFF,IAM endpoint %s used for verification", endpoint) creds: grpc.ChannelCredentials = self._get_creds(self.endpoints["iam"]) return grpc.secure_channel(endpoint, creds, options=self.channel_options) if service not in self._config_endpoints and insecure: From e426c54d5ef4416e097bd31771daf36ede0d44e7 Mon Sep 17 00:00:00 2001 From: Andrei Sirotenko Date: Mon, 2 Mar 2026 22:36:16 +0300 Subject: [PATCH 8/8] fix checkstyle --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b361b15..58ff21ab 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ Installation: ## Getting started -There are several options for authorization your requests - Metadata Service -(if you're executing your code inside VMs or Cloud Functions running in Yandex.Cloud), +There are several options for authorization your requests - Metadata Service +(if you're executing your code inside VMs or Cloud Functions running in Yandex.Cloud), Service Account Keys and externally created IAM tokens. ### Metadata Service