Monday, August 31, 2026

Susan's Solar Quandry


While at Home Depot this weekend, a SunRun representative approached me to see if I was interested in Solar. I said absolutely for many reasons. I explained that I've been keeping an eye on the cost of solar for many years and that once the cost becomes significantly financially beneficial over the 25 year life of a system, I would most certainly consider it.  However, I am not convinced that we've crossed that threshold yet and referred her to my blog post on the subject.  She said that leasing the solar system could be a beneficial option.  That reminded me of Susan's Solar Quandary.

About a year ago, my dear friend Susan shared with me that she had been approached by fine young man from SunRun that said that he could help her reduce her electricity bill through leasing a solar system.  With her current energy provider at the time, she was paying around $75/mo.  The highly detailed [sarcasm] quote (see picture below) provided by SunRun indicated that he could reduce her bill to $73/mo and relatively speaking lock in her rate for the next 25 years through a lease.


I reached out to the young man and asked for a sample copy of the lease terms. He wouldn't do that but he did eventually confirm the following points:
  • Lease term: 25 years
  • 2.99% annual rate increase (escalator)
  • Is there a fee for taking off and putting back on the solar system when the roof needs to be replaced? Yes but he didn't offer a cost
  • Could it cause issues with future buyers of the home if the buyer's lender requires the lease to be paid off before the buyer an acquire the home?  Yes
  • How is the system sized?  The system is covered to cover 90% of current usage
  • If she goes over the estimated usage for which the solar system is sized, are there any overage charges? Yes, they charge additional at around market rate at the time
  • Is there a penalty fee for buying out the system early? Yes but provided no details
I asked Susan if she had checked the market rate at Power To Choose to see if another energy provider might be less expensive than her existing provider.  She had not. I guided her through this process and found another provider that offered a rate significantly lower rate that would reduce her monthly bill at current usage from $75/mo to around $53/mo.

This created a moral question for me regarding SunRun. If SunRun knew that the market rate at the time was around $53/mo, why did their estimate only reflect a slight reduction in her monthly energy cost?

Setting the moral question aside for a moment, let's run the numbers over 25 years to compare Susan's current rate vs SunRun solar estimate, vs switching to a market rate plan.  Here were the numbers at that time if we assume consistent annual usage.


Notice that with only 2% overage, Susan's annual cost is never less than the current cost and with the built in 2.99% annual "escalator" increase, the cost of her energy with SunRun doubles by year 18 and is nearly triple by the end of the 25 year contract.  If by contrast, she switches to a market rate through Power To Choose, her rate reduces from $75/mo to $53/mo immediately and may increase only moderately over the same time period.

The important thing to take away from this post is that the details matter.  Before signing up for Solar do the math to find out if you will get a good return on the investment over the warrantied life span of the system.  And if you are considering a lease, make sure that the long term cost don't quickly exceed market rates.

Hope you find this informative and helpful.

Blessings!






Friday, August 28, 2026

Packaging ojdbc-extensions for managed software distribution


Over the last few years of helping customers explore Entra ID and OCI IAM integration with the Oracle AI Database for centralized authentication, authorization and user life cycle management, several have encountered issues downloading the required ojdbc-extensions libraries from Maven repository.  This is typically because enterprise firewalls or computer configurations are locked down to prevent downloading and installing un-approved software. That completely makes sense from a security perspective. However, it also inhibits the deployment of required software for JDBC-thin applications like SQL Developer for VS Code, SQL Developer and SQLcl that is already in use.  In this post, I'm going to share how enterprise management packaging teams can download and bundle up these requisites for their package management distribution systems like Microsoft InTune, Microsoft Configuration Manager, Windows Package Manager, Action1, PDQ Deploy and more...

Before getting into the procedure, it is imperative to note that this is an iterative process that will need to be periodically repeated with updated ojdbc-extensions versions.  Therefore, document this procedure for future re-use within your packaging management distribution solution.

1. Download Software

In the case of SQLcl and SQL Developer for VS Code, the built-in sdk is the preferred method to download the requisites.

SQLcl and SQL Developer for VS Code:
For SQLcl, use the built-in sdk command to download the requisite jar files.  For SQL Developer for VS Code, open the builtin SQLcl command. For more details, see corresponding post Entra ID Integration For VS Code.

sql -thin /nolog

