-
Notifications
You must be signed in to change notification settings - Fork 1
Update credential usage across all languages #15
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR updates credential usage across Python, JavaScript, and .NET implementations to require users to explicitly pass authentication credentials instead of relying on internal DefaultAzureCredential instantiation. This change improves flexibility and gives users explicit control over authentication.
- Removed internal fallback to
DefaultAzureCredential()in all language implementations - Updated all connection methods to require credential parameters (no longer optional/nullable)
- Updated documentation and samples to show explicit credential passing
- Moved identity dependencies from core to peer/dev dependencies
Reviewed Changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| python/src/azure_postgresql_auth/core.py | Removed DefaultAzureCredential imports and made credential parameters required (non-nullable) |
| python/src/azure_postgresql_auth/sqlalchemy/entra_connection.py | Updated to require credential via connect_args with validation and added usage examples |
| python/src/azure_postgresql_auth/sqlalchemy/async_entra_connection.py | Updated async SQLAlchemy to require credential via connect_args with validation |
| python/src/azure_postgresql_auth/psycopg3/entra_connection.py | Updated psycopg3 sync connection to require credential parameter |
| python/src/azure_postgresql_auth/psycopg3/async_entra_connection.py | Updated psycopg3 async connection to require AsyncTokenCredential parameter |
| python/src/azure_postgresql_auth/psycopg2/entra_connection.py | Updated psycopg2 connection to require credential parameter |
| python/pyproject.toml | Removed azure-identity from core dependencies |
| python/README.md | Updated all code examples to show explicit credential instantiation |
| python/samples/sqlalchemy/getting_started/create_db_connection.py | Updated sample to pass credential via connect_args |
| python/samples/psycopg3/getting_started/create_db_connection.py | Updated sample to pass credential via kwargs parameter |
| python/samples/psycopg2/getting_started/create_db_connection.py | Updated sample to use partial function to bind credential |
| javascript/src/entra_id_extension.js | Removed DefaultAzureCredential import and made credential parameter required |
| javascript/samples/sequelize/getting-started/create-db-connection.js | Updated sample to instantiate and pass credential explicitly |
| javascript/samples/pg/getting-started/create-db-connection.js | Updated sample to pass credential to getEntraTokenPassword function |
| javascript/package.json | Moved @azure/identity to peer dependency from core dependency |
| javascript/README.md | Updated all documentation examples to show explicit credential usage |
| dotnet/src/Microsoft/Azure/PostgreSQL/Auth/EntraIdExtension.cs | Removed nullable credential parameters and DefaultAzureCredential fallback |
| dotnet/src/Microsoft/Azure/PostgreSQL/Auth/Microsoft.Azure.PostgreSQL.Auth.csproj | Removed Azure.Identity package dependency |
| dotnet/samples/GettingStarted/GettingStarted.csproj | Added Azure.Identity package dependency for sample usage |
| dotnet/samples/GettingStarted/CreateDbConnectionNpgsql.cs | Updated sample to instantiate credential and pass to extension methods |
| dotnet/README.md | Updated documentation examples to show credential instantiation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if not isinstance(credential, (TokenCredential)): | ||
| raise CredentialValueError( | ||
| "credential must be a TokenCredential for sync connections" | ||
| "credential is required and must be a TokenCredential. " | ||
| "Pass it via connect_args={'credential': DefaultAzureCredential()}" | ||
| ) |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation logic will raise a TypeError when credential is None because isinstance(None, TokenCredential) check happens before raising the CredentialValueError.
The check should validate that credential is not None first:
if credential is None or not isinstance(credential, TokenCredential):
raise CredentialValueError(
"credential is required and must be a TokenCredential. "
"Pass it via connect_args={'credential': DefaultAzureCredential()}"
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
| Args: | ||
| engine: The SQLAlchemy Engine to enable Entra authentication for | ||
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces after engine:.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| Args: | ||
| engine: The async SQLAlchemy Engine to enable Entra authentication for | ||
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces after engine:.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| # authentication tokens are properly managed and refreshed so that each connection uses a valid token. | ||
| # | ||
| # For more details, see: https://www.psycopg.org/docs/advanced.html#subclassing-connection | ||
|
|
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this white space serves a purpose here.
|
|
||
| # Create a connection factory with the credential bound using functools.partial | ||
| credential = DefaultAzureCredential() | ||
| connection_factory = partial(EntraConnection, credential=credential) |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thoughts as the previous comment
javascript/package.json
Outdated
| "@azure/identity": { | ||
| "optional": false | ||
| }, |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Moving @azure/identity from dependencies to devDependencies while making it a required peer dependency is correct for a library pattern. However, the peerDependenciesMeta marks it as optional: false, which means it's required. This conflicts with the peer dependency pattern where packages are typically optional in metadata.
Either:
- Keep it as a regular dependency (if you want to bundle it)
- Make it truly optional in peerDependenciesMeta with
optional: trueand handle the missing credential case gracefully - Remove the peerDependenciesMeta entry entirely (required is the default for peerDependencies)
Given the PR's intent to require users to provide credentials, option 3 (removing the meta entry) would be most appropriate.
| "@azure/identity": { | |
| "optional": false | |
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good
| "credential is required and must be a TokenCredential. " | ||
| "Pass it via connect_args={'credential': DefaultAzureCredential()}" | ||
| ) | ||
|
|
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| """ | ||
| credential = kwargs.pop("credential", None) | ||
| if credential and not isinstance(credential, (AsyncTokenCredential)): | ||
| if not isinstance(credential, (AsyncTokenCredential)): |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation logic will raise a TypeError when credential is None because isinstance(None, AsyncTokenCredential) check happens before raising the CredentialValueError.
The check should validate that credential is not None first:
if credential is None or not isinstance(credential, AsyncTokenCredential):
raise CredentialValueError(
"credential is required and must be an AsyncTokenCredential for async connections"
)| if not isinstance(credential, (AsyncTokenCredential)): | |
| if credential is None or not isinstance(credential, AsyncTokenCredential): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
| Event handlers do not support async behavior so the token fetching will still | ||
| be synchronous. | ||
| Entra ID credentials for each database connection. A credential must be | ||
| provided via connect_args when creating the engine. Event handlers do not |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces after the period.
| provided via connect_args when creating the engine. Event handlers do not | |
| provided via connect_args when creating the engine. Event handlers do not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| "credential is required and must be a TokenCredential. " | ||
| "Pass it via connect_args={'credential': DefaultAzureCredential()}" | ||
| ) | ||
|
|
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing whitespace on this line. Remove the trailing spaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
…NET GitHub Actions workflow
Remove dependency on
DefaultAzureCredentialinternally and require the user to pass in a credential from which to generate a token across all languages and database drivers