-
Notifications
You must be signed in to change notification settings - Fork 573
SNOW-4036712: OAuth Authorization Code flow replaces custom public PKCE client_id with LOCAL_APPLICATION #3011
Open
Description
Python version
Python 3.12.12 (main, Jan 27 2026, 23:41:44) [Clang 21.1.4]
Operating system and processor architecture
macOS-26.6.2-arm64-arm-64bit
Installed packages
annotated-doc==0.0.5 annotated-types==0.8.0 anyio==4.14.2 asn1crypto==1.5.1 attrs==26.1.0 boto3==1.43.79 botocore==1.43.79 certifi==2026.7.22 cffi==2.1.1 charset-normalizer==3.5.1 click==8.4.2 cryptography==50.0.1 filelock==3.32.4 h11==0.16.0 httpcore==1.0.9 httpcore2==2.12.0 httpx==0.28.1 httpx-sse==0.4.3 httpx2==2.12.0 idna==3.19 keyring==25.7.0 mcp==2.1.1 mcp-types==2.1.1 packaging==26.3 pydantic==2.13.4 pyjwt==2.13.0 pyopenssl==26.4.0 pytest==9.1.1 python-dateutil==2.9.0.post0 requests==2.34.2 snowflake-connector-python==4.7.2 typing-extensions==4.16.0 urllib3==2.7.0
What did you do?
I configured Authorization Code OAuth with PKCE using a Snowflake custom OAuth integration registered as a public client. Public clients have a client_id but no client_secret. Minimal reproducer: from snowflake.connector.auth.oauth_code import AuthByOauthCode requested_client_id = "custom-public-client-id" auth = AuthByOauthCode( application="reproducer", client_id=requested_client_id, client_secret=None, authentication_url=( "https://example.snowflakecomputing.com/oauth/authorize" ), token_request_url=( "https://example.snowflakecomputing.com/oauth/token-request" ), redirect_uri="http://127.0.0.1:8730/", scope="session:role:TEST_ROLE", host="example.snowflakecomputing.com", ) print("requested client_id:", requested_client_id) print("effective client_id:", auth._client_id) print("effective client_secret:", auth._client_secret) Output: requested client_id: custom-public-client-id effective client_id: LOCAL_APPLICATION effective client_secret: LOCAL_APPLICATION `AuthByOauthCode._eligible_for_default_client_credentials()` considers the configuration eligible for default credentials whenever `client_secret` is None, even when a nonempty custom `client_id` was supplied. Using a dummy nonempty secret is not a valid workaround because the connector transmits it through HTTP Basic authentication. I reproduced the same behavior in connector versions 3.18.0 through 4.7.2. Using client_secret="" instead fails with:
What did you expect to see?
For an Authorization Code + PKCE public client, the connector should:
- Preserve the supplied custom client_id.
- Permit an absent client secret.
- Include client_id in the token request form.
- Omit the HTTP Basic Authorization header.
Instead, the connector silently replaces both values with LOCAL_APPLICATION. This authenticates against the wrong Snowflake OAuth integration and can also reuse tokens cached for that integration.
Can you set logging to DEBUG and collect the logs?
2026年08月28日 15:59:01,506 DEBUG snowflake.connector.auth.oauth_code chose oauth state: **********************************************************
2026年08月28日 15:59:01,506 DEBUG snowflake.connector.auth.oauth_code oauth pkce is going to be used
requested client_id: custom-public-client-id
effective client_id: LOCAL_APPLICATION
effective client_secret: LOCAL_APPLICATION