SQL> sdk install jdbc-zure
Downloading the ojdbc-provider-azure SDK and all its dependencies.
The jdbc-azure SDK is installed successfully, restart SQLcl for changes to take effect

SQL> sdk install jdbc-oci
Downloading the ojdbc-provider-oci SDK and all its dependencies.
The jdbc-oci SDK is installed successfully, restart SQLcl for changes to take effect

SQL> sdk list
+------------+-----------+---------+----------------------------------------------------------------------+
| SDK        | INSTALLED | VERSION | DOCS                                                                 |
+------------+-----------+---------+----------------------------------------------------------------------+
| jdbc-oci   | YES       | 1.1.0   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |
| jdbc-azure | YES       | 1.1.0   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |
+------------+-----------+---------+----------------------------------------------------------------------+

If the SQLcl or SQL Developer for VS Code sdk command fails to connect to Maven to download the requisite files and your company has a corporate proxy, try setting the relevant java web proxy options to enable routing the connection through the corporate web proxy before running sql command:

export _JAVA_OPTIONS="-Dhttp.proxyHost=YOUR_PROXY_HOST \
                      -Dhttp.proxyPort=YOUR_PROXY_PORT \
                      -Dhttp.proxyUser=YOUR_USERNAME \
                      -Dhttp.proxyPassword=YOUR_PASSWORD \
                      -Dhttps.proxyHost=YOUR_PROXY_HOST \
                      -Dhttps.proxyPort=YOUR_PROXY_PORT \
                      -Dhttps.proxyUser=YOUR_USERNAME \
                      -Dhttps.proxyPassword=YOUR_PASSWORD \
                      -Djdk.http.auth.tunneling.disabledSchemes= \
                      -Djdk.http.auth.proxying.disabledSchemes="

If going through a web proxy does not work, then a firewall rule or proxy will need to be setup to enable the downloads.  If is not possible, work with your corporate security time to find a compromise to complete the downloads.

For SQL Developer and other JDBC-thin applications that don't include SQlcl sdk command, you can use the JDBC driver get-deps command to download the requisites and create the product.conf configuration file.  Start with downloading the OJDBC driver and confirm the check sum matches.

Mac/Linux:
jdbcjar="https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc11/23.26.1.0.0/ojdbc11-23.26.1.0.0.jar"

curl -sko ojdbc11.jar ${jdbcjar}


ckmd5=$(openssl dgst -md5 ojdbc11.jar|awk '{ print $2 }')


md5=$(curl -sk 
${jdbcjar}.md5)

echo -e "${md5}\n${ckmd5}"

c0d07c69b0030f2f661a6c749919467f
c0d07c69b0030f2f661a6c749919467f


Windows PowerShell:
$jdbcJar = "https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc11/23.26.1.0.0/ojdbc11-23.26.1.0.0.jar"

curl.exe -s -k -o ojdbc11.jar $jdbcJar

$ckmd5 = (Get-FileHash -Algorithm MD5 -Path ojdbc11.jar).Hash.ToLower()

$md5 = (curl.exe -s -k "$jdbcJar.md5").Trim()

"$md5`n$ckmd5"

c0d07c69b0030f2f661a6c749919467f
c0d07c69b0030f2f661a6c749919467f


If these downloads are not successful, you may need to add relevant web proxy options to _JAVA_OPTIONS cited above with SQLcl sdk command before running the java command to route the requests through the web proxy.

If routing the requests through the web proxy are unsuccessful, work with the corporate security time to find an approach that enables you to download the requisties.


2. Prepare SQL Developer Requisites

SQL Developer has two additional requisites beyond just downloading the jar files.  The path where the ojdbc-extensions will need to be pre-determined for consistent dependency resolution and a corresponding product.conf configuration file needs to be created for either inclusion with SQL Developer or deploying to the user's <home>\AppData\Roaming\sqldeveloper\<version>\ Windows directory or $HOME/.sqldeveloper/<version>/ directory.  For more instructions on how to create this product.conf configuration file, see my post on ODB Entra ID Integration For JDBC-thin Applications.

Note for OCI IAM integration that you will be getting the ojdbc-provider-oci provider rather than the ojdbc-provider-azure provider.  It doesn't hurt to have both providers so long as they are in separate destination folders like "C:\u01\app\ojdbc-extensions-1.0.6\azure" for the ojdbc-provider-azure provider and "C:\u01\app\ojdbc-extensions-1.0.6\oci" for the ojdbc-provider-oci provider.


