Centralized Configuration Providers for Deployments

Managed ODP.NET and ODP.NET Core can store and retrieve connection string configuration values securely from a centralized provider. Centralizing ODP.NET connection configuration information makes managing user credentials easier in an app deployment. Ensuring connection strings are stored securely is necessary since they can contain sensitive information, such as passwords.

This configuration provider is available for ODP.NET cloud deployments and on-premises deployments and work with any Oracle database version ODP.NET supports. It can be stored in the following locations:

Since centralized configuration providers are often used for cloud deployments, local file system access is disabled by default when the connection string is populated with an URL. To enable local access, set OracleConnection.RemoteConfigurationFiltering to false.

Connection String URLs

The connection string URL is different from the traditional ODP.NET connection string format. To access the centralized configuration provider, ODP.NET apps specify a URL in the OracleConnection ConnectionString property in place of the traditional ODP.NET connection string. This URL contains the centralized configuration provider type, for example, Azure, and its configuration storage name, as well as authentication and connection configuration parameter values, if applicable. The traditional connection string values, such as User Id and Min Pool Size are stored within the centralized configuration provider itself.

Nonetheless, it remains simple moving from a traditional ODP.NET connection string to the centralized configuration provider model. The traditional ODP.NET connection string attributes and values are moved over to Azure App Configuration, OCI Object Storage, or local directory. Then, the ConnectionString property is set to the connection string URL instead of a traditional ODP.NET connection string.

Sensitive information, such as passwords, can be stored in secure stores, such Azure Key Vault and OCI Vault, or be encoded. The centralized configuration providers do not support storing plain text passwords in the connection string.

If using pooling, ODP.NET caches the connection string URL. Changing the configuration values in the centralized storage after the pool populates will not change the connection pool properties until the application is restarted.

If pooling is disabled, the connection string URL is not cached. Changes to the connection configuration is then possible for subsequent connection requests without an application restart.

Connection strings begin with the format config-<provider type> where the provider type is awss3, azure, gcpstorage, ociobject, or file, depending on the deployment location.

AWS Centralized Configuration Provider

The AWS configuration provider can use AWS S3 and AWS Secrets Manager to store Oracle database connection information in a JSON configuration file. The AWS Centralized Configuration Provider connection string URL syntax is:

config-awss3://{AWS S3 URI or URL}[?key=name&option1=value1&option2=value
2...]
s3://bucket-name/odpnet-folder/config.json

An example of AWS S3 Object URL is:

https://bucket.s3.us-west-1.amazonaws.com/odpnet-folder/config.json

An example of Object ARN is:

arn:aws:s3:::bucket/odpnet-folder/config.json

AWS Authentication Options Note: These options and values are case insensitive. The required parameters can be set alternatively as environment variables.

Authentication Method Required Parameters for This Option Value Example Value
SESSION_AWS_CREDENTIALS

AWS_ACCESS_KEY_ID

AWS_SECRET_ACCESS_KEY

AWS_SESSION_TOKEN

AAAAXUTHXBS3K56G7AAA

GKrTf8ySGrY5z603Mjhj3OLgDe3unu+aaaaaaaaa

IQoJb3JpZ2luX2VjEJv//////////...

BASIC_AWS_CREDENTIALS

AWS_ACCESS_KEY_ID

AWS_SECRET_ACCESS_KEY

AAAAXUTHXBS3K56G7AAA

GKrTf8ySGrY5z603Mjhj3OLgDe3unu+aaaaaaaaa

AWS_PROFILE_NAME AWS_PROFILE default
AWS_DEFAULT (Default)    

AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN might contain RFC 3986 reserved characters. You should use WebUtility.UrlEncode() to encode the parameter values.

When none of the authentication options are provided, ODP.NET will use AWS SDK for .NET to locate the AWS authentication parameters with its default credential search order.

See Also: Credential and profile resolution for more information about the default credential search order of AWS SDK for .NET.

The following optional parameters can be set in the AWS provider.

Table 10 AWS S3 Configuration Options

Name Description Example
AWS_REGION Region endpoint name us-west-1
QUEUEURL AWS Simple Queue Service URL for change notification `https://sqs.us-west-
1.amazonaws.com/1234567890/odpnet-sqs`    
VERSIONID Version identifier MK8fY7Ym00DU5YcKpaZDb2....

AWS Centralized Configuration Provider Code Sample:

OracleConnection con = new OracleConnection("config-awss3://odpnet-config/directory/jsconfig.json?key=connection1&aws_region=us-west-1");
con.Open();

AWS Centralized Configuration Provider JSON File Sample:

{
  "connection1": {
    "user": "HR",
    "password": {
      "type": "awssecretsmanager",
      "value": "arn:aws:secretsmanager:us-west-1:123456789012:secret:odpnet/myaws/mypassword-GPNigp"
    },
    "connect_descriptor": "(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=<HOSTNAME>))
(connect_data=(service_name=<SERVICE NAME>))(security=(ssl_server_dn_match=yes)))",
    "ODP": {
      "MaxStatementCacheSize": "150",
      "Pipelining": "true",
      "Wallet_Location": "config-awssecretsmanager://arn:aws:secretsmanager:us-west-1:123456789012:secret:odpnet/myaws/mywallet-vrOWx1"
    }
  }
}

Azure Centralized Configuration Provider

The Azure configuration provider can use Azure App Configuration and Azure Key Vault to store Oracle database connection information. The Azure Centralized Configuration Provider connection string URL syntax is:

config-azure://{Config Name}[?Key=Prefix&Label=Value&Option1=Value1&Option2=Value2...]

Azure Authentication Options

ODP.NET uses the Azure SDK for .NET credential classes to provide authorization and authentication to Azure App Configuration and Key Vault services. This dependency can be resolved by having your project incorporate the Oracle.ManagedDataAccess.Azure package available on NuGet Gallery when Azure authentication is required.

