Thursday, July 9, 2026

OCI IAM: Token Based Oracle AI Database Authentication


As many Oracle customers have continued to expand or move their Oracle AI Database estate from on premises to to multiple clouds including @OCI Autonomous, @OCI Base Database Service, @Azure, @AWS, and @Google, they ask how they can increase security posture and simplify user interaction with all of these databases regardless of where they live. One answer is to use passwordless authentication through Oracle Cloud Identity & Access Management (OCI IAM) integration via token-based authentication. OCI IAM integration offers three methods of database user authentication:
1. Password Verifier Authentication
2. DB Access Token (db-token) Authentication
3. Interactive OAuth2 Flow

In this post, I'll walk you through how to setup and test the DB Access Token (db-token) authentication method.

It is important to note that OCI IAM authentication only applies to Oracle AI Database servers with an Oracle Cloud Identifier (OCID).  Per the Oracle AI Database 26ai Security Guide, supported database deployments include:
  • Autonomous Database Serverless
  • Autonomous Database on Dedicated Exadata Infrastructure
  • Exadata Cloud@Customer Infrastructure
  • Exadata Cloud Service on Dedicated Infrastructure
  • Exadata Cloud Service on Cloud@Customer Infrastructure
  • Base Database Service
  • Exadata dedicated and Autonomous on dedicated Exadata @Azure, @AWS, @Google
Notably, OCI IAM integration does not apply to:
  • Standalone database server on servers, virtual machines, or cloud compute
  • Database server on Windows, AIX, Solaris or HPUX
  • Exadata on premises
OCI IAM authentication in all of its forms was introduced with Oracle AI Database versions 19.13 and 23.3 (now 26ai).

OCI IAM Integration Setup

Here is the outline for setting up OCI IAM database authentication integration.

1. OCI IAM Users, Groups, And Memberships

Create OCI IAM groups that will be used for shared user schema and database roles and add user to the shared user schema group and all groups that will map to database roles.
 
In this example, we create the following OCI IAM groups:
  • allDBUsers for the shared user schema
  • dbMinPriv for minimum privilege database users
  • dbMaxPriv for maximum privilege database users

This is just an example to show least and most privilege. You will come up with your own set of database roles according to the needs of your environment, business units and applications.

2. OCI IAM Policies

Add OCI IAM policies that grant use of the database-connections, database-family, and autonomous-database-family resources by tenancy or compartment to each of the OCI IAM groups specified (allDBUsers, dbMinPriv and dbMaxPriv).  There are typically two approaches that customers take to these policies. They either scope to the entire tenancy or to individual compartments within the tenancy.

Here is an example of granting OCI IAM groups to use the database-connections, database-family, and autonomous-database-family resources.

allow group MyIdentityDomain/allDBUsers to use database-connections in tenancy
allow group
MyIdentityDomain/dbMinPriv to use database-connections in tenancy
allow group
MyIdentityDomain/dbMaxPriv to use database-connections in tenancy

allow group
MyIdentityDomain/allDBUsers to use database-family in tenancy
allow group
MyIdentityDomain/dbMinPriv to use database-family in tenancy
allow group
MyIdentityDomain/dbMaxPriv to use database-family in tenancy

allow group
MyIdentityDomain/allDBUsers to use autonomous-database-family in tenancy
allow group
MyIdentityDomain/dbMinPriv to use autonomous-database-family in tenancy
allow group
MyIdentityDomain/dbMaxPriv to use autonomous-database-family in tenancy

Here is the same policy applied to a specific compartment "development:dev_dbs".

allow group MyIdentityDomain/allDBUsers to use database-connections in compartment development:dev_dbs
allow group
MyIdentityDomain/dbMinPriv to use database-connections in compartment development:dev_dbs
allow group
MyIdentityDomain/dbMaxPriv to use database-connections in compartment development:dev_dbs