3. Complete Functional Application Testing

Once the requisites are downloaded, confirm that use of each JDBC-thin application works properly with the respective Entra ID and/or OCI IAM integration.


4. Bundle Software

Once the functional testing is complete, then bundle up the requisite jar files and product.conf according to your corporate standards and package management distribution solution.  For example, perhaps zip up the entire directory into a hard coded full path that will be distributed and unziped to the target system for deployment.


5.  Register Package Bundle Into Management System

Once the package bundle is complete, register the package for distribution into your package management distribution solution so that it will become available to end user requests.


6. Test End User Deployment

Once the package bundle is registered, test deploying to an end user computer with your respective package management distribution solution. Then confirm that the respective JDBC-thin application functions properly for Entra ID and/or OCI IAM integration connections.


I hope you found this post helpful and informative.

Blessings!

Brad
















Entra ID Integration For VS Code


Over the past few years helping hundreds of customers evaluate Entra ID integration with Oracle AI Database for centralized authentication, authorization and database user life cycle management, I have been surprised how few customers know about SQL Developer's replacement SQL Developer for VS Code.  This is important to to know since SQL Developer support concludes April, 2027.

In this post I walk you through how to install and configure Visual Studio Code for Entra ID and OCI IAM integration.

1. Install Visual Studio Code

The first step is to download and install Visual Studio Code from the download site.
My daily driver is a macOS computer. Therefore, the screenshots will be from that perspective.
The downloaded file for an Apple silicon computer is VSCode-darwin-arm64.dmg. Other options for Apple Intel, Linux and Microsoft operating systems are available at the download site as well.  On my MacBook, I open the dmg file and drag Visual Studio Code app to the Applications folder and then open Visual Studio Code.


2. Install VS Code Extension

The next step is to install the SQL Developer for VS Code extension.  To do this, navigate to the download page at https://www.oracle.com/database/sqldeveloper/vscode/download/.



Click on "Install from Visual Studio Marketplace".  That will take you to the extension on the visual studio marketplace page. 


Once on the VSCode extension page, click on the green and white "Install" button.



This will open Visual Studio Code app and prompt you to install the extension. Click on "Install" and wait for the installer to complete the installation process.



3. Install ojdbc-extensions

The last step for setting up Visual Studio Code for Entra ID and OCI IAM integration is to install the respective libraries from the Maven.  To do this, you first open the Visual Studio Code Terminal panel by clicking on "View" from the top bar and then click on "Terminal".


Then in the command line prompt, click on the arrow next to the plus (+) symbol to pull down the list of command line options and click on "SQLcl". This will open a SQLcl command prompt.


In the SQLcl command prompt, you will install the Entra ID (a.k.a. azure) and OCI IAM SDKs. Once installed list the SDKs to confirm the version installed is at least 1.0.5.  In this case both are version 1.1.0, which is the latest version as of August, 2026.
SQL> sdk install jdbc-zure
Downloading the ojdbc-provider-azure SDK and all its dependencies.
The jdbc-azure SDK is installed successfully, restart SQLcl for changes to take effect
SQL> sdk install jdbc-oci
Downloading the ojdbc-provider-oci SDK and all its dependencies.
The jdbc-oci SDK is installed successfully, restart SQLcl for changes to take effect

SQL> sdk list
+------------+-----------+---------+----------------------------------------------------------------------+
| SDK        | INSTALLED | VERSION | DOCS                                                                 |
+------------+-----------+---------+----------------------------------------------------------------------+
| jdbc-oci   | YES       | 1.1.0   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |
| jdbc-azure | YES       | 1.1.0   | https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/ |
+------------+-----------+---------+----------------------------------------------------------------------+

4. Add Connections

Now that VSCode extension is configured, add database connections to Visual Studio Code.  The VSCode extension supports multiple connection types including Basic, JDBC URL, TNS, and others. On my computer, I have all connection strings defined in a single tnsnames.ora configuration file that already has my Entra ID and OCI IAM TNS entries.  Therefore, I select TNS for the "Connection Type".  And then I have to specify the path to the tnsnames.ora file.  To do that, click on the SQL Developer icon on the left panel and then click on click on "Create Connection" in the middle panel.


This will open a connection configuration panel on the right. In that panel, click on "Connection Type" and select "TNS" and click on the sprocket symbol to the right of the "TNS File Location".  Enter the path to your tnsadmin.ora configuration file and then click on the X symbol in the upper right hand corner of that Settings box to close that window.


