-
Notifications
You must be signed in to change notification settings - Fork 527
Add support for workload identity federation #2203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
97b021d
Add AWS dependencies
sfc-gh-pmansour 8bde498
add basic attestation loading
sfc-gh-pmansour d215fa7
improve the contract for fetching WIF attestations
sfc-gh-pmansour f01e0b2
Add explicit attestation provider type, support for OIDC tokens
sfc-gh-pmansour 2fd8825
add associated error codes
sfc-gh-pmansour 05a6d91
fix small bugs, clean-up data structures, add auto-detect provider
sfc-gh-pmansour b491f39
fix docstrings
sfc-gh-pmansour 4ed9819
add an entry point
sfc-gh-pmansour a4453b0
add WLID authenticator plugin
sfc-gh-pmansour 536da37
Add glue for WLID authenticator
sfc-gh-pmansour c2292f2
Remove explicit handling of token_file_path since this is done in con…
sfc-gh-pmansour 98fe189
Add unit tests for connection plumbing
sfc-gh-pmansour 206d383
fix bug with default value of workload_identity_provider
sfc-gh-pmansour f5052f6
small bug fix in HTTP request
sfc-gh-pmansour e5690fb
update logic for assertion_content
sfc-gh-pmansour 986a5b2
fix whitespace
sfc-gh-pmansour 4136a5a
update error message
sfc-gh-pmansour 88aa743
wrap metadata server requests in a try..except block
sfc-gh-pmansour 7b0b895
include issuer in Azure identifier string
sfc-gh-pmansour c08a77e
add unit tests
sfc-gh-pmansour da6db75
change order of constants
sfc-gh-pmansour 873bdcc
Slight refactor of metadata calls, added debug logs for missing crede…
sfc-gh-pmansour 3a746df
refactor token parsing
sfc-gh-pmansour deaa66c
gate the feature on the preview env variable
sfc-gh-pmansour d416752
update autodetect logic for OIDC
sfc-gh-pmansour 007380c
allow explicit setting of entra resource, don't ask for account
sfc-gh-pmansour 75f850f
add tests for Entra resource plumbing
sfc-gh-pmansour 814cb28
add support for AWS region and arn loading
sfc-gh-pmansour 724940d
add support for azure functions
sfc-gh-pmansour 9238e81
Extract CSP mocking logic to a separate file with context managers an…
sfc-gh-pmansour f24dcf6
Replace placeholder Azure resource with fake one that will break
sfc-gh-pmansour e3275dd
remove stale todos
sfc-gh-pmansour 79c813c
use extracted helper function
sfc-gh-pmansour 3d25921
use dict that was extracted earlier in test helper
sfc-gh-pmansour 4087ca6
Update comments for test helpers
sfc-gh-pmansour 02886e5
update test verification for AWS tokens
sfc-gh-pmansour 80ac41d
minor test changes
sfc-gh-pmansour 8cc8f38
updated JWT parsing error handling
sfc-gh-pmansour b2a3ca9
Run formatter
sfc-gh-pmansour 9bfdc2f
Move new fixtures to conftest.py
sfc-gh-pmansour ae7e252
Fix flake8 issues
sfc-gh-pmansour 86fdda0
fix old driver tests by wrapping imports in a try..except block
sfc-gh-pmansour 82e5810
slight changes for the PR
sfc-gh-pmansour 5e6f137
update fix for old driver tests
sfc-gh-pmansour 525c746
fix for old driver imports
sfc-gh-pmansour e7a8bc8
Move newer fixtures to unit-test specific conftest file
sfc-gh-pmansour 54d87b1
Fix how we're defining default WLID-specific params
sfc-gh-pmansour 467d59d
don't run old driver tests against unit tests or pandas tests
sfc-gh-pmansour 5400f25
Make AuthByWorkloadIdentity only accept keyword args
sfc-gh-pmansour 3794f9f
Make reauthenticate a no-op
sfc-gh-pmansour d8638d8
Add explanation for tox.ini olddriver change
sfc-gh-pmansour c95c29b
Update enum parsing from TOML, add test for TOML connection config
sfc-gh-pmansour b6bc1ee
Small fix for Windows paths
sfc-gh-pmansour File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| # | ||
| # Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved. | ||
| # | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import json | ||
| import typing | ||
| from enum import Enum, unique | ||
|
|
||
| from ..network import WORKLOAD_IDENTITY_AUTHENTICATOR | ||
| from ..wif_util import ( | ||
| AttestationProvider, | ||
| WorkloadIdentityAttestation, | ||
| create_attestation, | ||
| ) | ||
| from .by_plugin import AuthByPlugin, AuthType | ||
|
|
||
|
|
||
| @unique | ||
| class ApiFederatedAuthenticationType(Enum): | ||
| """An API-specific enum of the WIF authentication type.""" | ||
|
|
||
| AWS = "AWS" | ||
| AZURE = "AZURE" | ||
| GCP = "GCP" | ||
| OIDC = "OIDC" | ||
|
|
||
| @staticmethod | ||
| def from_attestation( | ||
| attestation: WorkloadIdentityAttestation, | ||
| ) -> ApiFederatedAuthenticationType: | ||
| """Maps the internal / driver-specific attestation providers to API authenticator types. | ||
|
|
||
| The AttestationProvider is related to how the driver fetches the credential, while the API authenticator | ||
| type is related to how the credential is verified. In most current cases these may be the same, though | ||
| in the future we could have, for example, multiple AttestationProviders that all fetch an OIDC ID token. | ||
| """ | ||
| if attestation.provider == AttestationProvider.AWS: | ||
| return ApiFederatedAuthenticationType.AWS | ||
| if attestation.provider == AttestationProvider.AZURE: | ||
| return ApiFederatedAuthenticationType.AZURE | ||
| if attestation.provider == AttestationProvider.GCP: | ||
| return ApiFederatedAuthenticationType.GCP | ||
| if attestation.provider == AttestationProvider.OIDC: | ||
| return ApiFederatedAuthenticationType.OIDC | ||
| return ValueError(f"Unknown attestation provider '{attestation.provider}'") | ||
|
|
||
|
|
||
| class AuthByWorkloadIdentity(AuthByPlugin): | ||
| """Plugin to authenticate via workload identity.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| *, | ||
| provider: AttestationProvider | None = None, | ||
| token: str | None = None, | ||
| entra_resource: str | None = None, | ||
| **kwargs, | ||
| ) -> None: | ||
| super().__init__(**kwargs) | ||
| self.provider = provider | ||
| self.token = token | ||
| self.entra_resource = entra_resource | ||
|
|
||
| self.attestation: WorkloadIdentityAttestation | None = None | ||
|
|
||
| def type_(self) -> AuthType: | ||
| return AuthType.WORKLOAD_IDENTITY | ||
|
|
||
| def reset_secrets(self) -> None: | ||
| self.attestation = None | ||
|
|
||
| def update_body(self, body: dict[typing.Any, typing.Any]) -> None: | ||
| body["data"]["AUTHENTICATOR"] = WORKLOAD_IDENTITY_AUTHENTICATOR | ||
| body["data"]["PROVIDER"] = ApiFederatedAuthenticationType.from_attestation( | ||
| self.attestation | ||
| ).value | ||
| body["data"]["TOKEN"] = self.attestation.credential | ||
|
|
||
| def prepare(self, **kwargs: typing.Any) -> None: | ||
| """Fetch the token.""" | ||
| self.attestation = create_attestation( | ||
| self.provider, self.entra_resource, self.token | ||
| ) | ||
|
|
||
| def reauthenticate(self, **kwargs: typing.Any) -> dict[str, bool]: | ||
sfc-gh-pmansour marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """This is only relevant for AuthByIdToken, which uses a web-browser based flow. All other auth plugins just call authenticate() again.""" | ||
| return {"success": False} | ||
|
|
||
| @property | ||
| def assertion_content(self) -> str: | ||
| """Returns the CSP provider name and an identifier. Used for logging purposes.""" | ||
| if not self.attestation: | ||
| return "" | ||
| properties = self.attestation.user_identifier_components | ||
| properties["_provider"] = self.attestation.provider.value | ||
| return json.dumps(properties, sort_keys=True, separators=(",", ":")) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.