allow group
MyIdentityDomain/allDBUsers to use database-family in compartment development:dev_dbs
allow group
MyIdentityDomain/dbMinPriv to use database-family in compartment development:dev_dbs
allow group
MyIdentityDomain/dbMaxPriv to use database-family in compartment development:dev_dbs

allow group
MyIdentityDomain/allDBUsers to use autonomous-database-family in compartment development:dev_dbs
allow group
MyIdentityDomain/dbMinPriv to use autonomous-database-family in compartment development:dev_dbs
allow group
MyIdentityDomain/dbMaxPriv to use autonomous-database-family in compartment development:dev_dbs

Note in both examples that the group is prefaced by the identity domain (MyIdentityDomain/). This scopes the authentication to only the groups of this identity domain. 

3. Enable OCI IAM In Database

Configure database server for OCI IAM integration Autonomous Database.  Note that this will need to be applied to each container (CDB) or pluggable (PDB) database.

BEGIN
   DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION(
      type => 'OCI_IAM' );
END;
/

ALTER SYSTEM SET IDENTITY_PROVIDER_TYPE=OCI_IAM SCOPE=BOTH;
ALTER SYSTEM RESET IDENTITY_PROVIDER_CONFIG SCOPE=BOTH;

Confirm the OCI IAM database configuration has been applied. Note that the identity_provider_type should now be set to OCI_IAM and the identity_provider_config should not have a value.
SQL> SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME='identity_provider_type';
NAME                      VALUE      
_________________________ __________ 
identity_provider_type    OCI_IAM    
SQL> SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME='identity_provider_config';
NAME                        VALUE    
___________________________ ________ 
identity_provider_config             

4. Configure Database Users And Roles

Configure shared or exclusive user schema and database roles that map to OCI IAM groups and grant relevant privileges to the database roles.
CREATE USER allDbUsers IDENTIFIED GLOBALLY AS 'IAM_GROUP_NAME=MyIdentityDomain/allDbUsers';

CREATE ROLE dbMinPriv IDENTIFIED GLOBALLY AS 'IAM_GROUP_NAME=MyIdentityDomain/dbMinPriv';

GRANT CREATE SESSION to dbminpriv;
CREATE ROLE dbMaxPriv IDENTIFIED GLOBALLY AS 'IAM_GROUP_NAME=MyIdentityDomain/dbMaxPriv';

GRANT pdb_dba, CREATE SESSION to dbmaxpriv;


5. Get Oracle Client Wallet

Because the OCI IAM integration requires an encrypted TLS connection between the database client and server, you will need to copy the client wallet to the host where the client application resides. Here is where I put the wallet on my Windows system.
C:\client_wallet

6. TNS Record For Token Based Authentication

Create a TNS record in the tnsnames.ora client name resolution configuration file that includes PROTCOL=TCPS, PORT=<secure_port>, WALLET_LOCATION=<path_of_client_wallet> and TOKEN_AUTH=OCI_TOKEN.
For example:

DEVDB_PDB1_SSL_TOKEN=
 (DESCRIPTION=
    (ADDRESS=(PROTOCOL=TCPS)(HOST=devdb-scan.mysubnet.odswest.oraclevcn.com)(PORT=2484))
    (SECURITY=
      (SSL_SERVER_DN_MATCH=TRUE)
      (WALLET_LOCATION=C:\client_wallet)
      (TOKEN_AUTH=OCI_TOKEN)
    )
    (CONNECT_DATA=
      (SERVER=DEDICATED)
      (SERVICE_NAME=devdb_pdb1.mysubnet.odswest.oraclevcn.com)
    )
  )


7. Authenticate To OCI IAM

Use the OCI IAM command line tool (oci) to authenticate against OCI IAM using the a specific OCI command line profile (DBUSER) and specify the OCI tenancy name, region and identity domain name.  This will pop-up a browser window to your OCI IAM tenancy to login.

oci session authenticate --profile-name DBUSER --tenancy-name <oci_tenancy_name> --region <oci_region> --identity-provider-name <oci_identity_domain_name> 
    Please switch to newly opened browser window to log in!
    You can also open the following URL in a web browser window to continue:
