Repository: snowflakedb/snowflake-connector-net
Pull request #1160: Oauth2 + PAT documentation
Author: login: sfc-gh-knozderko
Created: 2025-04-29T16:06:35Z | Merged: 2025-04-30T10:45:43Z

### Description
OAuth2 documentation

### Checklist
- [ ] Code compiles correctly
- [ ] Code is formatted according to [Coding Conventions](../blob/master/CodingConventions.md)
- [ ] Created tests which fail without the change (if possible)
- [ ] All tests passing (`dotnet test`)
- [x] Extended the README / documentation, if necessary
- [ ] Provide JIRA issue id (if possible) or GitHub issue id in PR name



Diff:
diff --git a/doc/Cache.md b/doc/Cache.md
index fa3467e1d..0d7128f7c 100644
--- a/doc/Cache.md
+++ b/doc/Cache.md
@@ -4,7 +4,7 @@ The Snowflake .NET driver provides the ability to cache tokens using different i
 
 ### Enabling the Cache
 
-The SSO token cache is enabled by setting the parameter **client_store_temporary_credential** to true. The default value is based on OS:
+The SSO token cache and the token cache for OAuth authorization code flow and OAuth client credentials flow is enabled by setting the parameter **client_store_temporary_credential** to true. The default value is based on OS:
 - **Windows**: true
 - **Linux**: false
 - **Mac**: false
diff --git a/doc/Connecting.md b/doc/Connecting.md
index 05c62f7b2..f12b55439 100644
--- a/doc/Connecting.md
+++ b/doc/Connecting.md
@@ -10,7 +10,7 @@ The following table lists all valid connection properties:
 <br />
 
 | Connection Property            | Required | Comment                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
-|--------------------------------| -------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|--------------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | ACCOUNT                           | Yes      | Your full account name might include additional segments that identify the region and cloud platform where your account is hosted                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
 | APPLICATION                       | No       | **_Snowflake partner use only_**: Specifies the name of a partner application to connect through .NET. The name must match the following pattern: ^\[A-Za-z](\[A-Za-z0-9.-]){1,50}$ (one letter followed by 1 to 50 letter, digit, .,- or, \_ characters).                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
 | DB                                | No       |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
@@ -31,7 +31,7 @@ The following table lists all valid connection properties:
 | PRIVATE_KEY_FILE                  | Depends  | The path to the private key file to use for key-pair authentication. Must be used in combination with AUTHENTICATOR=snowflake_jwt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
 | PRIVATE_KEY_PWD                   | No       | The passphrase to use for decrypting the private key, if the key is encrypted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
 | PRIVATE_KEY                       | Depends  | The private key to use for key-pair authentication. Must be used in combination with AUTHENTICATOR=snowflake_jwt. <br /> If the private key value includes any equal signs (=), make sure to replace each equal sign with two signs (==) to ensure that the connection string is parsed correctly.                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| TOKEN                             | Depends  | The OAuth token to use for OAuth authentication. Must be used in combination with AUTHENTICATOR=oauth.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| TOKEN                             | Depends  | The OAuth token to use for OAuth authentication or Programmatic Access Token authentication. Must be used in combination with AUTHENTICATOR=oauth or AUTHENTICATOR=programmatic_access_token.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 | INSECUREMODE                      | No       | Set to true to disable the certificate revocation list check. Default is false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
 | USEPROXY                          | No       | Set to true if you need to use a proxy server. The default value is false. <br/> <br/> This parameter was introduced in v2.0.4.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
 | PROXYHOST                         | Depends  | The hostname of the proxy server. <br/> <br/> If USEPROXY is set to `true`, you must set this parameter. <br/> <br/> This parameter was introduced in v2.0.4.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
@@ -50,10 +50,15 @@ The following table lists all valid connection properties:
 | EXPIRATIONTIMEOUT                 | No       | Timeout for using each connection. Connections which last more than specified timeout are considered to be expired and are being removed from the pool. The default is 1 hour. Usage of units possible and allowed are: e. g. `360000ms` (milliseconds), `3600s` (seconds), `60m` (minutes) where seconds are default for a skipped postfix. Special values: `0` - immediate expiration of the connection just after its creation. Expiration timeout cannot be set to infinity.                                                                                                                                                                                                                                          |
 | POOLINGENABLED                    | No       | Boolean flag indicating if the connection should be a part of a pool. The default value is `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
 | DISABLE_SAML_URL_CHECK            | No       | Specifies whether to check if the saml postback url matches the host url from the connection string. The default value is `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for SSO authentication. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for external bowser, oauth autorization code flow and oauth client credential flow authentications. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | PASSCODE                          | No       | Passcode from your 2FA application to be used in Multi Factor Authentication.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 | PASSCODEINPASSWORD                | No       | Boolean flag indicating if MFA passcode is added to the password.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-