Developers set the Azure authentication option to “Authentication” in the ODP.NET URL connection string. The possible values for this option are listed in the following table. Note: These options and values are case insensitive. The required parameters can be set alternatively as environment variables

Table 11 Azure Authentication Methods and their Values

Authentication Method Authentication Option Values Required Parameters for This Option Value Optional Parameters for This Option Value
Default Azure Credential AZURE_DEFAULT or Empty String  

AZURE_TENANT_ID

AZURE_MANAGED_IDENTITY_CLIENT_ID

Service Principal with client secret* AZURE_SERVICE_PRINCIPAL

AZURE_CLIENT_ID

AZURE_CLIENT_SECRET

AZURE_TENANT_ID

 
Service Principal with client certificate* AZURE_SERVICE_PRINCIPAL

AZURE_CLIENT_ID

AZURE_CLIENT_CERTIFICATE_PATH

AZURE_TENANT_ID

AZURE_CLIENT_CERTIFICATE_PASSWORD
Managed Identity AZURE_MANAGED_IDENTITY AZURE_CLIENT_ID - required only if user assigned  
Interactive Browser OAuth token flow AZURE_INTERACTIVE

AZURE_CLIENT_ID

AZURE_REDIRECT_URL

 

Table 12 Azure Auth Parameters and Example Values

Parameter Example Values
AZURE_TENANT_ID 5b743bc7-a1b2-3c4d-56ef-a32eddac0286
AZURE_MANAGED_IDENTITY_CLIENT_ID dea80a83-a1b2-3c4d-56ef-d6478ec51157
AZURE_CLIENT_ID 122a6dc8-a1b2-3c4d-56ef-d894e5981c66
AZURE_CLIENT_SECRET 8EqLhX...
AZURE_CLIENT_CERTIFICATE_PATH path\to\client\cert\file
AZURE_CLIENT_CERTIFICATE_PASSWORD p@ssW0rd
AZURE_REDIRECT_URL https://example.com/auth

ODP.NET supports Azure service principal with a client secret stored in a user created wallet. ODP.NET first attempts to use the ODP.NET Azure token client secret or connection string URL Azure client secret values. If neither contain a value, ODP.NET will then use a client secret stored in the wallet. The wallet path is specified in the azure_credentials property. This property can be set in TNS descriptor or sqlnet.ora.

When this property is specified, ODP.NET will attempt to authenticate with Azure by utilizing the secret corresponding to the configured wallet entry of the format oracle.security.azure.credential.{CLIENT_ID}, where {CLIENT_ID} is the Microsoft Entra ID registered Client identifier.

The azure_credentials property is ignored if client secret property is specified using the AzureTokenAuthentication class.

The ODP.NET connection string URL provides more connection configuration options, including:

The following code sample provides an ODP.NET connection string URL that specifies an Azure App configuration store name called MyConfig. The prefix key for the connection in MyConfig is MyConnection and the Azure App Configuration label name is production. The code sample uses Azure Managed Identity authentication to connect and supplies that id value. The code sample then sets the connection string URL using OracleConnection constructor. ODP.NET obtains the connection string from the Azure App Configuration store implicitly when opening the connection.

      {
       // This ODP.NET URL uses Azure Managed Identity authentication
       string connectionString = "config-azure://MyConfig?key=
         MyConnection/&Label=production&Authentication=Azure_Managed_Identity&
         Azure_Managed_Identity_Client_Id=111abccd8-18cc-4fa0-bf7b-d894e5981c67";
       OracleConnection conn = new OracleConnection();
       conn.ConnectionString = connectionString;
       conn.Open();
	}

See Also: DefaultAzureCredential Class for more information about Azure identity and authentication.

GCP Centralized Configuration Provider

The GCP configuration provider can use GCP Cloud Storage and Secret Manager to store Oracle database connection information in a JSON configuration file. The GCP Centralized Configuration Provider connection string URL syntax is:

config-gcpstorage://project={project-name};bucket={bucket-name};object={object-name}[?key={connectionKey}&
option1=value
1...]

The GCP provider only uses GCP’s Application Default Credentials to manage app authentication. No authentication parameters need to be provided. If an authentication key is provided in URL options, it will be ignored.

See Also: How Application Default Credentials works for more information about GCP’sApplication Default Credentials.

The following optional parameters can be set in the GCP provider.

Table 13 GCP Configuration Parameters

Name Description Format Example
SUBSCRIPTIONNAME GCP Pub/Sub subscription name for change notification projects/{project-name}/subscriptions/{subscription-name} projects/odpnet-1/subscriptions/odpnet-config-sub

GCP Centralized Configuration Provider Code Sample