The final configuration step is to enter the "Connection Name" and select the "Network Alias" from the TNS list. In my case, I named the connection "PDB1_19c_ENTRA" and selected "PDB1_19C_ENTRA" from the TNS Network Alias list and then click the "Save" button to save that connection configuration.




5. Restart Visual Studio Code

Even though the ojdbc-extensions libraries have been installed, Visual Studio Code has not yet loaded them. To load the libraries, you most quit and re-open the Visual Studio Code app again.


6. Test Connection

Once the Visual Studio Code app is open and the SQL Developer module has completed loading, click on SQL Developer icon on the left side and then right-click on the database that you want to connect to and click on "Connect".



If the connect string for the selected TNS alias is configured for Entra ID, a browser window will be opened to the Microsoft Entra ID login page (https://login.microsoftonline.com/) and you will be prompted to login to Entra ID.



Once logged in, the SQL Developer PDB1_19c_ENTRA connection will expand to reveal the view of the database under the connection name.




The OCI IAM interactive login configuration has a similar pop-up window to your OCI tenancy login page.

I hope you found this post helpful and informative.

Blessings!

Brad

Friday, August 14, 2026

Switching from mkstore to orapki (or java)



In April, 2023 Oracle announced the deprecation of the mkstore command in Oracle AI Database 26ai.  What was not entirely clear from that announcement was the equivalent orapki command syntax for accomplishing equivalent mkstore entry management operations.  Fortunately, this transition is not difficult if you know the proper syntax.  This post is to serve as a reference to self on the synatx differences particularly for use cases like Enterprise User Security (EUS) and Centrally Managed Users (CMU) wallet management for ORACLE.SECURITY.USERNAME, ORACLE.SECURITY.DN and ORACLE.SECURITY.PASSWORD entries.  In this series of examples, I'll just illustrate wallet entry management for the ORACLE.SECURITY.USERNAME entry.

Oracle Support Knowledge article KB924378 was published share this information.

Environment Variables To Simplify Commands

The following environment variables simplify finding and executing commands.  The JAVA_HOME, ldir and pkilib variables are only required for the java commands.
export JAVA_HOME=/u01/sw/jdk-25.0.4

export PATH=$ORACLE_HOME/bin:$JAVA_HOME/bin:$PATH

w="
/u01/app/oracle/26ai/admin/hrdb/wallet"

wpw="Oracle123"

ldir=$(find $ORACLE_HOME -name cryptojce.jar 2> /dev/null|head -1|xargs -n1 dirname)

pkilib="${ldir}/oraclepki.jar:${ldir}/cryptoj.jar"


List Wallet Entries

Here is how to view wallet entries with each of the command options.

mkstore
mkstore -nologo -wrl ${w} -list

orapki secretstore list_entries -nologo -wallet ${w} -pwd "${wpw}"

orapki summary
orapki wallet display -nologo -summary -wallet ${w}

orapki complete
orapki wallet display -nologo -complete -wallet ${w}

orapki details
orapki wallet display -nologo -details -wallet ${w}

java
java -classpath "${pkilib}" oracle.security.pki.textui.OraclePKITextUI secretstore list_entries -nologo -wallet ${w} -pwd "${wpw}"


Create Wallet Entry

Here is how to create a wallet entry for ORACLE.SECURITY.USERNAME with each of the command options.

mkstore
mkstore -nologo -wrl "${w}" -createEntry ORACLE.SECURITY.USERNAME bdiggs

orapki secretstore create_entry -nologo -wallet ${w} -pwd "${wpw}" -alias ORACLE.SECURITY.USERNAME -secret bdiggs

java
java -classpath "${pkilib}" oracle.security.pki.textui.OraclePKITextUI secretstore create_entry -nologo -wallet ${mywallet} -pwd "${walletpw}" -alias ORACLE.SECURITY.USERNAME -secret bdiggs


View Wallet Entry

Here is how to view a wallet entry for ORACLE.SECURITY.USERNAME with each of the command options.

mkstore
mkstore -nologo -wrl ${w} -viewEntry ORACLE.SECURITY.USERNAME

orapki secretstore view_entry -nologo -wallet ${w} -pwd "${wpw}" -alias ORACLE.SECURITY.USERNAME

java
java -classpath "${pkilib}" oracle.security.pki.textui.OraclePKITextUI secretstore view_entry -nologo -wallet ${w} -pwd "${wpw}" -alias ORACLE.SECURITY.USERNAME


Delete Wallet Entry

Here is how to delete a wallet entry for ORACLE.SECURITY.USERNAME with each of the command options.


mkstore
mkstore -nologo -wrl "${w}" -deleteEntry ORACLE.SECURITY.USERNAME

orapki secretstore delete_entry -nologo -wallet ${w} -pwd "${wpw}" -alias ORACLE.SECURITY.USERNAME

java
java -classpath "${pkilib}" oracle.security.pki.textui.OraclePKITextUI secretstore delete_entry -nologo -wallet ${w} -pwd "${wpw}" -alias ORACLE.SECURITY.USERNAME



I hope you found this informative and helpful.

Blessings!


Monday, August 3, 2026

Oracle AI Database Walletless TLS


Over the last few years, I've educated enough customers on the concept of walletless Transport Layer Security (TLS) that I think a blog post is warranted to unpack this feature.  In short, the term walletless means that you do not need to create, distribute and update Oracle wallets (or Java Trust store for JDBC thin clients) to all Oracle AI Database clients for validating the authenticity of the server's TLS signed certificate.  The client instead, leverage's the client host operating system's existing certificate trust store to confirm the authenticity of a server's certificate.  The client configuration conveys the intent to use the client's host operating system trust store by setting the WALLET_LOCATION=SYSTEM parameter in either sqlnet.ora or the connect string/name service (TNS) record stored in either a local tnsnames.ora file or remotely in the LDAP-based name service.

This feature was initially introduced between 2021 and 2022 with 21c and was backported to 19c and is supported going forward including 26ai.

This one-way TLS framework is composed of certificate authority (CA), a TLS server (Oracle AI Database Server) with a certificate that is signed by the CA, and a TLS client (Oracle AI Database Client such as SQL*Plus, SQLcl, SQL Developer, ... and programatic clients like java, python, ruby, ...) with local trust store.  The client connects to the server over TLS, retrieves the server's certificate and then confirms the authenticity with the certificate chain of trust that is stored in a local trust store.

With self-signed certificates, a wallet (or java trust store) must be created and populated with the certificate chain of trust, which is just the client's certificate.   Then the trust store(s) must be distributed to all database clients that need to securely connect over TLS to the server.  This can be an arduous and operationally inefficient repetitive maintenance task that may not always be possible because the database server administrators do not always know what clients are connecting to the server.

Mutual two-way TLS authenticity framework is the same as one-way TLS plus the client has a signed TLS certificate that the server must confirm as well.  Oracle's walletless solution does not include support for mutual TLS.

Let's look at two examples: Privately signed certificates by Active Directory Certificate Service (AD CS) and publicly signed certificates by a public CA.

Active Directory Certificate Service Signed Certificates

In the case of the privately signed certificates by AD CS, Microsoft automatically propagates the AD CS certificate chain to the trust store of managed computers.   For enterprise environments, that covers all of the enterprise managed laptop and desktop computers.  For database client software running on any of the managed hosts, the client's sqlnet.ora (parameter defaults file) or tnsnames.ora can set WALLET_LOCATION=SYSTEM to indicate that the client can confirm the authenticity of the server's certificate.


Here is a sample sqlnet.ora file entry:
cat sqlnet.ora
WALLET_LOCATION=SYSTEM

Here is a sample tnsnames.ora file entry:
PDB1 = 
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
    (SECURITY=
      (SSL_SERVER_DN_MATCH=TRUE)
      (WALLET_LOCATION=SYSTEM)
    )
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=pdb1)
    )
  )


Public Certificate Authority Signed Certificates

In the case of publicly signed certificates, the operating system vendor maintains a trust store that contains the current certificate chain of trust for all major public certificate authorities.  This trust store is periodically updated through operating system updates.



The sqlnet.ora and tnsnames.ora examples from the privately signed AD CS example would similarly set WALLET_LOCATION=SYSTEM to use the local operating system trust store.

For reference, here is information on each of the major operating system trust stores.
Note that Advanced Interactive Executive (AIX) is the only operating system for which the trust store provider that may not by default include any certificate chains of trust. The AIX link above provides instructions on how add certificate chains of trust to the AIX trust store.

Additional documentation references for client specific configurations available below:
I hope you find this helpful!

Blessings!