+| OAUTHCLIENTID                     | Depends  | ClientId used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| OAUTHCLIENTSECRET                 | Depends  | ClientSecret used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| OAUTHSCOPE                        | Depends  | The requested scope in OAuth flows. If not provided the default value is built based on `role`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| OAUTHAUTHORIZATIONURL             | Depends  | The url of the authorization endpoint (the one to get authorization code) for OAuth Authorization Code Flow. Required for non-Snowflake Identity Providers. Optional for Snowflake-provided OAuth service. See more: [Snowflake OAuth](https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview)                                                                                                                                                                                                                                                                                                                                                                                                                 |
+| OAUTHTOKENREQUESTURL              | Depends  | The url of the token endpoint (the one to get access token/refresh token) for OAuth Authorization Code Flow or OAuth Client Credential Flow. Required for OAuth Client Credentials Flow. For OAuth Authorization Code Flow, required in case of non-Snowflake Identity Providers, but optional for Snowflake-provided OAuth service. See more: [Snowflake OAuth](https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview)                                                                                                                                                                                                                                                                                       |
+| OAUTHREDIRECTURI                  | Depends  | The url of the local endpoint the driver will listen to in OAuth Authorization Code Flow to get an authorization code from the Identity Provider. Required for non-Snowflake Identity providers. Optional for Snowflake-provided OAuth service. See more: [Snowflake OAuth](https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
 <br />
 
 **Note**: Connections should not be shared across multiple threads.
@@ -222,6 +227,100 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens and refresh tokens are cached if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
+Caching the tokens means that once the token is cached it can be reused for subsequent authentications for which the cache is also enabled.
+Thanks to that you can reduce the number of interactions with the Identity Provider and also reduce the human effort in submitting authentication data in the browser.
+
+
+Example:
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=oauth_authorization_code;oauthScope=testScope;oauthClientId=testClientId;oauthClientSecret=testClientSecret;oauthAuthorizationUrl=https://testauthorize.okta.com;oauthTokenRequestUrl=https://testtoken.okta.com;oauthRedirectUri=http://localhost:8001/snowflake/oauth-redirect";
+
+      conn.Open();
+
+      conn.Close();
+  }
+```
+
+Alternatively you can provide `oauthClientSecret` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-client-secret"))
+  {
+      conn.OAuthClientSecret = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
+Note: On Mac/Linux OS the browser is started by open/xdg-open command. Make sure that the command is properly configured on your PATH environmental variable.
+
+- **OAuth Client Credentials Flow**
+
+It is a similar authentication to OAuth Authorization Code Flow because the driver gets an access token from the Identity Provider instead of getting a token in the connection parameters,
+but does not require any human interaction.
+The driver gets an access token from the Identity Provider and then use it to authenticate in Snowflake.
+
+
+The access tokens and refresh tokens are cached if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
+Caching the tokens means that once the token is cached it can be reused for subsequent authentications for which the cache is also enabled.
+Thanks to that you can reduce the number of interactions with the Identity Provider.
+
+
+Example:
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=oauth_client_credentials;oauthScope=testScope;oauthClientId=testClientId;oauthClientSecret=testClientSecret;oauthTokenRequestUrl=https://testtoken.okta.com;";
+
+      conn.Open();
+
+      conn.Close();
+  }
+```
+
+Alternatively you can provide `oauthClientSecret` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-client-secret"))
+  {
+      conn.OAuthClientSecret = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
+- **Programmatic Access Token**
+
+In Snowflake, you can generate a programmatic access token for your user and role restrictions and use this token to authenticate.
+
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=programmatic_access_token;token=testtoken";
+      conn.Open();
+  }
+```
+
+Alternatively you can provide `token` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-token"))
+  {
+      conn.Token = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
 - **Browser-based SSO**
 
   In the connection string, set `AUTHENTICATOR=externalbrowser`.
@@ -246,6 +345,8 @@ If you are using a different method for authentication, see the examples below:
   The timeout prevents the infinite hang when the user does not provide the login details, e.g. when closing the browser tab.
   To override, you can provide `BROWSER_RESPONSE_TIMEOUT` parameter (in seconds).
 
+Note: On Mac/Linux OS the browser is started by `open`/`xdg-open` command. Make sure that the command is properly configured on your `PATH` environmental variable.
+
 - **Native SSO through Okta**
 
   In the connection string, set `AUTHENTICATOR` to the
diff --git a/doc/ConnectionPooling.md b/doc/ConnectionPooling.md
index f9b8dad86..5ed6b8622 100644
--- a/doc/ConnectionPooling.md
+++ b/doc/ConnectionPooling.md
@@ -75,18 +75,18 @@ using (var connection = new SnowflakeDbConnection(ConnectionString))
 
 ### Pool Interfaces
 
-| Connection Pool Feature                                   | Connection String Parameter  | Default | Method                          | Info                                                                                                                       |
-|-----------------------------------------------------------|------------------------------|---------|---------------------------------|----------------------------------------------------------------------------------------------------------------------------|
-| [Multiple pools](#multiple-pools)                         |                              |         |                                 |                                                                                                                            |
-| [Minimum pool size](#minimum-pool-size)                   | MinPoolSize                  | 2       |                                 |                                                                                                                            |
-| [Maximum pool size](#maximum-pool-size)                   | MaxPoolSize                  | 10      |                                 |                                                                                                                            |
-| [Changed Session Behavior](#changed-session-behavior)     | ChangedSession               | Destroy |                                 | Destroy or OriginalPool                                                                                                    |
-| [Pool Size Exceeded Timeout](#pool-size-exceeded-timeout) | WaitingForIdleSessionTimeout | 30s     |                                 | Values can be provided with postfix [ms], [s], [m]                                                                         |
-| [Expiration Timeout](#expiration-timeout)                 | ExpirationTimeout            | 60m     |                                 |                                                                                                                            |
-| [Pooling Enabled](#connection-timeout)                    | PoolingEnabled               | true    |                                 | Pooling connections authenticated with External Browser or Key-Pair Authentication without password is disabled by default |
-| [Connection Timeout](#pooling-enabled)                    |                              | 300s    |                                 |                                                                                                                            |
-| [Current Pool Size](#current-pool-size)                   |                              |         | GetCurrentPoolSize()            |                                                                                                                            |
-| [Clear Pool](#clear-pool)                                 |                              |         | ClearPool() or ClearAllPools()  |                                                                                                                            |
+| Connection Pool Feature                                   | Connection String Parameter  | Default | Method                          | Info                                                                                                                                                      |
+|-----------------------------------------------------------|------------------------------|---------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
+| [Multiple pools](#multiple-pools)                         |                              |         |                                 |                                                                                                                                                           |
+| [Minimum pool size](#minimum-pool-size)                   | MinPoolSize                  | 2       |                                 |                                                                                                                                                           |
+| [Maximum pool size](#maximum-pool-size)                   | MaxPoolSize                  | 10      |                                 |                                                                                                                                                           |
+| [Changed Session Behavior](#changed-session-behavior)     | ChangedSession               | Destroy |                                 | Destroy or OriginalPool                                                                                                                                   |
+| [Pool Size Exceeded Timeout](#pool-size-exceeded-timeout) | WaitingForIdleSessionTimeout | 30s     |                                 | Values can be provided with postfix [ms], [s], [m]                                                                                                        |
+| [Expiration Timeout](#expiration-timeout)                 | ExpirationTimeout            | 60m     |                                 |                                                                                                                                                           |
+| [Pooling Enabled](#connection-timeout)                    | PoolingEnabled               | true    |                                 | Pooling connections authenticated with External Browser, OAuth Authorization Code Flow or Key-Pair Authentication without password is disabled by default |
+| [Connection Timeout](#pooling-enabled)                    |                              | 300s    |                                 |                                                                                                                                                           |
+| [Current Pool Size](#current-pool-size)                   |                              |         | GetCurrentPoolSize()            |                                                                                                                                                           |
+| [Clear Pool](#clear-pool)                                 |                              |         | ClearPool() or ClearAllPools()  |                                                                                                                                                           |
 
 #### Multiple pools
 
@@ -349,12 +349,15 @@ using (var connection = new SnowflakeDbConnection(connectionString))
 
 Enables or disables connection pooling for the pool identified by a given connection string.
 
-<u>For security reasons pooling is disabled by default for External Browser or Key-Pair Authentication (unless password for key is provided).</u>
+<u>For security reasons pooling is disabled by default for:
+- External Browser
+- OAuth Authorization Code Flow
+- Key-Pair Authentication (unless password for key is provided).</u>
 
 It can be enabled with a connection string parameter if needed.
 However, be warned that using:
 - token key file accessible by others and used to authorize connection
-- shared environment with an external browser authenticated connections
+- shared environment with an external browser or OAuth Authorization Code Flow authenticated connections
 leads to vulnerabilities and is not recommended.
 
 ```cs


