Monday, May 18, 2026

MacOS ODB Client Setup With EntraID Integration


A customer that does all of their Oracle database development and administration from Apple Silicon based MacOS computers and asked what the most efficient method is for setting up Oracle suite of database client tools on MacOS where the tools are setup for Entra ID integration.  I worked with them to get everything setup and am sharing my notes in case anyone else would like to do the same. Note that this is just one of many ways that you could set everything up.  There is nothing special about the $HOME/.oracle directory.  I just used a single base directory ($HOME/.oracle) for simplicity.

1. Setup Base Directory

Make a base directory in which to store the environment, TNS admin data, wallets, and downloaded software

mkdir -p $HOME/.oracle/env $HOME/.oracle/bits $HOME/.oracle/admin $HOME/.oracle/instant_client

2. Download Software

Download the following software into $HOME/.oracle/bits:

3. Extract Software Into Desired Directories

Extract and place each software package in respective folders in $HOME/.oracle in a Terminal window:

cd $HOME/.oracle
tar -zxf bits/jdk-21_macos-aarch64_bin.tar.gz
mv jdk-21.0.11.jdk/Contents jdk
$ rmdir jdk-21.0.11.jdk
unzip -qo bits/sqlcl-26.1.2.132.1334.zip
unzip -qo -d $HOME/Applications $HOME/.oracle/bits/sqldeveloper-24.3.1.347.1826-macos-x64.app.zip
hdiutil attach $HOME/.oracle/bits/instantclient-basic-macos.arm64-23.26.1.0.0.dmg -mountpoint /Volumes/ic_basic
rsync -Ha /Volumes/ic_basic/. $HOME/.oracle/instant_client/. 
hdiutil detach /Volumes/ic_basic
hdiutil attach bits/instantclient-sqlplus-macos.arm64-23.26.1.0.0.dmg -mountpoint /Volumes/ic_sqlplus
rsync -Ha /Volumes/ic_sqlplus/. $HOME/.oracle/instant_client/.
hdiutil detach /Volumes/ic_sqlplus

Download ojdbc-extensions 1.0.6 and make product.conf config file:

cd $HOME/.oracle
mkdir -p ojdbc-extensions/1.0.6
cd ojdbc-extensions
curl -sko o11.jar https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc11/23.26.2.0.0/ojdbc11-23.26.2.0.0.jar
JAVA_HOME=$HOME/.oracle/jdk/Home
$JAVA_HOME/bin/java -jar o11.jar get-deps --coords com.oracle.database.jdbc/ojdbc-provider-azure/1.0.6 --path 1.0.6

4. Setup SQL Developer For Entra ID Integration

Backup existing SQL Developer product.conf and install new product.conf that includes the JDK 21 home and specifies all of the ojbc-extensions libraries to load:

cd $HOME/.oracle/ojdbc-extensions
export JAVA_HOME=$HOME/.oracle/jdk/Home
echo "SetJavaHome $JAVA_HOME" > $HOME/.sqldeveloper/24.3.1/product.conf
productfile="$HOME/.sqldeveloper/24.3.1/product.conf"
cp ${productfile} ${productfile}-$(date +'%Y%m%d%H%M%S')
find 1.0.6 -name "*.jar"|sed -e "s/^/AddJavaLibFile \$HOME\/.oracle\/ojdbc-extensions\//g" >> ${productfile}

5. Add ojdbc-extensions To SQLcl For Entra ID Integration

Link the ojdbc-extensions/1.0.6 directory to sqlcl/lib/sdks/jdbc-azure so that SQLcl will load the ojbc-extensions on startup:

mkdir -p $HOME/.oracle/sqlcl/lib/sdks
ln -s $HOME/.oracle/ojdbc-extensions/1.0.6 $HOME/.oracle/sqlcl/lib/sdks/jdbc-azure

6. Make Environment File For Client Runtime

Make environment variables:

$ cat /Users/buz/.oracle/env/ora.env 
export JAVA_HOME=$HOME/.oracle/jdk/Home
export TNS_ADMIN=$HOME/.oracle/admin
PATH=$JAVA_HOME/bin:$HOME/.oracle/sqlcl/bin:$HOME/.oracle/instant_client:$HOME/Applications/SQLDeveloper.app/Contents/Resources/sqldeveloper/sqldeveloper/bin:$PATH

7. Create Oracle Database Server Name Resolution File

Make tnsnames.ora file. Note that this output is just sample output from my lab.

$ cat $HOME/.oracle/admin/tnsnames.ora
HRDB_26ai =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hrdb.dbauthdemo.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = hrdb)
    )
  )

HRDB_26ai_SSL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = hrdb.dbauthdemo.com)(PORT = 2484))
    (SECURITY=(WALLET_LOCATION=SYSTEM))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = hrdb)
    )
  )

PDB1_26ai_ENTRA = 
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
    (SECURITY=
      (SSL_SERVER_DN_MATCH=TRUE)
      (SSL_SERVER_CERT_DN="CN=hrdb.dbauthdemo.com")
      (WALLET_LOCATION=SYSTEM)
      (TOKEN_AUTH=AZURE_INTERACTIVE)
      (TENANT_ID=8d2aef2e-f5e0-46fc-86c2-82604520aea9)
      (CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
      (AZURE_DB_APP_ID_URI=https://dbauthdemo.com/e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
    )
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=pdb1)
    )
  )

PDB1_26ai =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=hrdb.dbauthdemo.com)(PORT=1521))
    (CONNECT_DATA=
      (SERVER = DEDICATED)
      (SERVICE_NAME=pdb1)
    )
  )