https://login.us-phoenix-1.oraclecloud.com/v1/oauth2/authorize?action=login...
Service
    Completed browser authentication process!
Config written to: /Users/dbuser/.oci/config

Note that a new DBUSER profile may have been added to your $HOME/.oci/config configuration file that looks similar to the following.

[DBUSER]
fingerprint=<unique_fingerprint>
key_file=/<users_home_directory>/.oci/sessions/DBUSER/oci_api_key.pem
tenancy=<oci_tenancy_ocid>
region=<oci_region>
security_token_file=/<users_home_directory>/.oci/sessions/DBUSER/token


8. Request Access Token (db-token)

Use the OCI IAM command line tool (oci) to request an access token (db-token) from OCI IAM.

oci iam db-token get --profile DBUSER --auth security_token --scope urn:oracle:db::id::<oci_compartment_ocid>::*

Private key written at /Users/dbuser/.oci/db-token/oci_db_key.pem
db-token written at: /Users/dbuser/.oci/db-token/token
db-token is valid until 2026-07-09 12:32:09
db-token is valid until 2026-07-09 12:32:09

IMPORTANT NOTES:

  • The access token (db-token) will expire after 1 hour. Therefore, you will need to get the token again after the initial token expires with the "oci iam db-token get ..." command again.
  • The scope parameter in the above example presumes that the IAM policy has restricted access to a specific OCI compartment.  If your OCI IAM policy is applied at the tenancy rather than compartment level, then the --scope ... parameter is not necessary.


9. Test Each Client Application

Here is how I tested SQL Developer, SQLcl and SQL*Plus.

a. SQL Developer
Open SQL Developer and add a new connection and connect with that new connection. Here is a sample configuration from my lab environment.

Name: DEVDB_PDB1_SSL_Token
Database Type: Oracle
Authentication Type: OS
Connection Type: TNS
Network Alias: DEVDB_PDB1_SSL_TOKEN

 


b. SQLcl

sql -thin /@DEVDB_PDB1_SSL_TOKEN


c. SQL*Plus

sqlplus /@DEVDB_PDB1_SSL_TOKEN


Once authenticated with any of the above methods, you can reveal details about the USERENV system context.

SQL> show user;
USER is "ALLDBUSERS"

SQL> SELECT SYS_CONTEXT ('USERENV','CURRENT_USER') FROM DUAL;

SYS_CONTEXT('USERENV','CURRENT_USER')
--------------------------------------------------------------------------------
ALLDBUSERS

SQL> SELECT SYS_CONTEXT ('USERENV','AUTHENTICATED_IDENTITY') FROM DUAL;

SYS_CONTEXT('USERENV','AUTHENTICATED_IDENTITY')
--------------------------------------------------------------------------------
oracleidentitycloudservice/dbuser@dbauthdemo.com

SQL> SELECT SYS_CONTEXT ('USERENV','ENTERPRISE_IDENTITY') FROM DUAL;

SYS_CONTEXT('USERENV','ENTERPRISE_IDENTITY')
--------------------------------------------------------------------------------
<user_ocid>

SQL> SELECT SYS_CONTEXT('USERENV', 'NETWORK_PROTOCOL') FROM DUAL;

SYS_CONTEXT('USERENV','NETWORK_PROTOCOL')
--------------------------------------------------------------------------------
tcps

SQL> SELECT SYS_CONTEXT('USERENV', 'AUTHENTICATION_METHOD') FROM DUAL;

SYS_CONTEXT('USERENV','AUTHENTICATION_METHOD')
--------------------------------------------------------------------------------
TOKEN_GLOBAL

SQL> SELECT SYS_CONTEXT('USERENV', 'IDENTIFICATION_TYPE') FROM DUAL;

SYS_CONTEXT('USERENV','IDENTIFICATION_TYPE')
--------------------------------------------------------------------------------
GLOBAL SHARED


I hope you find this helpful.


Blessings!


No comments: