Switch SiS demo to OAuth session token auth#63
Switch SiS demo to OAuth session token auth#63j-seuren wants to merge 5 commits intoJetBrains:mainfrom
Conversation
Replace password-based service user authentication with OAuth session token auth in the Streamlit-in-Snowflake demo. The app now reads the SPCS-provided token from /snowflake/session/token on every connection, authenticating as the logged-in Snowflake user. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The YAML now includes `authenticator: externalbrowser` so local dev works out of the box with Snowflake SSO. In SiS, the monkey-patch overrides this with OAuth token auth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Switches the Streamlit-in-Snowflake (SiS) demo from stored Snowflake service-user credentials to using the SiS-provided OAuth session token so the app authenticates as the logged-in Snowflake user.
Changes:
- Monkey-patches
SnowflakeIntrospector._connectin SiS to connect withauthenticator=oauth+ fresh token read from/snowflake/session/token. - Removes service-user / network-policy setup and deletes datasource credential secrets from setup/cleanup SQL.
- Updates demo Snowflake domain config and README to reflect new auth model and required grants.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/demo-snowflake-project/src/databao_snowflake_demo/app.py | Adds SiS detection + token-based OAuth connect patch for the Snowflake introspector. |
| examples/demo-snowflake-project/setup.sql | Removes service-user/network-policy provisioning and datasource credential secrets; keeps only warehouse/database config secrets. |
| examples/demo-snowflake-project/cleanup.sql | Removes cleanup steps for the deleted service-user/network-policy resources. |
| examples/demo-snowflake-project/databao/domains/root/src/snowflake.yaml | Switches account env var to SNOWFLAKE_ACCOUNT and uses externalbrowser auth for local runs (overridden in SiS by the patch). |
| examples/demo-snowflake-project/README.md | Updates documentation for token auth, new env vars, and required USAGE grants. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| SnowflakeIntrospector._connect = _sis_connect # type: ignore[assignment] | ||
| logger.info("Patched SnowflakeIntrospector._connect for SiS OAuth token auth") |
There was a problem hiding this comment.
Overwriting SnowflakeIntrospector._connect at the class level is a broad monkey-patch (affects all instances in-process) and Streamlit reruns can re-apply it repeatedly. Consider adding an idempotency guard (e.g., a sentinel attribute) and/or preserving the original method so it can be restored if needed (helps avoid surprising behavior in mixed environments/tests).
| """ | ||
| @contextmanager | ||
| def _sis_connect(self: Any, file_config: Any, *, catalog: str | None = None) -> Generator[Any, None, None]: | ||
| token = SESSION_TOKEN_PATH.read_text().strip() |
There was a problem hiding this comment.
SESSION_TOKEN_PATH.read_text().strip() can raise (e.g., transient file-not-found/permission issues) and can also produce an empty token; either case will currently bubble up as a low-level exception or a confusing connector auth failure. Consider catching OSError/decode errors, validating the token is non-empty, and raising/logging a clear message that the SiS OAuth session token could not be read from /snowflake/session/token.
| token = SESSION_TOKEN_PATH.read_text().strip() | |
| try: | |
| raw_token = SESSION_TOKEN_PATH.read_text() | |
| except (OSError, UnicodeDecodeError) as exc: | |
| msg = ( | |
| f"Failed to read SiS OAuth session token from {SESSION_TOKEN_PATH!s}. " | |
| "Ensure the token file exists and is readable inside Snowflake." | |
| ) | |
| logger.error(msg, exc_info=True) | |
| raise RuntimeError(msg) from exc | |
| token = raw_token.strip() | |
| if not token: | |
| msg = ( | |
| f"SiS OAuth session token file {SESSION_TOKEN_PATH!s} is empty. " | |
| "Connector authentication cannot proceed." | |
| ) | |
| logger.error(msg) | |
| raise RuntimeError(msg) |
| snowflake.connector.paramstyle = "qmark" | ||
| kwargs = file_config.connection.to_snowflake_kwargs() |
There was a problem hiding this comment.
Setting snowflake.connector.paramstyle = "qmark" mutates connector global state for the whole process (including any other Snowflake connections Streamlit may open). If this is only needed for the introspector connection, consider limiting the scope (set/restore around the connect) or moving it to a one-time initialization with a clear comment explaining why the global change is safe here.
Instead of pre-filling the password field with the env var value (which gets sent to the browser), show a disabled field with a placeholder indicating the env var is in use. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The agent executes SQL through DuckDB's Snowflake extension (separate from the introspector path). The default adapter doesn't support OAuth token auth, so we monkey-patch _create_secret_sql and _create_connection_string to inject the SPCS session token. Also adds the SNOWFLAKE_HOST parameter to both patches — Snowflake docs state the SPCS token can only be used with the SPCS-provided host endpoint. Corrects README claims about owner's rights vs caller's rights. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Switch the Snowflake demo from password-based service user auth to OAuth session token auth in Streamlit-in-Snowflake. The app now authenticates as the logged-in user by reading the SPCS-provided token from
/snowflake/session/token, eliminating stored credentials.Changes
OAuth session token authentication
Monkey-patches
SnowflakeIntrospector._connectwhen running in SiS to useauthenticator=oauthwith a fresh token on every connection (avoids ~1h expiry).Files
examples/demo-snowflake-project/src/databao_snowflake_demo/app.pyexamples/demo-snowflake-project/databao/domains/root/src/snowflake.yamlRemove service user infrastructure
Drops the service user, network policy, and user/password/account secrets from setup/cleanup SQL.
Files
examples/demo-snowflake-project/setup.sqlexamples/demo-snowflake-project/cleanup.sqlDocumentation update
Updates README to reflect the new auth model and note that users need USAGE grants.
Files
examples/demo-snowflake-project/README.mdTest Plan
uv run ruff checkpassesuv run pytest tests/ -v— 65/65 pass🤖 Generated with Claude Code