PDB1_26ai_SSL =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
    (SECURITY=(WALLET_LOCATION=SYSTEM))
    (CONNECT_DATA=
      (SERVER=dedicated)
      (SERVICE_NAME=pdb1)
    )
  )

8. Test Each Client

Load environment variables:

. $HOME/.oracle/env/ora.env

SQL*Plus Local Account Over TLS

sqlplus system@PDB1_26ai

SQL*Plus Entra ID Integration Over TLS
Note that as of May, 2026, the SQL*Plus for MacOS does not yet support Entra ID integration. You will see the following error message:
ERROR: ORA-25723: Unsupported platform
However, for when SQL*Plus eventually does support Entra ID integration, here is a sample command for connecting to an Entra ID integrated database:

sqlplus /@PDB1_26ai_ENTRA

SQLcl Local Account Over TLS
Note, if you see an SLF4J errors, they can be ignored.

sql -thin system@PDB1_26ai

SQLcl Entra ID Integration Over TLS

sql -thin /@PDB1_26ai_ENTRA


SQL Developer
Either open SQL Developer from the application bar or from the command line

sqldeveloper

Then, add connection profiles with the following parameters for Entra ID integrated databases:
Name: <your_database_preferred_name>
Database Type: Oracle
Authentication Type: OS
Connection Type: TNS
Network Alias: <select desired database>

Once the SQL Developer connection is configured, double-click the connection to connect.

I hope you found this helpful!

Blessings

Monday, May 11, 2026

Upgrading ODB 23.26.1 to 23.26.2 and adding TCPS


Last week I was troubleshooting an Oracle AI 26 Database unified audit log project that required upgrading from 23.26.1 to 23.26.2  I had to iterate through the setup multiple times to make sure that I had the flow just right.  I did not know that stand alone Oracle AI 26 Databases use an out-of-place Gold Image release updates (RUs)  method rather than the traditional "opatch apply".  Given that this was new to me, I thought that I would helpful to write up my notes from that journey for my own edification but hopefully help others as well.  In addition, since this project was oriented around Entra ID integration with TCPS/TLS connections required been database client and server, those steps are included as well.


1. Make sure /etc/hosts entry is preceded by TLS cert FQDN:

grep hrdb /etc/hosts
10.0.0.33 hrdb.dbauthdemo.com hrdb.sub10241351260.odswest.oraclevcn.com hrdb


2. Make sure hostname is fully qualified using the TLS cert FQDN:

sudo hostnamectl set-hostname $(hostname -f)


3. Upload Oracle AI Database 23.26.1 (V1054592-01.zip from https://edelivery.oracle.com) and 23.26.2 (p39099680_230000_Linux-x86-64.zip  from https://updates.oracle.com/download/39099680.html) to /u01/bits:

ls -1 /u01/bits
p39099680_230000_Linux-x86-64.zip (23.26.2)
V1054592-01.zip (23.26.1)


4.  Extract and install software and setup 19c database server:

/u01/manage_db.sh setup --dbv 26ai


5. Set LOCAL_LISTENER because I’m running 26ai on default port and 19c on alternate port in my lab.

$ORACLE_HOME/bin/sqlplus / as sysdba
SHOW PARAMETER LOCAL_LISTENER;

ALTER SYSTEM SET LOCAL_LISTENER='(ADDRESS=(PROTOCOL=TCP)(HOST=hrdb.dbauthdemo.com)(PORT=1521))' SCOPE=BOTH;

ALTER SYSTEM REGISTER;


6. Update 26 AI database to most recent release update (23.26.2) using the out-of-place Gold Image release update method found in the patch README file:

unzip -qo -d /u01/app/oracle/26ai/dbhome_2 /u01/bits/p39099680_230000_Linux-x86-64.zip

/u01/app/oracle/26ai/dbhome_2/runInstaller -silent -setupDBHomeAs /u01/app/oracle/26ai/dbhome_1

sudo /u01/app/oracle/26ai/dbhome_2/root.sh

/u01/app/oracle/26ai/dbhome_2/bin/dbca -silent -moveDatabase -sourceDB hrdb


7. Alter db26ai.env to change dbhome_1 (23.26.1 home) to dbhome_2 (23.26.2 home):

cat /u01/cfg/db26ai.env 

export ORACLE_BASE="/u01/app/oracle/26ai"

export ORACLE_HOME="/u01/app/oracle/26ai/dbhome_2"

export TNS_ADMIN="/u01/app/oracle/26ai/dbhome_2/network/admin"

export ORACLE_SID="hrdb"

export ORACLE_INSTANCE="/u01/app/oracle/26ai/dbhome_2"

export ORACLE_UNQNAME="hrdb"

export WALLET_ROOT="/u01/app/oracle/26ai/wallet_root"


8. Re-load the db26ai env and restart database:

. /u01/cfg/db26ai.env
/u01/manage_db.sh stop --dbv 26ai
/u01/manage_db.sh start --dbv 26ai


9. Set wallet_root and then lookup PDB1 GUID:

. /u01/cfg/db26ai.env
$ORACLE_HOME/bin/sqlplus / as sysdba
show parameter wallet_root;

alter system set wallet_root='/u01/app/oracle/26ai/wallet_root' scope=spfile;

select guid from v$containers where name = 'PDB1';

GUID
--------------------------------

512D5CFBAB67AA47E0632100000A0A24


10. Make tls directories (replace PDB GUID with value you retrieve from previous step):

mkdir -p $WALLET_ROOT/tls $WALLET_ROOT/<PDB_GUID>/tls


11. Extract wallet_root from backup with:

unzip -qo -d "$WALLET_ROOT/.." /u01/hrdb_wallet_root.zip


12. Copy wallet to PDB1 tls directory (replace PDB GUID with retrieved PDB GUID value):

rsync -Hav $WALLET_ROOT/tls/. $WALLET_ROOT/<PDB_GUID>/tls/.


13. Display wallet root contents to make sure they are valid:

$ORACLE_HOME/bin/orapki wallet display -nologo -complete  -wallet $WALLET_ROOT/tls


14. Create or update sqlnet.ora:

cat $TNS_ADMIN/sqlnet.ora
SQLNET.AUTHENTICATION_SERVICES = (TCPS,NTS,BEQ)

SSL_CLIENT_AUTHENTICATION = FALSE


15. Create or update listener.ora:

cat $TNS_ADMIN/listener.ora
SSL_CLIENT_AUTHENTICATION = FALSE


LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = hrdb.dbauthdemo.com)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
      (ADDRESS = (PROTOCOL = TCPS)(HOST = hrdb.dbauthdemo.com)(PORT = 2484))
      (SECURITY=(WALLET_LOCATION=/u01/app/oracle/26ai/wallet_root/tls))
    )
  )