Reviews:
user: login: sfc-gh-pbulawa
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-30T05:54:01Z
user: login: sfc-gh-pbulawa
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-30T05:54:21Z
user: login: sfc-gh-pbulawa
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-30T05:56:05Z
user: login: sfc-gh-knozderko
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T07:36:17Z
user: login: sfc-gh-knozderko
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T07:37:50Z
user: login: sfc-gh-pbulawa
body: LGTM
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-30T08:03:07Z
user: login: sfc-gh-mhofman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-30T08:15:19Z
user: login: sfc-gh-mhofman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-30T09:11:11Z
user: login: sfc-gh-mhofman
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-30T09:11:36Z
user: login: sfc-gh-knozderko
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T09:17:50Z
user: login: sfc-gh-knozderko
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T09:30:13Z
user: login: sfc-gh-knozderko
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-30T09:30:19Z
user: login: sfc-gh-mhofman
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-30T09:56:23Z

Review comments:
diff_hunk: @@ -50,10 +50,15 @@ The following table lists all valid connection properties:
 | EXPIRATIONTIMEOUT                 | No       | Timeout for using each connection. Connections which last more than specified timeout are considered to be expired and are being removed from the pool. The default is 1 hour. Usage of units possible and allowed are: e. g. `360000ms` (milliseconds), `3600s` (seconds), `60m` (minutes) where seconds are default for a skipped postfix. Special values: `0` - immediate expiration of the connection just after its creation. Expiration timeout cannot be set to infinity.                                                                                                                                                                                                                                          |
 | POOLINGENABLED                    | No       | Boolean flag indicating if the connection should be a part of a pool. The default value is `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
 | DISABLE_SAML_URL_CHECK            | No       | Specifies whether to check if the saml postback url matches the host url from the connection string. The default value is `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for SSO authentication. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for external bowser, oauth autorization code flow and oauth client credential flow authentications. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | PASSCODE                          | No       | Passcode from your 2FA application to be used in Multi Factor Authentication.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 | PASSCODEINPASSWORD                | No       | Boolean flag indicating if MFA passcode is added to the password.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-