string projectId = "dotnet-1";
string bucketName = "odpnet-sample";
string objectName = "hr.json";
OracleConnection conn = new OracleConnection($"config-gcpstorage://project={projectId};
bucket={bucketName};object={objectName}?key=Connection1&subscriptionname=projects/dotnet-1/subscriptions/dotnet-sub");
conn.Open();

OCI Centralized Configuration Provider

The Oracle Cloud Infrastructure configuration provider uses OCI Object Storage and OCI Vault to store database connection information in a JSON configuration file. The connection string URL syntax is:

config-ociobject://{Object-Url}[?key=name&option1=value1&option2=value2...]

OCI Authentication Options

ODP.NET OCI authentication has a dependency on OCI SDK for authorization and authentication to the OCI Object Storage and Vault services. This dependency can be resolved by having your project incorporate the Oracle.ManagedDataAccess.Oci package available on NuGet Gallery when OCI authentication is required.

The authentication parameters are provided via the connection string URL.

Developers set the OCI authentication option to Authentication in the ODP.NET URL connection string. The possible values for this option are listed in the following table. Note: These options and values are case insensitive. The required parameters can be set alternatively as environment variables

Table 14 OCI Authentication Methods and their Values

Authentication Method Authentication Option Values Optional Configuration Optional Parameters
API Key-Based Authentication OCI_DEFAULT or Empty String

(~/.oci/config),

(~/.oraclebmc/config), or

environment variable OCI_CONFIG_FILE

OCI_PROFILE

OCI_TENANCY

OCI_USER

OCI_FINGERPRINT

OCI_KEY_FILE

OCI_PASS_PHRASE

Instance Principal Authentication OCI_INSTANCE_PRINCIPAL    
Resource Principal Authentication OCI_RESOURCE_PRINCIPAL    

Table 15 OCI Authentication Parameter Example Values

Parameter Example Values
OCI_CONFIG_FILE ~/.oci/config
OCI_PROFILE profile_name
OCI_TENANCY `ocid
1.tenancy.oc1..aaaaaaaansdf897bgyserd…`  
OCI_USER ocid1.user.oc1..aaaaaaaazkxluul3yw7apxolbk...
OCI_FINGERPRINT a1:2b:3c:4d:56:ef:a4:8d:41:a3:d6:35:14:d2:fb:15
OCI_KEY_FILE path/to/key/file.pem
OCI_PASS_PHRASE keyf1LeP@ssphrAs3

The following code sample provides an ODP.NET connection string URL that specifies an OCI Object Store object URL. The connection key name identity is MyConnection. The code sample uses OCI’s API key-based authentication, OCI_DEFAULT, and the optional parameter, OCI_PROFILE, to specify the connection profile configuration. The code sample then sets the connection string URL using OracleConnection ConnectionString property. ODP.NET obtains the connection string from the JSON configuration file stored in OCI Object Storage Service when opening the connection.

{
  //This URL will use default OCI authentication, which requires no authentication parameters
  string connectionString = "config-ociobject://https://objectstorage.us-ashburn-1.
    oraclecloud.com/n/namespace/b/bucket1/o/odp.json?key=MyConnection&authentication
    =OCI_DEFAULT&OCI_PROFILE=MyProfile";
  OracleConnection conn = new OracleConnection(connectionString);
  conn.Open();
}

See Also: OCI SDK Authentication Methods for more information.

Local File Centralized Configuration Provider

The file config provider stores Oracle database connection information in a JSON configuration file on the local file system. The ODP.NET file connection string URL syntax is:

config-file://{File Path}[?Key=name&tns_admin=filepath]

The following code sample provides an ODP.NET connection string URL that specifies a local file, odpconfig.json, and directory location. The connection key name identity is MyConnection. This code sample then sets the connection string URL using OracleConnection constructor. ODP.NET obtains the connection string from the local JSON config file when opening the connection.

{
  //This URL will retrieve the c:\configs\odpconfig.json from the file system
  //The connection key is "MyConnection"
  string connectionString = "config-file://c:/configs/odpconfig.json?key=MyConnection";

  OracleConnection conn = new OracleConnection(connectionString);
  conn.Open();
}

The file config provider relies on Oracle.ManagedDataAccess.ConfigFile package available on NuGet Gallery.

JSON Configuration File Search Order

ODP.NET can use the absolute directory and file name value, that is, c:/configs/myconfig.json, set in the local file centralized configuration provider connection string URL to locate its JSON configuration file. It can also use a relative directory with a file name. In this case, it will append the relative directory and file to the settings in the following order to locate the JSON file.

  1. Current working directory

  2. Directory set in OracleConnection.TnsAdmin property

  3. Directory set for the Tns_Admin connection string attribute

  4. Directory set in the tns_admin attribute of the configuration provider URL

  5. Directory set in OracleConfiguration.TnsAdmin property

  6. TNS_ADMIN directory setting in .NET configuration file – managed ODP.NET only

  7. TNS_ADMIN directory setting of the Windows environment variable or container environment variable

  8. Directory set in the Windows Registry key, HKLM\SOFTWARE\Oracle\ODP.NET.Managed\<version>\TNS_ADMIN – managed ODP.NET only Note: 32-bit apps use the Registry key HKLM\SOFTWARE\Wow6432Node\Oracle\ODP.NET.Managed\<version>\TNS_ADMIN

  1. %ORACLE_HOME%\network\admin directory

Vault Providers

Database passwords, proxy passwords, wallets, JSON configuration are sensitive database information that can be stored in AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, or OCI Vault services as secret. These vault providers are included with the Oracle.ManagedDataAccess.Aws, Oracle.ManagedDataAccess.Azure, Oracle.ManagedDataAccess.Gcp, and Oracle.ManagedDataAccess.Oci NuGet packages, respectively.

ODP.NET provides a secured way to access this sensitive information from vaults using a predefined URL, secret-URL. The secret-URL must be prefixed with config-awssecretsmanager, config-azurevault, config-gcpsecretmanager, or config-ocivault for ODP.NET to access the user provided information. The user-provided URL must conform to the ODP.NET defined syntax below.

The ODP.NET vault providers support single sign-on (.sso) and PKCS #12 (.p12) wallets in cloud vaults.

Vault Connection String URLs

Similarly for centralized configuration providers, vault URLs can be passed as a connection string to the OracleConnection class through a constructor connection string property or an OracleConnection ConnectionString property.

Here is an example for Azure Vault:

new OracleConnection("config-azurevault://https://vault1.vault.azure.net/secrets/ODPConnStr/
abc69352e1d040e59wd7b83ffcdaf123");

The Vault can contain a standard connection string or a JSON config string.

Standard connection string example:

user id = scott; password = tiger; data source = inst1; pooling = false

JSON config example:

{
    "Connection1": {
        "ODP": {
            "User Id": "scott",
            "Password":"tiger",
            "Data Source": "inst1",
            "Pooling": "false"
        }
    }
}

Note: The connection/JSON config strings should be uploaded as clear text.

Vault Passwords

Instead of storing the entire connection string, developers have the option to store only the password or proxy password in a cloud vault. To do this, the application provides the vault URL value in the password or proxy password connection string attribute value.

For example, the ODP.NET connection string for Azure Vault could be:

"User ID = HR; Data Source = mydb;
password=config-azurevault://https://vault
1.vault.azure.net/secrets/ODPConnStr/
abc69352e1d040e59wd7b83ffcdaf123"

Vault Wallets and Tokens

An application can store wallets and tokens in cloud vault services securely by providing the vault URL in the ODP.NET wallet and token location properties. The application must store the wallet or token file data in the cloud vault as a base64 string. Note: For OCI vault, although wallet and token have to be converted to base64 string, they must be uploaded to OCI vault as “plain-text” type secret.

ODP.NET connection strings can use the Wallet_Location and Token_Location properties, respectively, to store wallets and tokens. For example, the ODP.NET connection string for accessing a wallet stored in Azure Vault could be:

"User ID = HR; password = <PASSWORD>; Data source = mydb;
Wallet_Location=config-azurevault://https://vault
1.vault.azure.net/secrets/HRWallet/
abc69352e1d040e59wd7b83ffcdaf123"

The OracleConnection WalletLocation and TokenLocation properties can be set to a vault URL or file path location. These OracleConnection properties have precedence over the wallet and token location attributes in the connection string. Here’s sample code to use these properties with Azure Vault:

OracleConnection conn = new OracleConnection();
conn.WalletLocation = "config-azurevault://https://vault1.vault.azure.net/secrets/HRWallet/abc693...";
conn.TokenLocation = "config-azurevault://https://vault1.vault.azure.net/secrets/HRToken/abc3ffc...";

Note: Secure External Password Store is not supported for cloud wallet locations.

ODP.NET supports Microsoft identity platform tokens v 1.0 for Microsoft Entra ID-only applications and v2.0 for applications that support consumer accounts. ODP.NET 23.5 and higher check the roles (roles) and user principal name (UPN) claims in v2.0 tokens to verify at least one is present. If both claims are missing, then the provider will report an error.

AWS Secrets Manager

All ODP.NET secrets can be stored in AWS Secrets Manager. Use the following URL syntax to access those secrets in AWS:

config-awssecretsmanager://{secret-name or secret-ARN}[?<options>]

Applications need to provide the following information in the URL:

The following optional parameters can also be set.

Table 16 AWS Secrets Manager Configuration Options

Parameter Name Description Example
AWS_REGION Region Endpoint Name. Optional when using ARNs. Required when using secret names. us-west-1
versionId Version ID MK8fY7Ym00DU5YcKpaZDb2....
versionStage

Version Stage.

If versionId and versionStage are not specified, then the current secret version is used.

AWSCURRENT, AWSPREVIOUS, or AWSPENDING

Table 17 AWS Secret Name Formats

Resource Type Format Example
Secret name Secret-name odpnet/myaws/hr
Secret ARN arn:aws:secretsmanager:<region>:<user id>:secret:<secret name>-<6 random characters> arn:aws:secretsmanager:us-west-1:525277269174:secret:odpnet/myaws/hr-ABcdEF

AWS Secrets Manager Code Samples:

//Retrieve connection parameters from AWS Secrets Manager
OracleConnection con = new ("config-awssecretsmanager://arn:aws:secretsmanager:us-west-1:123456789012:secret:odpnet/myaws/config.json-123456;");
con.Open();
// Retrieve password only from AWS Secrets Manager
OracleConnection conn = new ("user id = HR; password = config-awssecretsmanager://arn:aws:secretsmanager:us-west-1:123456789012:secret:
odpnet/myaws/mypassword-123456; data source = myadb");
conn.WalletLocation = "config-awssecretsmanager://arn:aws:secretsmanager:us-west-1:123456789012:secret:odpnet/myaws/mywallet-654321";
conn.Open();

The AWS Secrets Manager .NET SDK provides caching capability. Retrieving secrets from AWS incurs a performance and financial cost. AWS recommends using the cache to improve speed and lower costs.

Azure Key Vault

All ODP.NET secrets can be stored as Azure Vault secrets. Use the following URL syntax to access Azure Key Vault secrets:

config-azurevault://{Secret Identifier}[?key=name&Option1=Value1&Option2=Value2...]

Applications need to provide the following information in the URL:

GCP Secret Manager

All ODP.NET secrets can be stored in GCP Secret Manager. Use the following URL syntax to access those secrets in GCP:

config-gcpsecretmanager://{GCP secret resource name}?key={connection key}&{option1}={value1}&...

GCP Secret Manager uses GCP Application Default Credentials to manage app authentication.

GCP Secret Manager Code Sample

OracleConnection conn = new OracleConnection($"config-gcpsecretmanager://projects/123456789012/secrets/MySecret/versions/latest?key=Connection1");
conn.Open();

OCI Vault

All ODP.NET secrets can be stored as OCI Vault secrets. Use the following URL syntax to access OCI Vault secrets:

config-ocivault://{Secret OCID}[?VersionNumber=Value1&Stage=Value2&key=name&Option3=Value3&Option4=Value4...]

Applications need to provide the following information in the URL:

Provider Configuration

Provider Configuration Keys

All the centralized configuration providers use a JSON format to specify connection information, except for the Azure provider. The format is the same for all the providers that use JSON configuration.

ODP.NET uses the values in the provider configuration keys to construct a connection string to an Oracle database. Configuration keys generally map to an existing ODP.NET connection string and Oracle connection properties. Some keys are generic to all Oracle data access drivers. Those properties are:

In Azure App Configuration, the ODP.NET specific configuration keys are prefixed with ODP/ to indicate intent to be used for ODP.NET only. For example, MyConnection/ODP/Pooling key specifies the ODP.NET’s Pooling connection string attribute.

For all other providers, the ODP.NET specific configuration keys are specially identified in the JSON configuration. These keys use the "ODP" key. For example, "ODP": {"Max Pool Size": "500", "Pooling": true } specifies the Max Pool Size and Pooling connection string attributes for MyConnection property in the following example.

{
                "MyConnection": {
                                "ODP": {"Max Pool Size": "500", "Pooling" : true },
                "password":
                {
                                "type":"ocivault",
                               "value":"ocid1.vaultsecret.oc1.phx.example",
                                "authentication":
                               {
                                               "method" : "OCI_DEFAULT",
                                                "OCI_PROFILE" : "<PROFILE>"
                                }
                }
                "user": "HR",
                "connect_descriptor": "(description= .......)"
}

Generally, ODP.NET configuration keys are case insensitive. However, the ODP/ section in Azure App configuration and the ODP section in OCI and local configuration, including the keys and their values, are case-sensitive.

Connection Attributes

The ConnectionString key is an ODP.NET specific key in the configuration provider. It allows defining complete or partial ODP.NET connection strings. ODP.NET apps can continue to use the OracleConnection ConnectionString property and are not required to use the configuration provider’s ConnectionString key.

All the connection string attributes defined in OracleConnection ConnectionString are supported as is used in the traditional connection string except the following attribute:

ODP.NET also supports the following OracleConnection properties in the provider configuration:

If a non-supported attribute is specified in the provider configuration under the ODP JSON property or ODP/ Azure App Configuration section, then ODP.NET throws an exception.

The following example contains three connections: sales_app, hr_app, and sh_app using various configuration key types.

{
  "sales_app":
  {
    "connect_descriptor": "(description=(address=(protocol=tcps)(port=1521)(host=<HOSTNAME>
    (connect_data=(service_name=<SERVICE NAME>))(security=(ssl_server_dn_match=yes)))",
    "user": "sales",
    "password": {
      "type": "ocivault",
      "value": "<VAULT LOCATION>",
      "authentication": {
        "method": "OCI_INSTANCE_PRINCIPAL"
      }
    },
    "ODP": {
      "Connection Timeout": 30,
      "pooling": "true",
      "max pool size": 100
    }
  },
  "hr_app":
  {
    "password": {
      "type": "azurevault",
      "value": "<VAULT LOCATION>",
      "authentication": {
        "method": "AZURE_DEFAULT"
      }
    },
    "ODP": {
      "user": "hr",
      "data source": "oracle",
      "max pool size": 100
    }
  },
  "sh_app":
  {
    "ODP": {
      "ConnectionString": "user id = sh; data source = oracle; max pool size = 100",
      "BindByName": "false"
    }
    "password": {
      "type": "ocivault",
      "value": "<SECRET OCID>",
      "authentication": {
        "method": "OCI_INSTANCE_PRINCIPAL",
        "OCI_PROFILE": "DEFAULT"
      }
    }
  }
}

Within the configuration provider, ConnectionString key has precedence over other keys, such as connect_descriptor, with the same prefix key. Thus, if the User Id attribute is not included in the ConnectionString, then ODP.NET uses the user key that has the same prefix key. If the Data Source attribute is not included in the ConnectionString, then it will use the value of the connect_descriptor key that has the same prefix key. Similar behavior applies for all the ConnectionString attributes.

The precedence order for constructing the ODP.NET connection string from higher precedence to lower is as follows:

  1. ODP.NET ConnectionString centralized configuration provider key

  2. ODP.NET OracleConnection ConnectionString attributes, OracleConnection properties, provider configuration file, and ODP.NET connection parameters, such as ODP/Pooling, ODP/Connection Timeout, and ODP/OciCompartment. All of these have equal precedence.

  3. Oracle common driver attributes in provider configuration file, such as user, password, and connect_descriptor.

Password Connection Attributes

For the AWS, GCP, OCI, and local file providers, passwords, wallet locations, and token locations must be specified as password JSON objects. Password JSON objects are supported with Azure Vault as well, but not Azure App Configuration.

The Oracle user password has the following format and properties in the configuration providers:

Property Required or Optional Possible Values and Notes
type Required
  • Base64

  • AwsSecretsManager

  • azurevault

  • GcpSecretManager

  • ocivault

value Required
  • Base64 encoded password (base64)

  • AWS Secrets ARN (AwsSecretsManager)

  • Azure Key Vault URI (azurevault)

  • GCP Secret resource name (GcpSecretManager)

  • OCID of the secret (ocivault)

authentication Optional
  • Authentication type

  • Optional parameters

This property has the same possible values and defaults as described in the AWS, Azure and GCP, OCI Centralized Configuration Provider sections.

versionNumber Optional Applicable to AWS Secrets Manager, GCP Secret Manager, and OCI Vault only
stage Optional Applicable to AWS Secrets Manager and OCI Vault only

Sample OCI password configuration:

    "password": {
      "type": "ocivault",
      "value": "<SECRET OCID>",
      "authentication": {
	"method": "OCI_INSTANCE_PRINCIPAL",
	"OCI_PROFILE": "DEFAULT"
      }
    }

Sample AWS password configuration:

"password": {
  "type": "awssecretsmanager",
  "value": "<AWS SECRET ARN>",
 "authentication": {
    "method": "AWS_DEFAULT",
    "AWS_PROFILE": "<AWS PROFILE NAME>"
  }
}

Sample Azure password configuration:

"password": {
  "type": "azurevault",
  "value": "<AZURE KEY VAULT URI>",
 "authentication": {
    "method": "AZURE_SERVICE_PRINCIPAL",
    "AZURE_CLIENT_ID": "<AZURE CLIENT ID>",
    "AZURE_CLIENT_CERTIFICATE_PATH": "<AZURE CLIENT CERTIFICATE PATH>",
    "AZURE_TENANT_ID": "<AZURE TENANT ID>"
  }
}

Sample GCP password configuration:

"password": {
  "type": "gcpsecretmanager ",
  "value": "<GCP SECRET RESOURCE NAME>",
 "authentication": {
    "method": "GCP_DEFAULT"
  }
}

Sample Base64 password configuration:

{
    "type": "base64",
    "value": "<BASE64 ENCODED PASSWORD>"
}

ODP.NET ignores plain text passwords in the AWS S3, GCP Cloud Storage, OCI Object Store, or local file centralized configuration provider file for security reasons. The Azure centralized configuration provider accepts plain text passwords in password keys and the connection string since Azure provides secure means to access the app configuration.

While Base64 format is allowed in the password JSON object, it is not considered secure and should only be used in development environments.

If Persist Security Info is false (default) in the ODP.NET connection string, then the Password value is not returned with the connection string value to protect the sensitive password information.

In the AWS case, the following sensitive authentication information is also removed from the connection string:

In the Azure case, the following sensitive authentication information is also removed from the connection string:

In the OCI case, the following sensitive authentication information is also removed from the connection string:

Automatic Password Refresh

Administrators often set up password expiration policies so that the passwords become invalid at a regular cadence and replaced with new ones. For existing connection pools, this can result in ORA-01017 errors (invalid username/password; logon denied) and having to rebuild the connection pool.

ODP.NET supports the ability to automatically refresh the existing connection pool with the new password. This feature eliminates end users experiencing connection errors and forcing apps to rebuild their pool after each password refresh.

Using this feature requires:

When ODP.NET encounters an invalid password, it retrieves the latest configuration provider values and checks for the following conditions:

If any part of this process does not meet the stated conditions, then ODP.NET returns the original connection error.

For end users and administrators, this automated password refresh experience provides a seamless and error free experience.

Connection URL Caching

Since connection information retrieval takes longer retrieving from a cloud resource than local disk, ODP.NET can cache connection information. Cache updates can occur using a polling or change notification model.

Connection URL Polling Updates

The polling model uses the config_time_to_live key. This property sets the duration in seconds for ODP.NET to keep the connection information cached.

By default, config_time_to_live is 86,400 seconds (24 hours). The maximum value is Int 64.MaxValue. If it is set to a non-positive value, ODP.NET will never expire the cache.

When the cache expires, ODP.NET retrieves the connection information from the configuration provider again. Once retrieved, ODP.NET refreshes the cache and uses the new configuration for the duration of the config_time_to_live setting. Note: If pooling is enabled, then only the password and proxy password can be updated. If pooling is disabled, then all the connection information will be refreshed.

When config_time_to_live expires, the configuration is considered “softly expired”. ODP.NET attempts to refresh the cache with every connection request. If a new configuration cannot be retrieved, then ODP.NET continues to open new connections with the “softly expired” configuration for up to the time set in config_time_to_live_grace_period.

By default, config_time_to_live_grace_period is 1800 seconds (30 minutes). It is an Int64. Any negative value will be treated as a grace period of zero seconds.

If new connection information can not be retrieved during config_time_to_live_grace_period, then the configuration fully expires. No new connections can be made with these old credentials. Existing “softly expired” connections will continue to work until closed or disposed.

Connection URL Change Notification Updates

The change notification model provides real time connection information updates. When data on the cloud is modified, ODP.NET receives the notification almost immediately instead of waiting for config_time_to_live to expire. The relevant cache entries are evicted, and the latest values are retrieved the next time they are needed.

Connection URL change notifications are available for Azure App Configuration and OCI Object Storage only at this time.

Similarly to config_time_to_live, if connection pooling is disabled, then change notification can monitor and update all connection configuration provider settings. If pooling is enabled, only the password and proxy password are monitored and updated.

Developers register their apps for change notification using the options in the connection string URL.

To unregister from change notification, developers call the OracleConnection.UnregisterCloudConfigNotification(OracleConnection con) method. If pooling is enabled, the method unregisters all connections that reside in the same pool as the connection passed into the method.

Change notification updates do not reset the config_time_to_live timer.

AWS S3 Setup for Change Notification

ODP.NET AWS-based change notifications require AWS Simple Notification Service (SNS) and AWS Simple Queue Service (SQS). When a change is detected in AWS S3, SNS sends a notification message to SQS. SQS forwards the message to the ODP.NET application, prompting the application to refresh the values associated with the update notification upon their next use.

AWS SNS Setup Steps

Setting up AWS change notification requires the following configuration steps:

Create an Amazon SQS queue.

  1. Follow AWS SQS documentation to create a standard queue: Creating a standard queue using the Amazon SQS console

  2. Note down the SQS queue ARN and the queue URL.

(Optional) Create an Amazon SNS topic and subscription.

  1. Follow the AWS SNS documentation to create an Amazon SNS topic using the Amazon SQS console: Creating an Amazon SNS topic.

    In step 4a, choose standard topic type.

  2. Follow the AWS SNS documentation to create a subscription to the Amazon SNS topic: Creating a subscription to an Amazon SNS topic.

    In step 4b, choose Amazon SQS as protocol.

    In step 4c, enter the SQS queue ARN.

Setup change notification for AWS S3 Configuration Provider

ODP.NET Setup for AWS S3 Change Notifications

To enroll ODP.NET in change notifications, the following options in the URL connection string are required for SQS queue:

Name Description Example
QUEUEURL AWS Simple Queue Service URL for change notification https://sqs.us-west-1.amazonaws.com/1234567890/odpnet-sqs

URL Connection String format AWS S3 Change Notifications

string connStr = "config-awss3:// bucket.s3.us-west-1.amazonaws.com/odpnet-folder/config.json?
key=connection1&QueueUrl=https://sqs.us-west-1.amazonaws.com/1234567890/odpnet-sqs";

Azure App Configuration Setup for Change Notification

ODP.NET Azure-based change notifications require Azure Event Grid and Azure Service Bus. Azure Event Grid watches the Azure App Configuration for changes. When a change is detected, it sends a notification message to Azure Service Bus. Service Bus forwards the message to the ODP.NET application, prompting the application to refresh the values associated with the update notification upon their next use.

Azure Service Bus

Azure Service Bus is a fully managed enterprise message broker with message queues and publish-subscribe topics. ODP.NET change notification can use the Service Bus message entities, Queues and Topics. Queues follow a one-to-one model, where one sender delivers messages to one receiver. Topics follow a one-to-many model, where one sender delivers messages to multiple receivers.

Topics are used when multiple ODP.NET applications register for change notification on the same Azure App Configuration. Otherwise, Queues are sufficient. Azure Service Bus pricing varies depending on the usage and feature set the change notification app required.

Azure Service Bus Setup

  1. On the Azure portal, navigate to the Service Bus page.

  2. Start a new Service Bus resource setup by selecting a pricing tier appropriate for the intended use and budget.

  3. Once the Service Bus resource is created, select it, and go to the Overview tab. Remember the “Host name”

    • It will look like: <Service Bus Name>.servicebus.windows.net

    Next, you will need to set up either Service Bus queue or topic, not both.

Azure Service Bus Queue Setup

  1. On the Azure portal Service Bus page, navigate to the Queues and create a new Queue.

    • The default options can be used or be modified. It will not affect compatibility with ODP.NET change notifications.
  2. Name the Queue and remember the Queue name.

Azure Service Bus Topic Setup

  1. On the Azure portal Service Bus page, navigate to the Topics and create a new Topic.

    • The default options can be used or be modified. It will not affect compatibility with ODP.NET change notifications.
  2. Name the Topic and remember the Topic name.

  3. Navigate to the created topic.

  4. Create a new subscription.

    • The default options can be used with ODP.NET change notifications.
  5. Name the Subscription and remember the Subscription name.

  6. Repeat Steps 4 and 5 if there are multiple ODP.NET Applications that will receive change notifications from the same Azure App Configuration. Each application should use a separate subscription.

Azure Event Grid Setup

To connect the App Configuration to Service Bus, an Event Grid resource is required.

  1. On the Azure portal, search or navigate to the Event Grid page.

  2. Go to the “System topics” tab and create a new Event Grid System Topic.

  3. For “Topic Types”, search for and select Microsoft Azure App Configuration

  4. Have the System Topic point to the App Configuration to be watched.

  5. Navigate to your new System Topic and create a new subscription.

  6. For “Event Schema”, select “Event Grid Schema” from the drop-down menu.

  7. For “Filter to Event Types”, select both “Key-Value Modified” and “Key-Value Deleted”.

  8. For “Endpoint Type”, select “Service Bus Topic” or “Service Bus Queue” depending on whether you are using a topic or queue.

  9. For the “Endpoint”, select the topic or queue created earlier.

    • For the other options, you may use the default values.

ODP.NET Setup for Azure Change Notifications

To enroll ODP.NET in change notifications, the following options in the URL connection string are required for Service Bus queues:

Service Bus Option Description
SERVICE_BUS_HOST Service Bus host URL
SERVICE_BUS_QUEUE Service Bus queue name

All options are required values for queues and all are string values.

URL Connection String format for Azure queues

string connStr = "config-azure://myAppConfig?key=test/&SERVICE_BUS_HOST=<Service Bus Host>
&SERVICE_BUS_QUEUE=<Queue Name>";

For Service Bus topics, the following options in the ODP.NET URL connection string are required:

Service Bus Option Description
SERVICE_BUS_HOST Service Bus host URL
SERVICE_BUS_TOPIC Service Bus topic name
SERVICE_BUS_SUBSCIPTION Subscription name within the Service Bus topic

All options are required values for topics and all are string values.

URL Connection String format for Azure topics

string connStr = "config-azure://myAppConfig?key=test/&SERVICE_BUS_HOST=
<Service Bus Host>&SERVICE_BUS_TOPIC=<Topic Name>&SERVICE_BUS_SUBSCRIPTION=
<Subscription Name>";

You have now completed change notification setup for Azure App Configuration.

GCP Cloud Storage Setup for Change Notification

ODP.NET GCP-based change notifications require GCP Pub/Sub service. When a change is detected in GCP Cloud Storage, Pub/Sub notifications send information about changes to objects in your buckets to Pub/Sub, where the information is added to a Pub/Sub topic. In an ODP.NET application, if the GCP configuration provider is subscribed to this Pub/Sub topic, the application will refresh the values associated with the update information upon their next use.

GCP Pub/Sub Setup

  1. Follow GCP Pub/Sub documentation to create a Pub/Sub topic and its default subscription: Create a topic.

  2. Note down the topic name and subscription name.

GCP Pub/Sub notifications for Cloud Storage Setup

  1. Follow the GCP Cloud Storage documentation to set up the Pub/Sub notification: Configure Pub/Sub notifications for Cloud Storage.

  2. Use the GCP Cloud Storage bucket name where your ODP.NET configuration file is stored and the GCP Pub/Sub topic name from the previous step.

ODP.NET Setup for GCP Cloud Storage Change Notifications

To enroll ODP.NET in change notifications, the following options in the URL connection string are required for Pub/Sub Subscription:

Name Description Format Example
SUBSCRIPTIONNAME GCP Pub/Sub subscription name for change notification projects/{project-name}/subscriptions/{subscription-name} projects/odpnet-1/subscriptions/odpnet-config-sub

URL Connection String format for GCP Pub/Sub

string projectId = "dotnet-1";
string bucketName = "odpnet-sample";
string objectName = "hr.json";
OracleConnection conn = new OracleConnection($"config-gcpstorage://project={projectId};bucket={bucketName};object={objectName}?
key=Connection1&subscriptionname=projects/dotnet-1/subscriptions/dotnet-sub");

OCI Object Storage Event Notification for Change Notification

ODP.NET OCI Object Storage-based change notifications require Oracle Cloud Infrastructure Events Service and Notifications service to establish a communication channel that publishes messages using topics and subscriptions. When a change is detected, it sends a notification message to the HTTPS endpoint. The OCI event listener of the ODP.NET application receives the message, prompting the application to refresh the values associated with the update notification upon their next use.

To use OCI Object Storage event notifications, you must configure the OCI Object Storage, OCI Notifications service, event rules, an event listener, and ODP.NET to use OCI event notifications. Let’s walk through each of these setup topics.

OCI Object Storage Setup

The first step is to setup the OCI JSON configuration file in OCI Object Storage and then connect to the Oracle database using the file.

  1. Create a bucket in Object Storage and enable “Emit Object Events” for that bucket. Existing buckets can enable “Emit Object Events” in the “Bucket Details” > “ Bucket Information” section.

  2. Upload your OCI JSON configuration file to this bucket.

OCI Event Listener Setup

ODP.NET’s OCI Event Listener uses HTTPS protocol to receive notification messages, and it has two requirements. First, OCI Notifications service requires a publicly accessible URL with a certificate authority issued certificate. It also must accept POST calls. The OCI API Gateway can be set up to fulfill this requirement through setting up a route. A gateway route is the mapping between a path, one or more methods, and a back-end service.

Second, the host running ODP.NET application must be able to receive the HTTPS message. This usually requires the host to have a port open to the traffic of the notifications service. If your application is running in an OCI Compute Instance and are using OCI API Gateway, you can modify the virtual cloud network’s ingress rules security list to permit an open port to OCI API Gateway for the OCI Notifications service. Remember the network path and port you are forwarding into. You will use it in your ODP.NET connection string URL.

OCI Notifications Service

When the JSON configuration file in the OCI Object Storage bucket is updated, OCI Notifications service can emit an event. The event can publish a notification and use the notification to update to the latest configuration version.

OCI Notifications service supports alarms, event rules, and connectors to emit human-readable messages through supported endpoints, including email, SMS, and Slack messages with an HTTPS payload. Additionally, you can automate tasks through custom HTTPS endpoints and OCI Functions, as well as directly publish messages.

The notifications service can be enabled to set up communication channels for publishing messages using topics and subscriptions. A topic is a communication channel for sending messages to subscriptions. When a message is published to a topic, the notifications service sends the message to all the topic’s subscriptions. A subscription is a topic endpoint.

Setup OCI Notification Topic and Subscription

A notification topic allows creating a set of notification subscriptions that can be tied together by an event. Here’s how to setup a topic and subscription.

  1. Navigate to your OCI tenancy compartment’s Notifications service management web page. The page title should be “Topics in <Compartment Name> Compartment”.

  2. Click the Create Topic button.

  3. Give the topic an identifiable name. It can be helpful to include bucket/configuration file name and subscription protocols in the name.

  4. Click on the newly created topic name in the list. Now, let’s create the subscription.

  5. Click the Create Subscription button.

  6. Select HTTPS (Custom URL) as the communication protocol and add the URL for HTTPS.

  7. Confirm your subscription. For HTTPS, you will receive a payload like the following:

{"ConfirmationURL":"https://cell1.notification.us-phoenix-1.oci.oraclecloud.com/
20181201/subscriptions/ocid1.onssubscription.oc1.phx.../confirmation?token=MDA...&
protocol=CUSTOM_HTTPS"}

After confirming your subscription, its status will change from “Pending” to “Active”. You can test your subscription by publishing a test message.

Setup OCI Notification Event Rules

Rules trigger actions for specified event conditions. Let’s create a rule to trigger a notification when the config file is modified.

  1. Navigate to your OCI tenancy compartment’s event service rules web page. The page title should be “Rules in <Compartment Name> Compartment”.

  2. Click the Create Rule button.

  3. Give the rule an identifiable display name.

  4. Under the rule conditions section, set the following values:

    • Condition: Event Type

    • Service Name: Object Storage

    • Event Type: Object – Update

    These settings indicate whenever there is an Object Storage object update, an action is triggered. Since update can occur for any object in any bucket, let’s add more conditions to narrow it down.

  5. Click the Another Condition button to add more conditions.

    1. Create a condition with the following attributes:

      • Condition: Attribute

      • Attribute Name: <Bucket Name or ID>

      • Attribute Value: <Configuration File Bucket Name/OCID>

    2. Create a second condition with the following attributes:

      • Condition: Attribute

      • Attribute Name: <Resource Name or ID>

      • Attribute Value: <Configuration File Name/OCID>

  6. In the Actions section, set the following values:

    • Action Type: Notifications

    • Notifications Compartment: <Compartment Name of the Notification Topic>

    • Topic: <Topic Name>

  7. Click the Create Rule button.

  8. Click the Validate Rule button to test whether the rule works. A notification message should be sent.

    1. In the Example Events section, use a code editor to change the following settings to the matching values you just set for the event rules.

      • <Compartment Name of the Notification Topic>

      • <Resource Name>

      • <Bucket Name>

    2. Click the Check If Example Event Matches Rule button.

    That completes the OCI setup. Let’s complete the ODP.NET setup for OCI notifications.

ODP.NET Setup for OCI Notifications

For OCI Object Storage notifications, the ODP.NET connection string URL requires the OCI profile name in the JSON configuration file and the OCI event listener path and port. The connection string URL syntax is:

@config-ociobject:{object-url}[?key=name&option1=value1&option2=value2...]

To enable OCI change notification, the following options in the URL connection string are required:

OCI Event Listener Option Description
Event_Listener_Path network path listener listens on for notifications
Event_Listener_Port network port listener listens on for notifications

In our setup, the connection string URL will also include the OCI_PROFILE name that you created earlier for the OCI configuration file. Your ODP.NET connection string will look similar to the following.

Sample Code: ODP.NET OCI change notification connection string URL

OracleConnection conn = new OracleConnection("@config-ociobject:https://objectstorage
.us-ashburn-1.oraclecloud.com/.../Connection.json?KEY=myconn&authentication=OCI_DEFAULT
&EVENT_LISTENER_PATH=<HOSTNAME/DIRECTORY>&EVENT_LISTENER_PORT=80")

You have now completed change notification setup for OCI Object Storage.