16. Create or update tnsnames.ora:

cat $TNS_ADMIN/tnsnames.ora
HRDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = hrdb.dbauthdemo.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = hrdb)
    )
  )

HRDB_SSL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCPS)(HOST = hrdb.dbauthdemo.com)(PORT = 2484))
    (SECURITY=(WALLET_LOCATION=/u01/app/oracle/26ai/wallet_root/tls))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = hrdb)
    )
  )

pdb1 =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCP)(HOST=hrdb.dbauthdemo.com)(PORT=1521))
    (CONNECT_DATA=
      (SERVER = DEDICATED)
      (SERVICE_NAME=pdb1)
    )
  )

pdb1_ssl =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
    (SECURITY=(WALLET_LOCATION=/u01/app/oracle/26ai/wallet_root/tls))
    (CONNECT_DATA=
      (SERVER=dedicated)
      (SERVICE_NAME=pdb1)
    )
  )


17. Update /etc/oratab hrdb entry because I’m running 19c and 26ai on two separate home’s on the same host:
From:

hrdb:/u01/app/oracle/26ai/dbhome_1:N

To:

hrdb26ai:/u01/app/oracle/26ai/dbhome_2:N


18. Restart database server:

/u01/manage_db.sh stop --dbv 26ai
/u01/manage_db.sh start --dbv 26ai


19. Test that you can login to each alias in tnsnames.ora:

$ORACLE_HOME/bin/sqlplus system/Oracle123@hrdb

$ORACLE_HOME/bin/sqlplus system/Oracle123@hrdb_ssl

$ORACLE_HOME/bin/sqlplus system/Oracle123@pdb1

$ORACLE_HOME/bin/sqlplus system/Oracle123@pdb1_ssl


20. Configure PDB1 for Entra ID integration and add necessary users and roles:

$ORACLE_HOME/bin/sqlplus system/Oracle123@pdb1_ssl

ALTER SYSTEM SET IDENTITY_PROVIDER_TYPE=AZURE_AD SCOPE=BOTH;
SHOW PARAMETER IDENTITY_PROVIDER_TYPE;
ALTER SYSTEM SET IDENTITY_PROVIDER_CONFIG =
'{ 
   "application_id_uri" : "https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621",
   "tenant_id" : "7f4c6e3e-a1e0-43fe-14c5-c2f051a0a3a1",
   "app_id" : "16736175-ca41-8f33-af0d-4616ade17621"
}' SCOPE=BOTH;
SHOW PARAMETER IDENTITY_PROVIDER_CONFIG;

drop USER alldbusers;
CREATE USER alldbusers IDENTIFIED GLOBALLY AS 'AZURE_ROLE=pdb.users';
SELECT USERNAME, EXTERNAL_NAME from DBA_USERS where username='ALLDBUSERS';

drop ROLE entra_dba;
CREATE ROLE entra_dba IDENTIFIED GLOBALLY AS 'AZURE_ROLE=dba.role';
GRANT pdb_dba TO entra_dba;
SELECT EXTERNAL_NAME FROM DBA_ROLES WHERE ROLE = 'ENTRA_DBA';

drop ROLE dbsession;
CREATE ROLE dbsession IDENTIFIED GLOBALLY AS 'AZURE_ROLE=session.role';
GRANT CREATE SESSION TO dbsession;
SELECT EXTERNAL_NAME FROM DBA_ROLES WHERE ROLE = 'DBSESSION';

drop USER hrapp;
CREATE USER hrapp IDENTIFIED GLOBALLY AS 'AZURE_ROLE=hr.app';
GRANT CREATE SESSION, CONNECT, SELECT ANY TABLE, INSERT ANY TABLE, UPDATE ANY TABLE, DELETE ANY TABLE to hrapp;
SELECT EXTERNAL_NAME FROM DBA_ROLES WHERE ROLE = 'HRAPP';


21. Create TNS entry for PDB1 over TLS/SSL on database client (23.4 or newer).  Note that WALLET_LOCATION is set to SYSTEM, which means that the database client uses the client operating system's trust store to confirm the authenticity of the TLS certificate because the TLS certificate had been signed by a public certificate authority.

PDB1_26ai_ENTRA =
  (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=hrdb.dbauthdemo.com)(PORT=2484))
    (SECURITY=
      (SSL_SERVER_DN_MATCH=TRUE)
      (SSL_SERVER_CERT_DN="CN=hrdb.dbauthdemo.com")
      (WALLET_LOCATION=SYSTEM)
      (TOKEN_AUTH=AZURE_INTERACTIVE)
      (TENANT_ID=8d2aef2e-f5e0-46fc-86c2-82604520aea9)
      (CLIENT_ID=e5124a85-ac3e-14a4-f2ca-1ad635cf781a)
      (AZURE_DB_APP_ID_URI=https://dbauthdemo.com/16736175-ca41-8f33-af0d-4616ade17621)
    )
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=pdb1)
    )
  )



22. Test Entra ID integration authentication to the database. In this example, I use SQLcl 26.1 from my MacOS laptop.

sql -thin /@pdb1_entra


Initiating the connection to the database using the interactive OAuth2 flow pops up a browser window to Entra ID to login.  Here you either enter user email and password or select an existing user.



If you selected an existing user, the next step will be dictated by the Entra ID conditional access policies based on several factors including from where your connecting.  In my case, it just prompts for the user's password.



The default Entra ID tenancy conditional access policy requires a one-time PIN.



Upon successfully authentication, Entra ID returns an access token through the browser's localhost to the client, with which the client makes another call to Entra ID with the authorization token to request an access token.



Upon receipt of the access token, the database client sends the access token over a TLS encrypted connection to the databaase server.  The Oracle database server downloads the current set of keys from Entra ID and confirms the authenticity of the access token and returns the authenticated SQL prompt to the client application.  Here, I show the returned SQL prompt along with a few queries to show what it looks like for an authenticated user of a shared user schema.


I hope you find this helpful.

Blessings!

Wednesday, May 6, 2026

How To Supplement Oracle Unified Audit With USERENV Context

I work with customers on a weekly basis on how to centralize Oracle AI Database user authentication, authorization and user life cycle management. One very important topic that often comes up is how to uniquely identify users actions for a shared user schema authentication setup.  This enables database administrators to have a tamper proof forensic trail to identify who did what when on the database

The normal method for identifying users in the Oracle AI database unified audit log of 19c and newer database versions is to the DBUSERNAME or CURRENT_USER fields of the unified audit log.




For example, the following query shows who (DBUSERNAME) performed which action (ACTION_NAME):

SQL> SELECT EVENT_TIMESTAMP,ACTION_NAME,dbusername from UNIFIED_AUDIT_TRAIL order by 1;

                   EVENT_TIMESTAMP            ACTION_NAME    DBUSERNAME
__________________________________ ______________________ _____________
06-MAY-26 02.22.11.707376000 PM    AUDIT                  SYSTEM       
06-MAY-26 02.23.17.545825000 PM    CREATE AUDIT POLICY    SYSTEM       
06-MAY-26 02.23.31.787023000 PM    AUDIT                  SYSTEM       
06-MAY-26 02.23.46.212854000 PM    LOGON                  ALLDBUSERS   
06-MAY-26 02.23.46.216907000 PM    ALTER SESSION          ALLDBUSERS   
06-MAY-26 02.23.46.319741000 PM    SELECT                 ALLDBUSERS   
06-MAY-26 02.23.46.320954000 PM    SELECT                 ALLDBUSERS    
06-MAY-26 02.23.46.321219000 PM    LOGON                  JSMITH

However, the shared user schema ALLDBUSERS represents a group of users rather than an individual user.  There is supplemental information available to uniquely identify users within the shared user schema from information in the SYS_CONTEXT USERENV data including AUTHENTICATED_IDENTITY and ENTERPRISE_IDENTITY.  These additional fields can be added to the APPLICATION_CONTEXTS field of the unified audit record with the following:

SQL> AUDIT CONTEXT NAMESPACE userenv ATTRIBUTES AUTHENTICATED_IDENTITY, ENTERPRISE_IDENTITY

If we add APPLICATION_CONTEXTS to the output of the audit log, we see that additional context:

SQL> SELECT EVENT_TIMESTAMP,ACTION_NAME,dbusername,APPLICATION_CONTEXTS from UNIFIED_AUDIT_TRAIL order by 1;
                   EVENT_TIMESTAMP    ACTION_NAME    DBUSERNAME                                                                                                          APPLICATION_CONTEXTS 
__________________________________ ______________ _____________ _____________________________________________________________________________________________________________________________ 
06-MAY-26 03.59.13.290254000 PM    LOGON          ALLDBUSERS    (USERENV,AUTHENTICATED_IDENTITY=dbuser@DBAuthDemo.com); (USERENV,ENTERPRISE_IDENTITY=9608cae1-95a9-493d-af94-f4d36d9ba633)    
06-MAY-26 03.59.42.992825000 PM    CREATE USER    ALLDBUSERS    (USERENV,AUTHENTICATED_IDENTITY=dbuser@DBAuthDemo.com); (USERENV,ENTERPRISE_IDENTITY=9608cae1-95a9-493d-af94-f4d36d9ba633)    
06-MAY-26 03.59.44.661566000 PM    LOGOFF         ALLDBUSERS    (USERENV,AUTHENTICATED_IDENTITY=dbuser@DBAuthDemo.com); (USERENV,ENTERPRISE_IDENTITY=9608cae1-95a9-493d-af94-f4d36d9ba633) 
  

From the above output from the unified audit log, we can now identify the user by their Entra ID user principal name (dbuser@DBAuthDemo.com) and their Entra ID unique user ID (9608cae1-95a9-493d-af94-f4d36d9ba633).

We can present this data a little more clearly with the application of regular expression manipulation.

SQL> SELECT EVENT_TIMESTAMP AS TIMESTAMP,ACTION_NAME AS OPERATION,dbusername AS USERNAME,REGEXP_SUBSTR(APPLICATION_CONTEXTS, 'AUTHENTICATED_IDENTITY\s*=\s*([^,; \)]+)', 1, 1, 'i', 1) as entra_upn from UNIFIED_AUDIT_TRAIL order by 1;

                         TIMESTAMP      OPERATION      USERNAME                ENTRA_UPN 
__________________________________ ______________ _____________ ________________________ 
             
06-MAY-26 03.58.59.012149000 PM    SELECT         SYSTEM        SYSTEM                   
06-MAY-26 03.58.59.012404000 PM    SELECT         SYSTEM        SYSTEM                   
06-MAY-26 03.59.13.290254000 PM    LOGON          ALLDBUSERS    dbuser@DBAuthDemo.com    
06-MAY-26 03.59.42.992825000 PM    CREATE USER    ALLDBUSERS    dbuser@DBAuthDemo.com    
06-MAY-26 03.59.44.661566000 PM    LOGOFF         ALLDBUSERS    dbuser@DBAuthDemo.com
    

This concept can be extended to include other SYS_CONTEXT USERENV content such as cryptographic connection details.  I'll save that for another day.

As a bonus, the EntraID user's UPN is available by default in the legacy audit log in comment_text. Here is an example search:

SQL> select extended_timestamp, STATEMENT_TYPE, db_user, REGEXP_SUBSTR(comment_text, 'AZURE_USER\s*=\s*([^,; \;]+)', 1, 1, 'i', 1) as azure_upn FROM dba_common_audit_trail;

                    EXTENDED_TIMESTAMP    STATEMENT_TYPE       DB_USER                AZURE_UPN 
______________________________________ _________________ _____________ ________________________ 
06-MAY-26 07.54.56.115998000 PM GMT    LOGON             SYSTEM                                 
06-MAY-26 07.57.23.830030000 PM GMT    LOGON             ALLDBUSERS    dbuser@DBAuthDemo.com    
06-MAY-26 07.57.24.324858000 PM GMT    SELECT            ALLDBUSERS                                

If no data is returned, you will need to add an audit policy.  For example:

$ORACLE_HOME/bin/sqlplus system@pdb1_ssl
SQL> audit create session;                                


I hope you find this helpful and beneficial.

Blessings

Wednesday, March 25, 2026

Linux Entra ID Authentication Integration Options



In recent months, I've been asked by several customers what options exist for centralizing Linux authentication, authorization and user life cycle management with Microsoft Entra ID integration.  This would enable end users to connect via the secure shell (ssh) to Linux hosts using their existing Entra ID credentials. Unfortunately, the short answer is ... not enough. Based on my research as of March, 2026 there are three options that use an intermediate broker or server to provide indirect authentication against Entra ID.  However, the direct solution that most customers desire through the System Security Services Daemon (SSSD) is still in progress.  The target Red Hat/Oracle/CentOS version for the native SSSD solution is 10.

The in-direct connect option is through Microsoft Azure command line tool (az ssh) by way of the Azure Arc agent.  Let's look at each method to understand pros and cons of each.









Himmelblau
Himmelblau is an open source project that operates as an identity broker to Entra ID via the himmelblaud daemon.  This is the most comprehensive solution available thus far.
  • Type: Password + PIN verification authentication or just Microsoft HELLO PIN
  • Project: https://himmelblau-idm.org
  • GitHub Repo: https://github.com/himmelblau-idm/himmelblau
  • Walkthrough: https://www.youtube.com/watch?v=wCibnqVQ_bs
  • Pros: 
    • Users and groups can be managed in Entra ID 
    • Users can use standard ssh/putty into Linux hosts with this integration
    • Supports Entra ID MFA
    • Directly integrated into SuSE Linux and works for SSH and GDM
  • Cons:
    • Does not provide native OAuth2 authentication with Entra ID
    • Not officially supported by other major Linux vendors such as Red Hat and Oracle
    • Not an officially vendor supported solution outside of SuSE Linux
    • Already has a few security vulnerabilities (CVE-2025-54781, CVE-2026-31957, CVE-2026-31979, ...) 
    • It is not yet clear if this solution fully supports Entra ID conditional access policies
    • May require additional cost for license and/or support

Red Hat IPA Federation To Entra ID
This option extends Red Hat's IPA (Identity, Policy and Audit) solution by way of OpenID Connect (OIDC) to Entra ID where Entra ID is an identity provider (IdP) to IPA.  IPA is effectively an authentication and authorization broker to either internal or external identity providers.  The method of authentication between the Linux host and IPA appears to be either Kerberos or LDAP BIND even though the authentication between the IPA server and Entra ID is OIDC.
  • Type: Password, ssh key, and/or MFA
  • Support solution pages:
    • Login to RHEL using Microsoft Entra ID - https://access.redhat.com/solutions/7076188
    • Configure IdM to use Entra ID (Azure AD) as external IdP - https://access.redhat.com/solutions/7073948
  • Pros:
    • Users and groups can be managed in Entra ID 
    • Users can use standard ssh/putty into Linux hosts with this integration 
    • Officially supported by Red Hat
    • Enables use of identities in Entra ID
  • Cons:
    • Does not provide native OAuth2 authentication with Entra ID
    • Not officially supported by other Linux vendors
    • It is not yet clear if this solution fully supports Entra ID conditional access policies
    • Is not yet clear if solution supports Entra ID MFA
    • May require additional cost for license and/or support

Kerberos Domain Join With Microsoft Entra Domain Services
Microsoft's Entra Domain Services (e.g. managed AD Kerberos Domain Servers) can be used as an intermediary authentication to Entra ID via Kerberos authentication.
  • Type: Kerberos ticket
  • Kerberos Join to managed AD - https://learn.microsoft.com/en-us/entra/identity/domain-services/join-rhel-linux-vm?tabs=rhel
  • Pros:
    • Users and groups can be managed in Entra ID 
    • Users can use standard ssh/putty into Linux hosts with this integration
    • Does not support Entra ID MFA
  • Cons:
    • Does not provide native OAuth2 authentication with Entra ID
    • It is not yet clear if this solution fully supports Entra ID conditional access policies
    • May require additional cost for license and/or support

Azure Arc Enabled SSH Authentication
Azure Arc is a Microsoft Azure cloud service that provides a variety of host management capabilities such as updating the operating system, collecting log data, and providing proxied ssh to the hose via the Azure command line tool (az).  For example, once a Linux host is registered with Azure Arc, configured with Azure AD ssh Login software, specified the ssh port and the AADSSHLoginForLinux extension has been enabled, an Entra ID user can authenticate to the Linux host from the Azure console command prompt or any host running the Azure command line tool (e.g. az ssh arc ...).  Here is the basic workflow:
1. Login to Entra ID via the Azure command line tool:

az login

2. Use the Azure command line tool to remotely login to a Linux host:

az ssh arc --resource-group <az_resource_group> --name <linux_host> 