+| OAUTHCLIENTID                     | Depends  | ClientId used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| OAUTHCLIENTSECRET                 | Depends  | ClientSecret used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| OAUTHSCOPE                        | Depends  | The requested scope in OAuth flows. If not provided the default value is built based on `role`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| OAUTHAUTHORIZATIONURL             | Depends  | The url of the authorization endpoint (the one to get authorization code) for OAuth Authorization Code Flow. Required for non-Snowflake Identity Providers. Optional for Snowflake used as an Identity Provider because for Snowflake there is a default value.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
path: doc/Connecting.md
user: login: sfc-gh-pbulawa
body: How about:
`Optional for Snowflake used as an Identity Provider because for Snowflake there is a default value.` 
to
 `Optional for Snowflake-provided OAuth service. See more: [Snowflake OAuth](https://docs.snowflake.com/en/user-guide/oauth-snowflake-overview)`
created_at: 2025-04-30T05:54:01Z
author_association: COLLABORATOR
diff_hunk: @@ -50,10 +50,15 @@ The following table lists all valid connection properties:
 | EXPIRATIONTIMEOUT                 | No       | Timeout for using each connection. Connections which last more than specified timeout are considered to be expired and are being removed from the pool. The default is 1 hour. Usage of units possible and allowed are: e. g. `360000ms` (milliseconds), `3600s` (seconds), `60m` (minutes) where seconds are default for a skipped postfix. Special values: `0` - immediate expiration of the connection just after its creation. Expiration timeout cannot be set to infinity.                                                                                                                                                                                                                                          |
 | POOLINGENABLED                    | No       | Boolean flag indicating if the connection should be a part of a pool. The default value is `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
 | DISABLE_SAML_URL_CHECK            | No       | Specifies whether to check if the saml postback url matches the host url from the connection string. The default value is `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for SSO authentication. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for external bowser, oauth autorization code flow and oauth client credential flow authentications. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | PASSCODE                          | No       | Passcode from your 2FA application to be used in Multi Factor Authentication.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 | PASSCODEINPASSWORD                | No       | Boolean flag indicating if MFA passcode is added to the password.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-
+| OAUTHCLIENTID                     | Depends  | ClientId used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| OAUTHCLIENTSECRET                 | Depends  | ClientSecret used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| OAUTHSCOPE                        | Depends  | The requested scope in OAuth flows. If not provided the default value is built based on `role`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| OAUTHAUTHORIZATIONURL             | Depends  | The url of the authorization endpoint (the one to get authorization code) for OAuth Authorization Code Flow. Required for non-Snowflake Identity Providers. Optional for Snowflake used as an Identity Provider because for Snowflake there is a default value.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
path: doc/Connecting.md
user: login: sfc-gh-pbulawa
body: Same for the two parameters below.
created_at: 2025-04-30T05:54:21Z
author_association: COLLABORATOR
diff_hunk: @@ -222,6 +227,94 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication that the driver doesn't get the token from the connection parameters but instead communicates with
path: doc/Connecting.md
user: login: sfc-gh-pbulawa
body: Missing `is` between `authentication` and  `that`
created_at: 2025-04-30T05:56:04Z
author_association: COLLABORATOR
diff_hunk: @@ -50,10 +50,15 @@ The following table lists all valid connection properties:
 | EXPIRATIONTIMEOUT                 | No       | Timeout for using each connection. Connections which last more than specified timeout are considered to be expired and are being removed from the pool. The default is 1 hour. Usage of units possible and allowed are: e. g. `360000ms` (milliseconds), `3600s` (seconds), `60m` (minutes) where seconds are default for a skipped postfix. Special values: `0` - immediate expiration of the connection just after its creation. Expiration timeout cannot be set to infinity.                                                                                                                                                                                                                                          |
 | POOLINGENABLED                    | No       | Boolean flag indicating if the connection should be a part of a pool. The default value is `true`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
 | DISABLE_SAML_URL_CHECK            | No       | Specifies whether to check if the saml postback url matches the host url from the connection string. The default value is `false`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
-| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for SSO authentication. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+| CLIENT_STORE_TEMPORARY_CREDENTIAL | No       | Specifies whether to cache tokens and use them for external bowser, oauth autorization code flow and oauth client credential flow authentications. The default value is `true` for Windows and `false` on non-Windows platforms.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | PASSCODE                          | No       | Passcode from your 2FA application to be used in Multi Factor Authentication.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
 | PASSCODEINPASSWORD                | No       | Boolean flag indicating if MFA passcode is added to the password.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