Note that this solution does not enable the standard ssh command to be able to authenticate using Entra ID integration. It only applies to authenticating through the Azure command line tool.
    • Type: Whatever is prescribed by Entra ID password and conditional access policies
    • SSH access to Azure Arc-enabled servers - https://learn.microsoft.com/en-us/azure/azure-arc/servers/ssh-arc-overview
    • Arc-enabled servers: Configuration and remote access - https://learn.microsoft.com/en-us/azure/azure-arc/servers/security-machine-configuration
    • Sign in to a Linux virtual machine in Azure by using Microsoft Entra ID and OpenSSH - https://learn.microsoft.com/en-us/entra/identity/devices/howto-vm-sign-in-azure-ad-linux
    • Pros:
      • Users and groups can be managed in Entra ID 
      • Provides native OAuth2 authentication with Entra ID
      • Supports Entra ID MFA
      • Supports Entra ID conditional access policies
      • Can ssh to the host without need of direct or indirect (e.g. VPN) connection to the Linux host
    • Cons:
      • Can only ssh to Linux hosts via the Azure command line tool
      • Users cannot use standard ssh/putty into Linux hosts
      • Linux hosts must run an local agent to facilitate authentication to the host
      • Azure agent will require additional resources and compute to facilitate connections to the host

    System Security Services Daemon (SSSD) Entra ID Integration
    The solution that most customers desire is native support of Entra ID integration by the SSSD service.  This solution appears to be in progress with a tentative target for inclusion in Red Hat/Oracle Linux 10.
    The SSSD 2.11.0 release notes announces the introductory of support of Entra ID integration through the sssd-idp package:
    "New generic id and auth provider for Identity Providers (IdPs), as a start Keycloak and Entra ID are supported."

    However, testing of this new capability indicates that the requisite libsss_idp.so library is not yet available. This is made evident by the following error in the /var/log/sssd/ssd_<domain>.log file:

    Unable to load module [idp] with path [/usr/lib64/sssd/libsss_idp.so]: /usr/lib64/sssd/libsss_idp.so: cannot open shared object file: No such file or directory

     Once SSSD finally and fully supports native OAuth2 integration with Entra ID, I expect that will support MFA and Entra ID Conditional Access Policies. However, time will tell. Here are references to this project:

    • Type: Whatever is prescribed by Entra ID password and conditional access policies
    • SSSD Identity Provider (IdP) Support - https://sssd.io/docs/idp/idp-introduction.html
    • sssd-idp man page - https://www.mankier.com/5/sssd-idp
    • Pros:
      • Users and groups can be managed in Entra ID 
      • Provides native OAuth2 authentication with Entra ID
      • Supports Entra ID MFA
      • Supports Entra ID conditional access policies
      • Can ssh to Linux hosts with standard ssh/putty tools
    • Cons:
      • Not yet fully implemented
    I hope you find this information helpful and useful.

    Blessings!


    Wednesday, March 18, 2026

    ODB Entra ID Integration For JDBC-thin Applications

    Centralizing Oracle AI Database Authentication, Authorization, and User Lifecycle Management is a great way to improve operational efficiency and improve security posture through the addition of multi-factor authentication (MFA).  For C-based Oracle Call Interface (OCI) and JDBC-thick driver clients, this is enabled through the Oracle instant client or Oracle full client applications.  However, JDBC-thin driver based applications such as SQL Developer, SQLcl and many others require the ojdbc-extensions libraries and all dependencies from the GitHub project https://github.com/oracle/ojdbc-extensions to enable Entra ID integration. In my previous blog post on Entra ID Integration For SQLDeveloper, I provided a sample set of ojdbc-extensions and dependencies as a standalone downloadable zip file.  Thanks to the great work of the Oracle JDBC team, there is a new command (get-deps) that enables downloading all of the extensions and requisites through the OJDBC driver.

    Lets say that you want to evaluate the next stable version of ojdbc-extensions driver version 1.0.5 with SQL Developer 24.3.1.  The following sequence guides you through that setup. Note that the same sequence can be applied to the previous ojdbc-extensions version 1.0.4 as well as the upcoming version 1.0.6 and future versions.

    1. Download 23.26.1 (or newer) of the Oracle JDBC-thin library from Maven repository or Oracle AI Database instant client.

    Oracle JDBC-thin library from Maven:

    curl -sko ojdbc11.jar https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc11/23.26.1.0.0/ojdbc11-23.26.1.0.0.jar

    Alternatively, the JDBC-thin library is included with the Oracle instant client at:
     https://www.oracle.com/database/technologies/instant-client/downloads.html

    2. Extract the Oracle instant client. In my case, I extracted into C:\u01\app\instantclient_23_26_1

    3. Download the desired 1.0.5 version of ojdbc-extensions into a version specific directory:

    cd C:
    cd \u01\app\instantclient_23_26_1
    java -jar ojdbc11.jar get-deps --coords com.oracle.database.jdbc/ojdbc-provider-azure/1.0.5 --path C:\u01\app\ojdbc-extensions-1.0.5

    If this fails, you may need also need to load private certificate chain for Web Application Firewall (WAF) SSL/TLS termination or SSL/TLS offloading service into the Java cacerts truststore:

    keytool -import -trustcacerts -alias privateca -keystore cacerts -file "C:\Users\dbUser\privateca.cer"



    4. Produce the output with Windows PowerShell that will be needed to update the SQL Devleoper product.conf configuration file located in <home>\AppData\Roaming\sqldeveloper\<version>:

    Get-ChildItem -Path "C:\u01\app\ojdbc-extensions-1.0.5" -Include "*.jar" -Recurse -Name -Force | ForEach-Object { Add-Content -Path C:\u01\app\ojdbc-extensions-1.0.5\product.txt  -Value "AddJavaLibFile C:\u01\app\ojbc-extensions-1.0.5\$_"}


    5. Stop SQL Developer

    6. Make a backup copy of the existing SQL Developer product.conf config file in <home>\AppData\Roaming\sqldeveloper\<version>.

    7. Update the <home>\AppData\Roaming\sqldeveloper\<version>\product.conf configuration file replacing all AddJavaLibFile references with those resulting from step 4 above.  Here was the resulting output for this iteration of these commands. Note that your execution may result in different library versions because they can change over time.

    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\accessors-smart-2.5.1.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\asm-9.6.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-core-1.54.1.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-core-http-netty-1.15.7.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-data-appconfiguration-1.7.3.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-identity-1.14.2.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-json-1.3.0.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-security-keyvault-secrets-4.9.1.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\azure-xml-1.1.0.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\content-type-2.3.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jackson-annotations-2.17.2.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jackson-core-2.17.2.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jackson-databind-2.17.2.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jackson-datatype-jsr310-2.17.2.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jcip-annotations-1.0-1.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jna-5.13.0.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\jna-platform-5.13.0.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\json-smart-2.5.1.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\lang-tag-1.7.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\msal4j-1.17.2.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\msal4j-persistence-extension-1.3.0.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-buffer-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-codec-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-codec-dns-4.1.112.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-codec-http-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-codec-http2-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-codec-socks-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-common-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-handler-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-handler-proxy-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-resolver-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-resolver-dns-4.1.112.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-resolver-dns-classes-macos-4.1.112.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-resolver-dns-native-macos-4.1.112.Final-osx-x86_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-tcnative-boringssl-static-2.0.69.Final-linux-aarch_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-tcnative-boringssl-static-2.0.69.Final-linux-x86_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-tcnative-boringssl-static-2.0.69.Final-osx-aarch_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-tcnative-boringssl-static-2.0.69.Final-osx-x86_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-tcnative-boringssl-static-2.0.69.Final-windows-x86_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-tcnative-classes-2.0.69.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-transport-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-transport-classes-epoll-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-transport-classes-kqueue-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-transport-native-epoll-4.1.115.Final-linux-x86_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-transport-native-kqueue-4.1.115.Final-osx-x86_64.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\netty-transport-native-unix-common-4.1.115.Final.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\nimbus-jose-jwt-9.40.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\oauth2-oidc-sdk-11.18.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\ojdbc-provider-azure-1.0.4.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\ojdbc-provider-common-1.0.4.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\ojdbc8-23.7.0.25.01.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\oraclepki-23.7.0.25.01.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\reactive-streams-1.0.4.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\reactor-core-3.4.41.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\reactor-netty-core-1.0.48.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\reactor-netty-http-1.0.48.jar
    AddJavaLibFile C:\u01\app\ojdbc-extensions-1.0.5\slf4j-api-1.7.36.jar


    8. Start SQL Developer and test Entra ID integrated database authentication

    Try it out and let me know if it works for you.

    Blessings!

    Wednesday, February 18, 2026

    TLS Cert Rotation Lifetime Compression

    One way that vendors and customers are forcing the improvement of security posture of web public key infrastructure (PKI) is through progressively shortening the certificate rotation lifetime of the TLS Baseline Requirements (TBRs).  Apple led a charge in 2025 toward this end through a CA/Browser (CA/B) Forum Ballot SC-081v3 initiative.  The measure was overwhelmingly approved and certificate authorities and browser vendors have begin preparations for the eventual support of the following TLS certificate lifetime shortening guidelines:

    Root CA Validity
    Between 2922 days (approximately 8 years) and 9132 days (approximately 25 years)

    Short-lived Subscriber Certificates
    Certificates issued between March 15, 2024 and March 15, 2026 have maximum validity period of 10 days
    Certificates issued after March 15, 2026 have a maximum validity period of 7 days

    Domain Name and IP Address (Subject Alternative Name [SAN]) validation data reuse periods
    Certificates issued before March 15, 2026 have a validity period of up to 398 days
    Certificates issued between March 15, 2026 and March 15, 2027 have a validity period of up to 200 days
    Certificates issued between March 15, 2027 and March 15, 2029 have a validity period of up to 100 days
    Certificates issued after March 15, 2029 have a validity period of up to 10 days

    Subscriber Certificate Subject Identity Information and validation data reuse periods
    Certificates issued before March 15, 2026 have validity window of up to 825 days
    Certificates issued on or after March 15, 2026 have a validity window of up to 398 days

    Subscriber Certificate operational periods and key pair usage periods
    Certificates issued before March 15, 2026 have a validity period of up to 398 days
    Certificates issued between March 15, 2026 and March 15, 2027 have a validity period of up to 200 days
    Certificates issued between March 15, 2027 and March 15, 2029 have a validity period of up to 100 days
    Certificates issued after March 15, 2029 have a validity period of up to 47 days

    What does this mean to you?  Enterprises need to work through automating detection, validation, issuing and deploying certificates across their infrastructure as soon as possible.  There are many ways to detect certificate but the easiest is by using the openssl command to check the certificate validity period of a target <host>:<port>.  For example: 

    echo|openssl s_client -connect <database_host>:2484 2>&1 | openssl x509 -noout -text|egrep "^Certificate:|^        Issuer:|^        Subject|^        Validity|^            Not "
    Certificate:
            Issuer: C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
            Validity
                Not Before: Oct 27 17:49:47 2024 GMT
                Not After : Nov  6 16:19:28 2025 GMT
            Subject: CN = hrdb.dbauthdemo.com
            Subject Public Key Info:

    Cloud providers such as Oracle Cloud Infrastructure (OCI) include services such as Cloud Guard for some certificates.

    Automating the issuing of certificate renewal and certificate retrieval is available via API for most public certificate authorities.

    Automating of rotating the old certificate out and the new one into a given product is product specific.

    Here are some great references and commentaries on these TLS certificate lifetime reductions:

    1. DigitCert: TLS Certificate Lifetimes Will Officially Reduce to 47 days

    2.  DigiCert: How Short-Lived Certificates Improve Certificate Trust


    I hope you find this information helpful.


    Blessings!


    Tuesday, November 18, 2025

    How To Make Database Client Certificate Trust Store

    While helping out a customer with Oracle Database TLS configuration, they realized that they didn't have a trust store for their database clients.  I shared that there is an easy way of creating the client trust store all necessary store formats with openssl. Here's how to accomplish for Oracle wallet, Java JKS and PKCS trust store formats.

    Note in all of the following examples, you will want to use your own password. For these examples, I've used Oracle123.

    Get Cert Chain

    The first thing to do is capture the cert-chain into a PEM file with openssl.  

    OpenSSL Export Method

    The easiest way to do this is via the openssl command with:

    timeout 5 openssl s_client -connect <db_host>:2484 -showcerts > ~/cert-chain.pem

    Standalone Oracle Database Export Method

    For a standalone Oracle database, you can use orapki to export the certificate.

    Setup the environment variables with:

    export ORACLE_BASE="/u01/app/oracle/19c"
    export ORACLE_HOME="$ORACLE_BASE/dbhome_1"
    export WALLET_ROOT="$ORACLE_BASE/wallet_root"
    PATH=$ORACLE_HOME/bin:$PATH


    Lookup the CN= value of the CA cert chain or if self signed, the certificate subject with:

    orapki wallet display -nologo -wallet $WALLET_ROOT/rootca_wallet/tls -complete


    Export the certificate using the CN= value of the previous command for <cnvalue> with:

    orapki wallet export -wallet $WALLET_ROOT/rootca_wallet/tls -pwd Oracle123 -dn <cnvalue> -cert ~/cert-chain.pem

    Exadata Export Method

    For Oracle Exadata systems, you can lookup the current certificate CN value via orapki command with:

    sudo su - grid -c "orapki wallet display -nologo -wallet /var/opt/oracle/dbaas_acfs/grid/tcps_wallets -complete"


    Then, use the orapki command to export the certificate to a file using the CN= value of the certificate returned from the previous command as an input (<cnvalue>) to the the following command:

    sudo su - grid -c "orapki wallet export -nologo -wallet /var/opt/oracle/dbaas_acfs/grid/tcps_wallets -dn CN=<cnvalue> -cert ~/cert-chain.crt"


    Then, you can view the contents of the certificate file as the grid user with:

    sudo cat ~grid/cert-chain.crt

    Client Wallet

    For Oracle database clients using the Oracle Call Interface (OCI) and JDBC-thick drivers, you will need an Oracle wallet containing the certificate chain.  Here's how to create the client wallet with Oracle's orapki command:

    mkdir clientwallet
    cd clientwallet
    orapki wallet create -wallet . -pwd Oracle123 -auto_login
    orapki wallet add -wallet . -pwd Oracle123 -trusted_cert -cert ~/cert-chain.pem

    Display the contents of the Oracle wallet with:

    orapki wallet display -wallet . -complete

    Java Key Store (JKS) Trust Store

    For JDBC-thin clients they will need either a JKS or PKCS12 trust store.  Here is how to create the JKS trust store from the certificate: 

    keytool -importcert -storepass Oracle123 -keystore clientstore.jks -alias root-ca-chain -file ~/cert-chain.pem -noprompt

    Display the contents of the JKS trust store:

    keytool -list -keystore clientstore.jks  -storetype JKS  -storepass Oracle123 -v

    PKCS12 Trust Store

    For JDBC-thin clients they will need either a JKS or PKCS12 trust store.  Here is how to create the PKCS12 trust store from the certificate: 

    keytool -importcert -storepass Oracle123 -storetype PKCS12 -keystore clientstore.p12 -alias root-ca-chain -file ~/cert-chain.pem -noprompt

    Display the contents of the PKCS12 trust store:

    keytool -list -storetype PKCS12 -keystore clientstore.p12 -storepass Oracle123 -v

    I hope this was helpful and informative.

    Blessings!