-
+| OAUTHCLIENTID                     | Depends  | ClientId used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
+| OAUTHCLIENTSECRET                 | Depends  | ClientSecret used for OAuth flows. It is required for OAuth Authorization Code Flow and OAuth Client Credentials Flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
+| OAUTHSCOPE                        | Depends  | The requested scope in OAuth flows. If not provided the default value is built based on `role`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| OAUTHAUTHORIZATIONURL             | Depends  | The url of the authorization endpoint (the one to get authorization code) for OAuth Authorization Code Flow. Required for non-Snowflake Identity Providers. Optional for Snowflake used as an Identity Provider because for Snowflake there is a default value.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
path: doc/Connecting.md
user: login: sfc-gh-knozderko
body: changed
created_at: 2025-04-30T07:36:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -222,6 +227,94 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication that the driver doesn't get the token from the connection parameters but instead communicates with
path: doc/Connecting.md
user: login: sfc-gh-knozderko
body: done
created_at: 2025-04-30T07:37:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -222,6 +227,94 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens (and refresh tokens) are cached and reused for other authentications if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
path: doc/Connecting.md
user: login: sfc-gh-mhofman
body: the word 'other' authentications might be misleading. I would suggest to replace with 'subsequent` and add a sentence explaining that `token caching allows to limit number of human authentications using external browser` or sth like 'when the driver stores token in the cache it can reuse it for subsequent automated authentications without necessity for the user to interact with the browser on each connect request.
WDYT? 
created_at: 2025-04-30T08:15:18Z
author_association: COLLABORATOR
diff_hunk: @@ -222,6 +227,96 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens (and refresh tokens) are cached and reused for other authentications if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
+
+
+Example:
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=oauth_authorization_code;oauthScope=testScope;oauthClientId=testClientId;oauthClientSecret=testClientSecret;oauthAuthorizationUrl=https://testauthorize.okta.com;oauthTokenRequestUrl=https://testtoken.okta.com;oauthRedirectUri=http://localhost:8001/snowflake/oauth-redirect";
+
+      conn.Open();
+
+      conn.Close();
+  }
+```
+
+Alternatively you can provide `oauthClientSecret` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-client-secret"))
+  {
+      conn.OAuthClientSecret = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
+Note: On Mac/Linux OS the browser is started by open/xdg-open command. Make sure that the command is properly configured on your PATH environmental variable.
+
+- **OAuth Client Credentials Flow**
+
+It is a similar authentication to OAuth Authorization Code Flow because the driver gets an access token from the Identity Provider instead of getting a token in the connection parameters,
+but requires no human interaction.
path: doc/Connecting.md
user: login: sfc-gh-mhofman
body: `but does not require human interaction` wouldn't sound more clearly?
created_at: 2025-04-30T09:11:10Z
author_association: COLLABORATOR
diff_hunk: @@ -222,6 +227,96 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens (and refresh tokens) are cached and reused for other authentications if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
+
+
+Example:
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=oauth_authorization_code;oauthScope=testScope;oauthClientId=testClientId;oauthClientSecret=testClientSecret;oauthAuthorizationUrl=https://testauthorize.okta.com;oauthTokenRequestUrl=https://testtoken.okta.com;oauthRedirectUri=http://localhost:8001/snowflake/oauth-redirect";
+
+      conn.Open();
+
+      conn.Close();
+  }
+```
+
+Alternatively you can provide `oauthClientSecret` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-client-secret"))
+  {
+      conn.OAuthClientSecret = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
+Note: On Mac/Linux OS the browser is started by open/xdg-open command. Make sure that the command is properly configured on your PATH environmental variable.
+
+- **OAuth Client Credentials Flow**
+
+It is a similar authentication to OAuth Authorization Code Flow because the driver gets an access token from the Identity Provider instead of getting a token in the connection parameters,
+but requires no human interaction.
+It gets an access token from the Identity Provider and then use it to authenticate in Snowflake.
path: doc/Connecting.md
user: login: sfc-gh-mhofman
body: Change `it` to 'Driver' 
created_at: 2025-04-30T09:11:36Z
author_association: COLLABORATOR
diff_hunk: @@ -222,6 +227,94 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens (and refresh tokens) are cached and reused for other authentications if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
path: doc/Connecting.md
user: login: sfc-gh-knozderko
body: changed
created_at: 2025-04-30T09:17:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -222,6 +227,96 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens (and refresh tokens) are cached and reused for other authentications if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
+
+
+Example:
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=oauth_authorization_code;oauthScope=testScope;oauthClientId=testClientId;oauthClientSecret=testClientSecret;oauthAuthorizationUrl=https://testauthorize.okta.com;oauthTokenRequestUrl=https://testtoken.okta.com;oauthRedirectUri=http://localhost:8001/snowflake/oauth-redirect";
+
+      conn.Open();
+
+      conn.Close();
+  }
+```
+
+Alternatively you can provide `oauthClientSecret` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-client-secret"))
+  {
+      conn.OAuthClientSecret = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
+Note: On Mac/Linux OS the browser is started by open/xdg-open command. Make sure that the command is properly configured on your PATH environmental variable.
+
+- **OAuth Client Credentials Flow**
+
+It is a similar authentication to OAuth Authorization Code Flow because the driver gets an access token from the Identity Provider instead of getting a token in the connection parameters,
+but requires no human interaction.
path: doc/Connecting.md
user: login: sfc-gh-knozderko
body: done
created_at: 2025-04-30T09:30:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -222,6 +227,96 @@ If you are using a different method for authentication, see the examples below:
 
     - `{oauthTokenValue}` is the oauth token to use for authentication.
 
+- **OAuth Authorization Code Flow**
+
+The difference from simple OAuth authentication is that the driver doesn't get the token from the connection parameters but instead communicates with
+the Identity Provider to get the token by itself. The Identity Provider can be Snowflake or any other provider e.g. Okta, etc.
+For this kind of authentication a browser is started for the Identity Provider authorization endpoint.
+After a human submits a request in a browser the driver gets authorization code from the Identity Provider and then use it to get an access token
+which then is used to authorize in Snowflake.
+
+
+The access tokens (and refresh tokens) are cached and reused for other authentications if `CLIENT_STORE_TEMPORARY_CREDENTIAL` property is set to true (the default value for that is `true` on Windows and `false` on Mac/Linux).
+
+
+Example:
+```csharp
+  using (IDbConnection conn = new SnowflakeDbConnection())
+  {
+      conn.ConnectionString = "account=testaccount;user=testuser;db=testdb;schema=testschema;authenticator=oauth_authorization_code;oauthScope=testScope;oauthClientId=testClientId;oauthClientSecret=testClientSecret;oauthAuthorizationUrl=https://testauthorize.okta.com;oauthTokenRequestUrl=https://testtoken.okta.com;oauthRedirectUri=http://localhost:8001/snowflake/oauth-redirect";
+
+      conn.Open();
+
+      conn.Close();
+  }
+```
+
+Alternatively you can provide `oauthClientSecret` property as a secure string of the connection instead of specifying it in the connection string:
+
+```csharp
+  using (SnowflakeDbConnection conn = new SnowflakeDbConnection("connection-string-without-client-secret"))
+  {
+      conn.OAuthClientSecret = ...; // configure client secret here
+      conn.Open();
+  }
+```
+
+Note: On Mac/Linux OS the browser is started by open/xdg-open command. Make sure that the command is properly configured on your PATH environmental variable.
+
+- **OAuth Client Credentials Flow**
+
+It is a similar authentication to OAuth Authorization Code Flow because the driver gets an access token from the Identity Provider instead of getting a token in the connection parameters,
+but requires no human interaction.
+It gets an access token from the Identity Provider and then use it to authenticate in Snowflake.
path: doc/Connecting.md
user: login: sfc-gh-knozderko
body: done
created_at: 2025-04-30T09:30:19Z
author_association: CONTRIBUTOR

PR comments:
user: login: sfc-gh-snowflakedb-snyk-sa
created_at: 2025-04-29T16:06:48Z
body: ![](https://res.cloudinary.com/snyk/image/upload/r-d/scm-platform/snyk-pull-requests/pr-banner-default.svg)

### :tada: **Snyk checks have passed. No issues have been found so far.**

:white_check_mark: **security/snyk** check is complete. No issues have been found. [(View Details)](https://app.snyk.io/org/snowflakedb-sca-scanning-public-repo/pr-checks/8313f934-9492-4388-992a-fe8b0a5548b6?refs=d0863e3b235319bdf8def79ca561a0261ef2a126&source=prChecksComment)

:white_check_mark: **license/snyk** check is complete. No issues have been found. [(View Details)](https://app.snyk.io/org/snowflakedb-sca-scanning-public-repo/pr-checks/8313f934-9492-4388-992a-fe8b0a5548b6/license?refs=d0863e3b235319bdf8def79ca561a0261ef2a126&source=prChecksComment)



author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-04-29T16:47:52Z
body: ## [Codecov](https://app.codecov.io/gh/snowflakedb/snowflake-connector-net/pull/1160?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=snowflakedb) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 87.61%. Comparing base [(`2f0a174`)](https://app.codecov.io/gh/snowflakedb/snowflake-connector-net/commit/2f0a1740cc15a8d0eb469be54ccf20da03829ee4?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=snowflakedb) to head [(`d0863e3`)](https://app.codecov.io/gh/snowflakedb/snowflake-connector-net/commit/d0863e3b235319bdf8def79ca561a0261ef2a126?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=snowflakedb).
> Report is 1 commits behind head on oauth_flows.

<details><summary>Additional details and impacted files</summary>


```diff
@@               Coverage Diff               @@
##           oauth_flows    #1160      +/-   ##
===============================================
- Coverage        87.75%   87.61%   -0.14%     
===============================================
  Files              156      156              
  Lines            13871    13871              
  Branches          1418     1418              
===============================================
- Hits             12172    12153      -19     
- Misses            1343     1358      +15     
- Partials           356      360       +4     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/snowflakedb/snowflake-connector-net/pull/1160?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=snowflakedb).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=snowflakedb).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE