<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Vignan. V on Medium]]></title>
        <description><![CDATA[Stories by Vignan. V on Medium]]></description>
        <link>https://medium.com/@vignan.v?source=rss-3861953a94b4------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*3yZ6cTcaqfcL3p4w0NugeA.jpeg</url>
            <title>Stories by Vignan. V on Medium</title>
            <link>https://medium.com/@vignan.v?source=rss-3861953a94b4------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 06 May 2026 17:26:49 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@vignan.v/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[OCI SDK Authentication Methods Supported in Python-oracledb]]></title>
            <link>https://medium.com/oracledevs/oci-sdk-authentication-methods-supported-in-python-oracledb-6b614a8f4223?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/6b614a8f4223</guid>
            <category><![CDATA[token-based-auth]]></category>
            <category><![CDATA[python-oracledb]]></category>
            <category><![CDATA[oracle-ai-database]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[oci-sdk-auth]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Tue, 05 May 2026 17:40:32 GMT</pubDate>
            <atom:updated>2026-05-05T17:40:32.780Z</atom:updated>
            <content:encoded><![CDATA[<h4>Summary of supported OCI SDK authentication methods in Python-oracledb</h4><figure><img alt="Image demonstrating the OCI SDK authentication methods supported in Python-oracledb." src="https://cdn-images-1.medium.com/max/1024/1*CL58KYzaV_WEI-32cfUlWA.jpeg" /><figcaption>Image generated by Oracle Generative Chat</figcaption></figure><h4>Key Takeaways</h4><ul><li>Python-oracledb supports multiple OCI SDK authentication methods, so you’re not locked into just one way of connecting, you can pick what fits your setup best.</li><li>The most common options you’ll come across are <strong>API keys, session tokens, instance principals, and resource principals</strong>, each with its own trade-offs.</li><li>API key-based authentication is still the simplest to get started with, but it involves managing config files and private keys locally.</li><li>Session tokens are a good step up for security, they’re temporary and expire automatically, which makes them useful for development and short-lived access.</li><li>Instance principals and resource principals remove the need to manage credentials entirely, making them a better fit for cloud-native or production workloads.</li><li>The nice part is that all of these can be used with python-oracledb through the auth_type parameter, so switching between them doesn’t require a complete rewrite of your code.</li></ul><p>The <a href="https://pypi.org/project/oracledb/">python-oracledb</a> driver supports several <a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm">OCI SDK authentication</a> methods to connect Python applications to Oracle Cloud Autonomous Databases. Each method has it’s own use cases and benefits. This post provides a quick overview and links to detailed tutorials for each of these authentication methods.</p><p>OCI SDK authentication methods rely on token-based authentication, where a secure token is generated and used instead of repeatedly sending credentials. These tokens represent an authenticated identity and are validated by OCI services to authorize requests. Different authentication methods vary in how these tokens are obtained and managed.</p><p>The following diagram provides a high-level view of how OCI SDK authentication methods interact with OCI <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/overview.htm">IAM</a> to obtain database access tokens (db-tokens), which are then used by the database client for secure authentication.</p><p>In all cases, the chosen authentication method is used to authenticate with IAM, which then issues a db-token. This token is passed to the database client (via file or API) and used in place of a password.</p><figure><img alt="IAM User or OCI Application Authenticating to an Oracle AI Database with an OCI IAM Token." src="https://cdn-images-1.medium.com/max/943/1*mJg7oBL9WxlUcwanJzIHuw.png" /><figcaption>IAM User or OCI Application Authenticating to an Oracle AI Database with an OCI IAM Token</figcaption></figure><p>For a detailed explanation of this flow, refer to the <a href="https://docs.oracle.com/en/database/oracle/oracle-database/26/dbseg/authenticating-and-authorizing-iam-users-oracle-dbaas-databases.html#GUID-8D203376-C302-4200-9DB0-8D96C98BF7E5">Oracle documentation</a>.</p><h3>Supported Authentication Methods in python-oracledb</h3><h4>API Key-Based Authentication</h4><p>With <a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm#sdk_authentication_methods_api_key">API key-based authentication</a>, you create a configuration file stored locally. The file contains your <em>user OCID, tenancy OCID, region, private key path</em>, and <em>fingerprint</em>.</p><p>This method results in a permanent configuration file on your machine, so it should be used only if you’re working from a secure network and are comfortable storing private keys locally.</p><p>In python-oracledb, <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/authentication_methods.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin">API key-based authentication</a> is supported in two flavours:</p><p><strong>ConfigFileAuthentication</strong> — Reads your <em>user, tenancy, fingerprint, key file</em>, and <em>region</em> from ~/.oci/config.</p><p><strong>SimpleAuthentication</strong> — A streamlined version where you provide minimal parameters directly.</p><p>For detailed setup steps and examples, refer to my <a href="https://medium.com/oracledevs/cloud-native-authentication-in-python-oracledb-using-oci-iam-tokens-96d73db59fe1">blog</a> on configuring API key-based authentication.</p><h4>Instance Principal Authentication</h4><p><a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm#sdk_authentication_methods_instance_principaldita">Instance principal authentication</a> allows an OCI compute instance, container, or function to make API calls without user credentials or a local configuration file.<br>Once the required resources and policies are set up, applications running on the instance can call Oracle Cloud Infrastructure services directly.</p><p>OCI automatically provides a short-lived token to the instance, which python-oracledb uses to <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/authentication_methods.html#instance-principal-authentication">authenticate</a> database connections securely.</p><p>This method is ideal for cloud-native workloads and automation, especially when storing API keys locally is not desirable.</p><p>You can explore this further in my <a href="https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-instance-principals-in-e213e1f40c44">blog</a> on Instance Principal authentication.</p><h4>Resource Principal Authentication</h4><p><a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm#sdk_authentication_methods_resource_principal">Resource principal authentication</a> allows OCI services such as Data Science notebooks, Functions, or OKE workloads to make API calls without user credentials or local configuration files.</p><p>Once the required dynamic groups and IAM policies are set up, applications running inside these services can directly access Oracle Cloud Infrastructure services.</p><p>OCI automatically provides short-lived tokens to the running resource, which python-oracledb can use to authenticate database connections securely.</p><p>This method is ideal for applications running in OCI-managed environments where there is no direct access to underlying compute instances and storing credentials is not practical.</p><p>You can learn more on it in my <a href="https://medium.com/@vignan.v/no-more-credentials-connect-to-oracle-autonomous-database-using-resource-principals-in-56f9735a0169">post</a> on Resource Principal authentication.</p><h4>Session Token-Based Authentication</h4><p><a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm#sdk_authentication_methods_session_token">Session token-based authentication</a> uses a local configuration file containing your <em>user OCID, tenancy OCID, region, private key path,</em> and a temporary<em> session token file path</em>.<br>The temporary session token expires after a short period (usually one hour) and provides quick, secure authentication without storing long-lived credentials.</p><p>In python-oracledb, <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/authentication_methods.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin">session token authentication</a> is supported in two flavors:</p><p><strong>SecurityToken — </strong>Uses the session profile from your OCI configuration file.</p><p><strong>SecurityTokenSimple</strong> — A streamlined version where configuration parameters are supplied via environment variables.</p><p>Python-oracledb reads the token and private key, builds a signer, and authenticates securely, without requiring a password.</p><p>This method is ideal for short-lived credentials, interactive sessions.</p><p>Learn more about setup and usage in my <a href="https://medium.com/@vignan.v/using-oci-session-token-authentication-with-python-oracledb-ba863ef09bd4">blog</a> on session token authentication.</p><h4>Summary of Authentication Methods</h4><p>Here’s a quick comparison of the OCI SDK authentication methods supported in python-oracledb, their use cases, and how each one manages credentials.</p><figure><img alt="Summary of supported OCI SDK Authentication methods in python-oracledb." src="https://cdn-images-1.medium.com/max/1024/1*rw1c3ooJz9kGRsYiHw6_Wg.png" /><figcaption>Summary of supported OCI SDK Authentication methods in python-oracledb</figcaption></figure><h3>Conclusion</h3><p>Python-oracledb supports multiple OCI SDK authentication methods to fit different environments and workflows: <strong>API key-based</strong>, <strong>instance principal</strong>, and <strong>session token-based</strong> authentication.<br>Choose the method that best balances <strong>security, convenience, and automation</strong> for your use case.</p><p>For detailed setup instructions and step-by-step examples, check out the linked tutorial blogs for each authentication method.</p><h3>FAQs</h3><h4>What authentication methods are supported in python-oracledb?</h4><p>You can use multiple OCI SDK authentication methods, including:</p><ul><li>API key-based authentication</li><li>Session token-based authentication</li><li>Instance principals</li><li>Resource principals</li></ul><h4>Which authentication method should I start with?</h4><p>If you’re just getting started, API keys are the easiest.<br>But if you’re working on something more serious, it’s worth looking at session tokens or principals-based authentication.</p><h4>What’s the main difference between these methods?</h4><p>It mostly comes down to <strong>how credentials are handled:</strong></p><ul><li>API keys → stored locally</li><li>Session tokens → temporary credentials</li><li>Instance/resource principals → no credentials to manage</li></ul><h4>Do I always need an OCI config file?</h4><p>Not always.</p><ul><li>API keys and session tokens typically rely on a config file</li><li>Instance and resource principals don’t require one since OCI manages identity internally</li></ul><h4>Can I switch between authentication methods easily?</h4><p>Yes. Since python-oracledb supports these via configuration (like auth_type), switching is mostly about changing how authentication is set up, not rewriting your whole connection logic.</p><h4>Which method is best for production workloads?</h4><p>Generally:</p><ul><li>Instance principals or resource principals are preferred</li><li>They avoid secret management and work better with IAM policies</li></ul><h4>What about local development?</h4><p>Session tokens are usually the most convenient option for local work, they’re easy to generate and don’t require long-lived credentials.</p><h4>Do all methods work the same way under the hood?</h4><p>Not exactly, but they all end up doing the same thing, authenticating your request to OCI services. The SDK abstracts most of the differences, so from your code’s perspective, the experience is fairly consistent.</p><h3>Python-oracledb Resources</h3><p>Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul><li><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">Installation instructions</a></li><li><a href="https://python-oracledb.readthedocs.io/en/latest/index.html">Documentation</a></li><li><a href="https://github.com/oracle/python-oracledb/discussions">Discussions</a></li><li><a href="https://github.com/oracle/python-oracledb">Source code on GitHub</a></li><li><a href="https://pypi.org/project/oracledb/">PyPI</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6b614a8f4223" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/oci-sdk-authentication-methods-supported-in-python-oracledb-6b614a8f4223">OCI SDK Authentication Methods Supported in Python-oracledb</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using OCI Session Token Authentication with Python-oracledb]]></title>
            <link>https://medium.com/oracledevs/using-oci-session-token-authentication-with-python-oracledb-ba863ef09bd4?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/ba863ef09bd4</guid>
            <category><![CDATA[security-token-auth]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[oracle-ai-database]]></category>
            <category><![CDATA[token-based-auth]]></category>
            <category><![CDATA[session-token-auth]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Mon, 04 May 2026 17:40:02 GMT</pubDate>
            <atom:updated>2026-05-04T17:40:02.170Z</atom:updated>
            <content:encoded><![CDATA[<h4>Use OCI Session Tokens to enable secure, password-less access to Oracle AI Database connections with your Python applications</h4><figure><img alt="Feature image demonstrating Session token based authentication." src="https://cdn-images-1.medium.com/max/1024/1*NEIGduV6iuor-kVemGNFyQ.jpeg" /><figcaption>Image generated by Oracle Generative Chat</figcaption></figure><p><strong>Key Takeaways</strong></p><ul><li>Using OCI session tokens is a safer option than keeping API keys or Oracle AI Database passwords around, mainly because they’re short-lived and expire on their own.</li><li>You can connect to Oracle AI Database using python-oracledb without ever typing a password.</li><li>The oci session authenticate command makes the whole setup pretty straightforward. Once you run it, everything you need gets stored in your OCI config.</li><li>This approach keeps your code clean. No secrets hard-coded, no environment variables full of sensitive values.</li><li>It fits really well for local development or short-lived scripts where you just need quick, secure access.</li><li>Since it’s backed by OCI IAM, access control stays centralized , you’re not managing database credentials separately anymore.</li></ul><p><a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm#sdk_authentication_methods_session_token">Session token authentication</a> is one of the cleanest ways to connect to Oracle Cloud databases without handling long-lived credentials.<br>It’s short-lived, secure, and fits naturally into cloud workflows where users or services already have OCI identities.</p><p>Starting with python-oracledb 4.0, session token authentication is supported, so you can connect using the same session credentials that power the <a href="https://docs.oracle.com/en-us/iaas/Content/API/Concepts/cliconcepts.htm">OCI CLI</a>, without needing to build custom signer logic or rely on <a href="https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-instance-principals-in-e213e1f40c44">instance principals</a>.</p><p>This post shows how to do that, step by step.</p><h3>What Is OCI Session Token Authentication?</h3><p>OCI session tokens are temporary credentials issued when you authenticate using the OCI CLI or console. They replace long-lived private key and fingerprint credentials with a short-term token, stored locally in a token file. This token is then used to sign API requests, including database connection authentication.</p><p>You typically see this line in your ~/.oci/config file when you’re logged in via a session:</p><pre>security_token_file=/home/user/.oci/sessions/profilename/token</pre><p>Python-oracledb can now use the same token to authenticate to your Oracle Autonomous Database.</p><h4>Prerequisites</h4><p>To use session token authentication, ensure you have the following in place:</p><ol><li>Access to an Oracle Cloud Autonomous Database(ADB) instance that supports IAM authentication.</li><li>An OCI account with IAM properly configured.</li><li>The <em>oci</em> Python SDK and the latest <em>python-oracledb</em> package installed (<em>pip install oracledb[oci]</em>).</li></ol><p>I won’t go through each setup step here, as I covered them in my <a href="https://medium.com/oracledevs/cloud-native-authentication-in-python-oracledb-using-oci-iam-tokens-96d73db59fe1">earlier blog</a>, where I explained how to provision an ADB, configure IAM, prepare your environment for authentication. If you need a refresher, you can revisit that for detailed setup instructions.</p><p>Let’s jump straight into configuring the session token.</p><h3>Configuring the Session Token</h3><p>Configuring the session token is the first step before using it in Python-oracledb. You’ll start by creating an authenticated OCI CLI session, which generates a short-lived token and updates your OCI configuration automatically.<br>Let’s look at how to do this both <a href="https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/clitoken.htm#Starting">with</a> and <a href="https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/clitoken.htm#clitoken_topic-Starting_a_Tokenbased_CLI_Session_No_Browser">without</a> a browser.</p><h4>Creating a CLI Session with a Browser</h4><p>To use token-based authentication for the OCI CLI on a system with a web browser:</p><ol><li>Open a terminal and run, oci session authenticate</li><li>Select your region</li><li>In the browser window that opens, sign in with your OCI credentials.</li><li>After successful authentication, close the browser and return to the terminal.<br>Follow the interactive prompts — a session configuration file will be created automatically.</li></ol><h4>Creating a CLI Session without a Browser</h4><p>If your environment doesn’t have a browser (for example, a headless server or VM), you can still generate a session token.</p><p>First, ensure you’ve authenticated with oci setup config.</p><p>Then, run the following command to create a session without a browser:</p><pre>oci session authenticate --no-browser</pre><p>You will be prompted to select a region.</p><pre>Enter a region by index or name</pre><p>Choose your region from the list.</p><p>Next, you’ll be asked to provide a profile name:</p><pre>Enter the name of the profile you would like to create:</pre><p>Enter any name your prefer. The CLI will then write the configuration file. Also, you will see a message suggesting how to test your new credentials:</p><pre>Config written to: /home/user/.oci/config<br><br>    Try out your newly created session credentials with the following example command:<br><br>    oci iam region list --config-file /home/user/.oci/config --profile st --auth security_token</pre><p>Now, open your ~/.oci/config file to verify that a new profile has been created. It will include the location of the generated session token.</p><pre>[st_1]<br>fingerprint=&lt;fingerprint&gt;<br>key_file=/home/user/.oci/sessions/st_1/oci_api_key.pem<br>tenancy=&lt;tenancy_ocid&gt;<br>region=ap-mumbai-1<br>security_token_file=/home/user/.oci/sessions/st_1/token</pre><p>Each profile under ~/.oci/sessions holds its own token and key files.</p><p>With this configuration in place, you’re ready to authenticate to your Oracle Autonomous Database using the same session token that powers your OCI CLI.</p><h3>Connecting to the Oracle Autonomous Database Using Session Token Authentication</h3><p>Once your OCI CLI session is authenticated and the token file is available in ~/.oci, you can use it directly with Python-oracledb. The driver reads the token and private key from your OCI configuration, builds a signer, and authenticates securely without any password.</p><p>To use the session token with Python-oracledb, the <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin"><em>oci_tokens</em></a><em> </em>plugin must be imported. It’s a built-in hook that integrates session token authentication logic using the OCI Python SDK. The cloud configuration parameters are provided through the extra_auth_params argument in the connection call.</p><p>The auth_type parameter can be set to either SecurityToken or SecurityTokenSimple, depending on how you want to authenticate with the session token.</p><p>Below is an example using <strong>SecurityToken</strong> authentication. Here, auth_type, profile are passed through extra_auth_params. This example assumes the default OCI configuration file location: /home/user/.oci/config. <em>session_profile</em> is the profile name given during oci session authenticate.</p><pre>import oracledb<br>import oracledb.plugins.oci_tokens<br><br>dsn = &quot;(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps) \<br>       (port=1521)(host=host.oraclecloud.com))(connect_data= \<br>       (service_name=myclouddb19_high.adb.oraclecloud.com)) \<br>       (security=(ssl_server_dn_match=yes)))&quot;<br>}<br><br>token_based_auth = {<br>      &quot;auth_type&quot;: &quot;SecurityToken&quot;,<br>      &quot;profile&quot;: &quot;session_profile&quot;<br>}<br><br>connection = oracledb.connect(<br>               dsn=dsn, <br>               extra_auth_params=token_based_auth<br>)</pre><p>The next example demonstrates <strong>SecurityTokenSimple</strong> authentication. In this case, auth_type is set to SecurityTokenSimple, and all configuration parameters are required to be supplied via environment variables.</p><pre>import oracledb<br>import oracledb.plugins.oci_tokens<br>import os<br><br>dsn = &quot;(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps) \<br>       (port=1521)(host=host.oraclecloud.com))(connect_data= \<br>       (service_name=myclouddb19_high.adb.oraclecloud.com)) \<br>       (security=(ssl_server_dn_match=yes)))&quot;<br>}<br><br>token_based_auth = {<br>      &quot;auth_type&quot;: &quot;SecurityTokenSimple&quot;,<br>      &quot;key_file&quot;: os.getenv(&quot;PYO_STSA_OCI_KEYFILE&quot;),<br>      &quot;fingerprint&quot;: os.getenv(&quot;PYO_STSA_OCI_FINGERPRINT&quot;),<br>      &quot;tenancy&quot;: os.getenv(&quot;PYO_STSA_OCI_TENANCY&quot;),<br>      &quot;region&quot;: os.getenv(&quot;PYO_STSA_OCI_REGION&quot;),<br>      &quot;profile&quot;: os.getenv(&quot;PYO_STSA_OCI_PROFILE&quot;),<br>      &quot;security_token_file&quot;: os.getenv(&quot;PYO_STSA_OCI_SECURITY_TOKEN_FILE&quot;)<br>}<br><br>connection = oracledb.connect(<br>               dsn=dsn, <br>               extra_auth_params=token_based_auth<br>)</pre><h3>Conclusion</h3><p>Session token authentication in Python-oracledb makes connecting to Oracle Autonomous Databases simple, secure, and password-free. With just a few steps, you can use your OCI CLI session tokens to authenticate automatically, whether on a local machine or a headless server.</p><p>This approach reduces reliance on long-living and less secure credentials and fits seamlessly into modern cloud workflows.</p><p>Give it a try and see how effortless and secure session token authentication can make your database connections.</p><h3>FAQs</h3><h4>What exactly is an OCI session token?</h4><p>It’s a temporary authentication token you get after logging in through OCI (usually via a browser). Instead of using API keys, you use this token to access services.</p><h4>How do I generate one?</h4><p>On your terminal, run:</p><pre>oci session authenticate</pre><p>It’ll open a browser, ask you to log in, and then store the token details in your OCI config file. You can also generate it without browser using--no-browser option in the above command.</p><h4>Is this something I should use in production?</h4><p>Not usually. It’s great for development and quick scripts, but for production setups, things like instance principals are a better fit.</p><h4>Do I still need the OCI config file?</h4><p>Yes, that’s where the token location, key path, and other details live. Your code relies on it.</p><h4>Does this mean I can completely avoid Oracle AI Database passwords?</h4><p>Yep. Once IAM-based auth is set up, you don’t need to deal with database passwords at all.</p><h3>Python-oracledb Resources</h3><p>Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul><li><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">Installation instructions</a></li><li><a href="https://python-oracledb.readthedocs.io/en/latest/index.html">Documentation</a></li><li><a href="https://github.com/oracle/python-oracledb/discussions">Discussions</a></li><li><a href="https://github.com/oracle/python-oracledb">Source code on GitHub</a></li><li><a href="https://pypi.org/project/oracledb/">PyPI</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ba863ef09bd4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/using-oci-session-token-authentication-with-python-oracledb-ba863ef09bd4">Using OCI Session Token Authentication with Python-oracledb</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[No More Credentials: Connect to Oracle Autonomous Database Using Resource Principals in…]]></title>
            <link>https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-resource-principals-in-56f9735a0169?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/56f9735a0169</guid>
            <category><![CDATA[oracle-ai-database]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[oci]]></category>
            <category><![CDATA[token-based-auth]]></category>
            <category><![CDATA[resource-principal]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Mon, 04 May 2026 17:38:41 GMT</pubDate>
            <atom:updated>2026-05-04T17:38:41.577Z</atom:updated>
            <content:encoded><![CDATA[<h3>No More Credentials: Connect to Oracle Autonomous Database Using Resource Principals in python-oracledb 4.0</h3><h4>Leverage OCI Resource Principals for secure, password-less Oracle AI Database connections with your Python applications</h4><figure><img alt="Feature image demonstrating Resource Principals." src="https://cdn-images-1.medium.com/max/1024/1*pN0EqZNkT9_XEPA7orUcyg.jpeg" /><figcaption>Image generated by Oracle Generative Chat</figcaption></figure><h4>Key Takeaways</h4><ul><li>Resource principals let you connect to Oracle AI Database without storing any credentials at all, no config files, no API keys, nothing sitting in your code.</li><li>Instead of authenticating as a user, your resource (like a function, or service) becomes the identity. OCI handles the authentication behind the scenes.</li><li>Once the right dynamic group and IAM policies are in place, the database or service can securely access other OCI resources on its own.</li><li>It works really well with python-oracledb, making it easy to build secure, cloud-native apps without worrying about credential handling.</li></ul><p>Starting with version 1.1, <a href="https://oracle.github.io/python-oracledb/index.html">python-oracledb</a> added support for <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#token-based-authentication">token-based authentication</a>. This was extended in version 3.0 to include cloud-native authentication using Oracle Cloud Infrastructure (OCI) <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/overview.htm">Identity and Access Management</a> (IAM) tokens. With the 4.0 release, python-oracledb now adds support for Resource Principal authentication, allowing applications running inside OCI services to connect to Oracle AI Database without managing credentials. This post explains what that means and how to use it.</p><h4>ELI5: What is Resource Principal ?</h4><p>Imagine your code is running inside an OCI service, like a notebook or a function, and it needs to talk to something like a Oracle AI Database. The usual way is to give it a password or key and make sure it’s stored safely. That gets messy fast and is easy to get wrong.</p><p><a href="https://docs.oracle.com/en-us/iaas/mysql-database/doc/resource-principals.html">Resource Principals</a> are OCI’s way of saying, “<em>Don’t worry about that</em>, <em>I’ll handle it for you.</em>” The service running your code is treated as an identity, just like a user or group, and OCI automatically gives it what it needs to prove who it is. Everything is handled behind the scenes, including creating and refreshing the credentials.</p><p>From a technical point of view, the service uses this identity to get a short-lived token from OCI <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/overview.htm">IAM</a>. That token is then used to access services like <a href="https://www.oracle.com/autonomous-database/">Oracle Autonomous Database</a>, without storing any secrets in your code.</p><h4>How Resource Principals work ?</h4><h4>Dynamic Groups</h4><p>OCI uses <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm"><strong>Dynamic Groups</strong></a> to manage access for resources running inside OCI services. These work like IAM groups, but instead of users or instances, they group resources such as <a href="https://docs.oracle.com/en-us/iaas/Content/data-science/using/manage-notebook-sessions.htm">Notebook sessions</a>, <a href="https://docs.oracle.com/en-us/iaas/Content/Functions/home.htm">Functions</a>, or <a href="https://docs.oracle.com/en-us/iaas/Content/ContEng/home.htm">OKE</a> workloads. You define matching rules based on resource attributes, and anything that matches is automatically included.</p><p>Example Matching Rule:</p><p><em>ALL {resource.type = ‘datasciencenotebooksession’}</em></p><p>Once the resources are part of a dynamic group, you can assign policies to control what they can access.</p><h4>IAM Policies</h4><p>After defining the dynamic group, you create IAM policies that specify what those resources are allowed to do. For example:</p><p><em>Allow dynamic-group id &lt;dynamicgroup_ocid&gt; to manage autonomous-database-family in tenancy</em></p><p>This policy allows all resources defined by the specified dynamic group (via it’s <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/dynamicgroups/Working_with_Dynamic_Groups.htm">OCID</a> and matching rules) full access to Oracle Autonomous Database operations across the tenancy.</p><h4>How Resource Principals differs from Instance Principals ?</h4><p>Instance Principals work with compute instances that you manage. The identity is tied to the VM, and the application inherits that identity when it runs on the instance.</p><p>Resource Principals apply to OCI-managed services where you don’t control the underlying infrastructure. The identity is assigned to the service resource itself, such as a <a href="https://docs.oracle.com/en-us/iaas/Content/data-science/using/manage-notebook-sessions.htm">Notebook session</a> or an OCI <a href="https://docs.oracle.com/en-us/iaas/Content/Functions/home.htm">Function</a>.</p><p>In short, Instance Principals are for machines you manage. Resource Principals are for services OCI manages for you.</p><blockquote>If you want more background on Instance Principals, I’ve covered them in my earlier <a href="https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-instance-principals-in-e213e1f40c44">post</a>.</blockquote><h4>How to use Resource Principals ?</h4><h4>Prerequisites</h4><ol><li>You should have an OCI resource available. In this post, we will use an OCI Data Science notebook to demonstrate Resource Principals. You will also briefly see how to create one in the Oracle cloud console.</li></ol><p>Go to your Oracle Cloud console, <em>Navigation Menu -&gt; Analytics &amp; AI -&gt; Data Science</em></p><figure><img alt="Analytics and AI section of the OCI console." src="https://cdn-images-1.medium.com/max/848/1*sJ2ObXd_thSDCRnExJFmUQ.png" /><figcaption>Analytics &amp; AI, Data Science</figcaption></figure><p>Click on the Create project and give a Name (optional) and Description(optional).</p><figure><img alt="Create Project user interface." src="https://cdn-images-1.medium.com/max/900/1*sn6QSq51DSZVHyKzRwUE4A.png" /><figcaption>Create project</figcaption></figure><p>You can see the project created from the Project details page, click on Create notebook session.</p><figure><img alt="Project Details User Interface" src="https://cdn-images-1.medium.com/max/577/1*rzMEpXo-Nf6cdlOVXcUh0A.png" /><figcaption>Project details</figcaption></figure><p>In the Create notebook session page, you can give a Name(optional), select appropriate fields fields and click on Create.</p><figure><img alt="Create Notebook Session Interface" src="https://cdn-images-1.medium.com/max/580/1*CXWakoDhSRk431LzssyGng.png" /><figcaption>Create notebook session</figcaption></figure><p>You can see the Notebook session created. Clicking Open will take you to the Notebook.</p><figure><img alt="Page showing the Notebook is created." src="https://cdn-images-1.medium.com/max/996/1*Yl0Q6Ibd63ggAseXfSD0Zw.png" /><figcaption>Notebook created</figcaption></figure><p>2. Ensure the OCI CLI is available in the notebook environment. You can follow the installation instructions provided <a href="https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm">here</a>.</p><p>3. Also, make sure python-oracledb is installed. To install or upgrade it, run:</p><pre>python3 -m pip install oracledb --upgrade</pre><p>See <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb Installation</a> for details.</p><h4>Steps to set up Resource Principals</h4><ol><li><strong>Create a Dynamic Group</strong><br>Define rules to group the resources that require access.</li><li><strong>Create an IAM Policy</strong><br>Grant the dynamic group permissions to access the required OCI services (e.g., Oracle Autonomous Database).</li><li><strong>Map Principals to Oracle AI Database users<br></strong>In the database, create user mappings for your resource principals or dynamic groups.</li><li><strong>Run the Application from the Data Science notebook</strong><br>Developers can configure their applications to use Resource Principals from the OCI SDK. The application authenticates using the resource’s identity and makes API or database calls, no credentials or config files required.</li></ol><p><strong>Create a Dynamic group</strong></p><p>Create a Dynamic group that matches a set of resources.</p><p>Login to your Oracle Cloud console. Go to<em> Navigation menu → Identity &amp; Security</em>. Under <em>Identity</em>, select <em>Domains</em>. Under <em>Identity domain</em>, select <em>Dynamic groups</em></p><figure><img alt="Dynamic Groups User Interface." src="https://cdn-images-1.medium.com/max/1024/1*CdVrU9WIqDX5Nn4tMhsp5w.png" /><figcaption>Dynamic groups interface</figcaption></figure><p>Click <em>Create dynamic group</em> and enter the following details.</p><p><em>Name</em>. Provide a unique name for the group. The name must be unique across all groups in your tenancy, dynamic groups, and user groups.</p><p><em>Description. </em>Provide a friendly description (optional).</p><p>The next step is to create matching rules.</p><p>Resources that meet the rule criteria are members of the group.</p><figure><img alt="Create Dynamic Group Interface." src="https://cdn-images-1.medium.com/max/1024/1*5S2ZL9OKbrCJbzuHdvYuww.png" /><figcaption>Create dynamic group</figcaption></figure><p>After the Rules are added, click on ‘<em>Create</em>’ button to create a dynamic group. You can see the dynamic group created.</p><figure><img alt="Page showing that the Dynamic group is created." src="https://cdn-images-1.medium.com/max/548/1*OQVTqEMVxscXcAb6HLRTQw.png" /><figcaption>Dynamic group created</figcaption></figure><p><strong>Create an IAM Policy</strong></p><p>Now, create a policy dictating what permissions those resources should receive.</p><p>Go to <em>Identity &amp; Security → Policies → Create Policy</em>.</p><p>Give <em>Name </em>and <em>Description </em>and click on ‘<em>Show manual Editor</em>’. You can give the statement in the text box available.</p><figure><img alt="Create Policy User Interface" src="https://cdn-images-1.medium.com/max/902/1*vwC8ocY_yMUFqxCjcghsiw.png" /><figcaption>Create Policy</figcaption></figure><p>The policy gets created.</p><figure><img alt="Page showing policy is created." src="https://cdn-images-1.medium.com/max/618/1*kYGPGln4VIWq_WrT4nXZFA.png" /><figcaption>Policy created</figcaption></figure><p>From the <em>Statements </em>tab, you can verify the policy statements provided, as well as, you can edit the policy further, if required.</p><figure><img alt="Edit Policy Statements User Interface." src="https://cdn-images-1.medium.com/max/1024/1*IhLoPM87MDm0CXoHSeYIuA.png" /><figcaption>Edit Policy Statements</figcaption></figure><blockquote><strong>Note:</strong> The resource principal token is cached for 15 minutes. If you change the policy or the dynamic group, you must <a href="https://docs.oracle.com/en-us/iaas/Content/data-science/using/use-notebook-sessions.htm">wait</a> for 15 minutes to see the effect of the changes.</blockquote><p><strong>Map Principals to Oracle Database users</strong></p><p>So far so good, your application is authenticated using a Resource Principal. However, the database still needs to know: <em>“Who is this principal, and what Oracle Database user should I map it to?”</em></p><p>This mapping is not automatic — you must explicitly create users or mappings in the database.</p><p>Map your dynamic group to a shared Oracle AI Database user.</p><p>You map a dynamic group of resources to a single shared database user.</p><pre>CREATE USER shared_user IDENTIFIED GLOBALLY<br>AS &#39;IAM_GROUP_NAME=rpdg&#39;;<br><br>GRANT CREATE SESSION TO shared_user;</pre><p>This means <em>any</em> resource in the specified dynamic group can log in as shared_user.</p><p>Also, make sure that External authentication is enabled on ADB and <em>identity_provider_type</em> is set to OCI_IAM. Refer ‘Enable IAM Authentication on ADB’ from this <a href="https://medium.com/oracledevs/cloud-native-authentication-in-python-oracledb-using-oci-iam-tokens-96d73db59fe1">link</a> for the steps involved.</p><pre>BEGIN<br> DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION(<br> type =&gt; &#39;OCI_IAM&#39; );<br>END;<br>/<br> <br>SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = &#39;identity_provider_type&#39;;</pre><figure><img alt="Enable External Authentication and Map group to user at the DB side." src="https://cdn-images-1.medium.com/max/975/1*1TF9LkJ50IinmynndQFuDg.png" /><figcaption>Enable External Authentication; Map group to user</figcaption></figure><p><strong>Run the Application from the Data Science notebook</strong></p><p>Now, run your application code in the Data Science notebook. The Python example below shows how to connect to Oracle Autonomous Database using Resource Principal authentication, without any user-managed credentials or configuration files.</p><p>To enable this, the application uses the <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/module.html#oracle-cloud-infrastructure-oci-cloud-native-authentication-plugin">oci_tokens</a> plugin in <a href="https://oracle.github.io/python-oracledb/index.html">python-oracledb</a>.</p><p>To use Resource Principal authentication, set the <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin">auth_type</a> to &quot;resourceprincipal&quot; and pass it through <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connect_params.html">extra_auth_params</a> in the connection call.</p><pre>import oracledb<br>import oracledb.plugins.oci_tokens<br> <br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3)<br>                    (address=(protocol=tcps)(port=1521)<br>                    (host=adb.sa-saopaulo-1.oraclecloud.com))(connect_data=<br>                    (service_name=myclouddb26_high.adb.oraclecloud.com))<br>                    (security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br> <br>token_based_auth = {<br>      &quot;auth_type&quot;: &quot;ResourcePrincipal&quot;<br>}<br> <br>connection = oracledb.connect(<br>              dsn=connect_string, <br>              extra_auth_params=token_based_auth<br>)<br><br>curr = connection.cursor()<br>sqlText = &quot;select user from dual&quot;<br>curr.execute(sqlText)<br>record = curr.fetchone()<br>print(record)</pre><p>When the application runs, you can verify that resource principal authentication happens successfully and the connection goes through as shared_user, because the dynamic group, rpdg, your notebook belongs to, is mapped to that user in the database.</p><figure><img alt="Page showing the application output." src="https://cdn-images-1.medium.com/max/1023/1*2WH2Gjo5b6xgU_DPNrNU3Q.png" /><figcaption>Application output</figcaption></figure><h3>Conclusion</h3><p>Resource Principals make it easier to authenticate from OCI-managed services without managing credentials. With support now available in python-oracledb 4.0, you can connect to Oracle AI Database in a secure, cloud-native way using IAM tokens.</p><p>Give it a try and stop worrying about secrets :)</p><h3>FAQs</h3><h4>What are resource principals in OCI?</h4><p>Resource principals allow an OCI resource (like an OCI function, Data-science Notebook) to authenticate itself directly with OCI services, instead of using user credentials.</p><h4>What do I need to set this up?</h4><p>At a high level:</p><ul><li>A <strong>dynamic group</strong> that includes your resource</li><li>IAM <strong>policies</strong> that grant required permissions</li></ul><p>Once that’s done, the resource can act on its own behalf.</p><h4>Do I need an OCI config file or wallet?</h4><p>No, that’s one of the biggest advantages.<br>You don’t need a config file, private key, or wallet for authentication in this setup.</p><h4>How does python-oracledb fit into this?</h4><p>Python-oracledb supports resource principals by allowing you to set auth_type=&quot;ResourcePrincipal&quot; in extra_auth_params during oracledb.connect(), so your application can connect without explicitly providing credentials.</p><h4>Is this approach suitable for production?</h4><p>Yes, this is the recommended approach for production workloads because:</p><ul><li>No secret management</li><li>Automatic credential rotation</li><li>Better alignment with IAM policies</li></ul><h4>What are the prerequisites for using resource principals?</h4><p>You’ll need:</p><ul><li>Proper IAM configuration (dynamic groups and policies)</li><li>Your application running inside OCI (or an OCI-managed environment)</li></ul><h4>How is Resource Principal different from Instance Principal?</h4><ul><li>Instance Principal: Used when your application runs on an OCI compute instance (VM), the VM acts as the identity.</li><li>Resource Principal: Used by OCI services (like Functions, OKE, etc.), the service/resource acts as the identity.</li></ul><h3>Python-oracledb Resources</h3><p>Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul><li><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">Installation instructions</a></li><li><a href="https://python-oracledb.readthedocs.io/en/latest/index.html">Documentation</a></li><li><a href="https://github.com/oracle/python-oracledb/discussions">Discussions</a></li><li><a href="https://github.com/oracle/python-oracledb">Source code on GitHub</a></li><li><a href="https://pypi.org/project/oracledb/">PyPI</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=56f9735a0169" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-resource-principals-in-56f9735a0169">No More Credentials: Connect to Oracle Autonomous Database Using Resource Principals in…</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[From DAG to Database: Using Airflow with Oracle AI Database]]></title>
            <link>https://medium.com/oracledevs/from-dag-to-database-using-airflow-with-oracle-database-ec132f5cedce?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/ec132f5cedce</guid>
            <category><![CDATA[apache-airflow]]></category>
            <category><![CDATA[airflow-installation]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[oracle-database]]></category>
            <category><![CDATA[airflow-dag]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Wed, 25 Mar 2026 08:01:07 GMT</pubDate>
            <atom:updated>2026-04-24T10:41:58.916Z</atom:updated>
            <content:encoded><![CDATA[<h4>A step-by-step guide to setting up Apache Airflow and running your first Oracle AI Database query through a DAG</h4><figure><img alt="Airflow Meets Oracle AI Database. Orchestrate database workflows with Python DAGs" src="https://cdn-images-1.medium.com/max/1024/1*nn05ZJV-axW4a5KsKSIFWw.png" /></figure><p><strong>Key Takeaways</strong></p><ul><li>Airflow lets you run and schedule Oracle AI Database queries in a structured, repeatable way.</li><li>The python-oracledb driver handles the actual database connection behind the scenes.</li><li>Airflow Connections keep credentials out of your code and make setups easier to manage.</li><li>A simple DAG is enough to verify that Airflow and Oracle AI Database are working together.</li></ul><p><a href="https://airflow.apache.org/">Airflow</a> works best when you treat workflows as code. <a href="https://www.oracle.com/database/">Oracle AI Database</a> works best when it stays the system of record. Put them together and you get something predictable, which is rarer than it should be.</p><p>This blog is a practical walk-through of how to get Airflow talking to Oracle AI Database and doing useful work. We’ll keep the moving parts to a minimum and focus on what actually runs.</p><p>If you’ve been running scripts by hand or wiring basic jobs together, using Airflow will orchestrate them for you and save you time!</p><h4>Why Use Airflow with Oracle AI Database</h4><p>Most teams already keep their data in Oracle AI Database. The real problem isn’t storage, it’s orchestration. Scripts pile up, dependencies tangle, and sooner or later someone ends up triggering jobs by hand.</p><p>Airflow fixes that by giving your workflows structure. It turns scattered scripts into something predictable and easier to reason about. You stop stitching scripts together and start defining workflows that behave the same way every time.</p><p>This starts to matter once things grow. One script is fine. Five scripts with dependencies and retries is where things fall apart. Airflow keeps that complexity in one place.</p><h4>What You Need Before You Start</h4><p>You need Airflow running locally or on a server. A working Oracle AI Database helps, along with credentials that actually connect.</p><p>First, install Airflow — you can follow the steps over <a href="https://airflow.apache.org/docs/apache-airflow/stable/start.html">here</a>. This brings a standalone Airflow instance on your machine. Airflow needs a home directory. By default, it uses ~/airflow, but you can choose a different location if needed.</p><p>Set the AIRFLOW_HOME environment variable to tell Airflow where to store its files. Do this before installing Airflow so it knows where to place everything. Below are the steps on Linux.</p><pre>$ export AIRFLOW_VERSION=&quot;3.1.8&quot;<br>$ export PYTHON_VERSION=&quot;3.12&quot;<br>$ export AIRFLOW_HOME=~/airflow<br>$ export CONSTRAINT_URL=&quot;https://raw.githubusercontent.com/apache/airflow/constraints-${AIRFLOW_VERSION}/constraints-${PYTHON_VERSION}.txt&quot;<br>$<br>$ echo $CONSTRAINT_URL<br>https://raw.githubusercontent.com/apache/airflow/constraints-3.1.8/constraints-3.12.txt<br>$ <br>$ pip install &quot;apache-airflow==${AIRFLOW_VERSION}&quot; --constraint &quot;${CONSTRAINT_URL}&quot;<br>$<br>$ pip freeze | grep airflow<br>Using Python 3.12.3 environment at: venv_af_rag<br>apache-airflow                           3.1.8<br>apache-airflow-core                      3.1.8<br>apache-airflow-providers-common-compat   1.14.0<br>apache-airflow-providers-common-io       1.7.1<br>apache-airflow-providers-common-sql      1.32.0<br>apache-airflow-providers-smtp            2.4.2<br>apache-airflow-providers-standard        1.12.0<br>apache-airflow-task-sdk                  1.1.8<br>$ <br>$ airflow version<br>3.1.8</pre><p>You’ll need the <a href="https://pypi.org/project/oracledb/">python-oracledb</a> package, since your Airflow tasks use it under the hood. If you install the <a href="https://airflow.apache.org/docs/apache-airflow-providers-oracle/stable/index.html">Oracle provider</a> for Airflow, it gets installed for you.</p><pre>$ pip install apache-airflow-providers-oracle<br> + apache-airflow-providers-oracle==4.5.1<br> + oracledb==3.4.2</pre><h4>A Quick Primer on Airflow (Just Enough to Begin)</h4><p>Airflow is a scheduler that runs Python code.</p><p>You define a workflow as a DAG(Directed Acyclic Graph). A <a href="https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/dags.html">DAG</a> is a set of <a href="https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/tasks.html">tasks</a> with dependencies, written in Python. Each task does one thing, and Airflow handles the order, retries, and logging.</p><p>The important parts are simple. DAG defines the workflow, the <a href="https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/tasks.html">tasks</a> define the work, and the <a href="https://airflow.apache.org/docs/apache-airflow/stable/administration-and-deployment/scheduler.html">scheduler</a> decides when to run them.</p><p>Finally, after above installation steps, run airflow standalone on the terminal. This should bring up the Airflow UI on <a href="http://localhost:8080">http://localhost:8080</a> on your default browser (8080 is the default port for Apache Airflow). The credentials to login are available in file, simple_auth_manager_passwords.json.generated under AIRFLOW_HOME directory.</p><figure><img alt="Airflow User Interface" src="https://cdn-images-1.medium.com/max/871/1*08wGxoSHxiIAaIN9CWXUrg.png" /><figcaption>Airflow UI</figcaption></figure><h4>How Airflow Connects to Oracle AI Database</h4><p>Airflow does not talk to Oracle AI Database directly. It uses <a href="https://airflow.apache.org/docs/apache-airflow/stable/operators-and-hooks-ref.html">hooks and operators</a>, which are just wrappers around database connections.</p><p>Underneath, the actual connection is handled by the python-oracledb driver. Airflow stores connection details like host, port, schema, and credentials, then passes them to your code or its own operators when needed.</p><p>Think of Airflow as the coordinator. The driver still does the real database work.</p><h4>Setting Up an Oracle AI Database Connection in Airflow</h4><p>Start with the Airflow UI.</p><p>Go to Admin, then Connections. Create a new connection and set the type to Oracle. Fill in Host, Port, Login, Password and other required details.</p><p>Give it a clear Connection ID, something like oracle_conn. You’ll use that ID in your DAG instead of repeating credentials everywhere.</p><p>Once saved, Airflow can reuse this connection across tasks.</p><figure><img alt="Page demonstrating on how to add a Connection." src="https://cdn-images-1.medium.com/max/1024/1*pnBvhQCeqndFn5mNbo8Oow.png" /><figcaption>Add Connection</figcaption></figure><p>Alternatively, you can also create connections using Airflow <a href="https://airflow.apache.org/docs/apache-airflow/stable/howto/usage-cli.html">Command Line Interface</a> as below.</p><pre>$ airflow connections add oracle_conn3 --conn-type oracle --conn-login admin --conn-password password1 --conn-host &quot;tcps://host.oraclecloud.com:1521/myclouddb26_high.adb.oraclecloud.com&quot;<br>Successfully added `conn_id`=oracle_conn3 : oracle://admin:******@tcps://host.oraclecloud.com:1521/myclouddb26_high.adb.oraclecloud.com:<br>$<br>$ airflow connections get oracle_conn3<br>id | conn_id      | conn_type | description | host                     | schema | login | password     | port | is_encrypted | is_extra_encrypted | extra_dejson | get_uri<br>===+==============+===========+=============+==========================+========+=======+==============+======+==============+====================+==============+==========================<br>2  | oracle_conn3 | oracle    | None        | tcps://host.oraclecloud. | None   | admin | password1    | None | True         | True               | {}           | oracle://tcps://admin:pas<br>   |              |           |             | .com:1521/myclouddb26_   |        |       |              |      |              |                    |              | sword1@host.oraclecloud.<br>   |              |           |             | high.adb.oraclecloud.com |        |       |              |      |              |                    |              | .com%3A1521%2F_mycloudd<br>   |              |           |             |                          |        |       |              |      |              |                    |              | b26_high.adb.oraclecloud.<br>   |              |           |             |                          |        |       |              |      |              |                    |              | com<br>   |              |           |             |                          |        |       |              |      |              |                    |              | </pre><h4>A Simple DAG — Using Airflow’s Oracle Hook</h4><p>You can always call <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html">python-oracledb.connect()</a> directly inside a task to connect to Oracle AI Database. That works, and sometimes it’s all you need. Here, we’ll take a slightly cleaner route and use Airflow’s Oracle hook.</p><p><a href="https://airflow.apache.org/docs/apache-airflow-providers-oracle/stable/_api/airflow/providers/oracle/hooks/oracle/index.html#classes">OracleHook</a> is Airflow’s wrapper around Oracle AI Database connections. It reads connection details from Airflow, manages the plumbing, and gives you a ready-to-use connection or cursor.</p><p>Here’s a minimal DAG that uses it. This DAG connects to Oracle AI Database using above created connection identifier, oracle_conn3, and runs a simple SELECT query on Oracle AI Database, to verify that the setup works end to end.</p><p>The DAGs usually sit in theAIRFLOW_HOME/dags folder.</p><pre>from airflow import DAG<br>from airflow.operators.python import PythonOperator<br>from airflow.providers.oracle.hooks.oracle import OracleHook<br>from datetime import datetime<br><br><br>def test_oracle_adb_connection():<br>    hook = OracleHook(oracle_conn_id=&quot;oracle_conn3&quot;)<br>    conn = hook.get_conn()<br>    cursor = conn.cursor()<br>    cursor.execute(&quot;SELECT 1 FROM dual&quot;)<br>    result = cursor.fetchone()<br>    print(&quot;Oracle connection works! Result:&quot;, result)<br><br><br>with DAG(<br>    dag_id=&quot;vig_test_oracle_adb_conn&quot;,<br>    start_date=datetime(2025, 1, 1),<br>    schedule = &quot;@once&quot;,<br>    catchup=False,<br>    tags=[&quot;test&quot;],<br>) as dag:<br>    test_task = PythonOperator(<br>        task_id=&quot;test_oracle_adb&quot;,<br>        python_callable=test_oracle_adb_connection,<br>    )<br><br>    test_task</pre><p>This keeps your DAG focused on the work, not on connection details. Airflow handles the credentials, and the hook gives you a connection that’s ready to use.</p><h4>Running and Monitoring Your DAG</h4><p>Once your DAG is in place, Airflow picks it up automatically.</p><figure><img alt="Airflow’s DAG page interface" src="https://cdn-images-1.medium.com/max/1024/1*JvrgakWsoNnbv_W_FbHHow.png" /><figcaption>Airflow DAGs</figcaption></figure><p>Use the UI to trigger it manually or wait for the schedule. You can see each task, its status, logs, and retries from the <a href="https://airflow.apache.org/docs/apache-airflow/stable/ui.html#dag-details-page">DAG Details page</a>.</p><figure><img alt="Airflow’s DAG Run interface" src="https://cdn-images-1.medium.com/max/1024/1*iv9LhTQqi7NOH73ueK0ckw.png" /><figcaption>Airflow DAG Run</figcaption></figure><p>If something fails, Airflow shows you where and why. No digging through random log files.</p><p>At this point, you have a basic setup that works. Airflow can trigger a DAG, connect to Oracle AI Database, and run a query end to end.</p><p>From here, you can start layering in real work. Add more tasks, split logic where it makes sense, and build toward actual pipelines as your use case grows.</p><h4>FAQs</h4><p><strong>1. Do I need special setup to connect Airflow to Oracle AI Database ?</strong><br> You only need the Airflow server to be up and running, access to an Oracle AI Database, and the python-oracledb package.</p><p><strong>2. Can I run Oracle AI Database queries directly from a DAG?</strong><br> Yes. You can execute queries inside a task using either python-oracledb or Airflow’s OracleHook.</p><p><strong>3. Why use OracleHook instead of direct connections?</strong><br> It uses Airflow’s stored connection details, so you don’t have to manage credentials in your application code.</p><p><strong>4. How do I confirm everything is working?</strong><br> Run a simple DAG that executes a query and check the results and logs in the Airflow UI.</p><h3>Airflow Resources</h3><p>Apache Airflow is an open-source workflow orchestration tool that lets you define, schedule, and monitor pipelines as code. It helps you manage task dependencies, retries, and execution flow without relying on ad-hoc scripts.</p><ul><li><a href="https://airflow.apache.org/docs/apache-airflow/stable/start.html">Installation instructions</a></li><li><a href="https://airflow.apache.org/docs/">Documentation</a></li><li><a href="https://airflow.apache.org/docs/apache-airflow-providers-oracle/stable/index.html">Providers-Oracle</a></li><li><a href="https://github.com/apache/airflow">Source code on GitHub</a></li><li><a href="https://pypi.org/project/apache-airflow/">PyPI</a></li></ul><h3>Python-oracledb Resources</h3><p>Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul><li><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">Installation instructions</a></li><li><a href="https://python-oracledb.readthedocs.io/en/latest/index.html">Documentation</a></li><li><a href="https://github.com/oracle/python-oracledb/discussions">Discussions</a></li><li><a href="https://github.com/oracle/python-oracledb">Source code on GitHub</a></li><li><a href="https://pypi.org/project/oracledb/">PyPI</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ec132f5cedce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/from-dag-to-database-using-airflow-with-oracle-database-ec132f5cedce">From DAG to Database: Using Airflow with Oracle AI Database</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sessionless Transactions in Python-oracledb: Speed without Strings]]></title>
            <link>https://medium.com/oracledevs/sessionless-transactions-in-python-oracledb-speed-without-strings-b218c6ff62f2?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/b218c6ff62f2</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-oracledb]]></category>
            <category><![CDATA[oracle-database]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[oracle]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Wed, 30 Jul 2025 02:24:40 GMT</pubDate>
            <atom:updated>2025-08-12T05:03:07.964Z</atom:updated>
            <content:encoded><![CDATA[<h4>No session locks. No idle waits. Just clean, efficient transactions without the usual session stickiness.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qo47IefNIPl27hDS" /><figcaption>Photo by <a href="https://unsplash.com/@growtika?utm_source=medium&amp;utm_medium=referral">Growtika</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p><a href="https://www.oracle.com/in/database/23ai/">Oracle Database 23ai</a> introduced <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/developing-applications-sessionless-transactions.html#GUID-8844E944-A110-4567-9B5A-60938152A8A0">Sessionless Transactions</a>, a way to run multi-step transactions without holding on to a dedicated database session between steps. With version 3.3, the <a href="https://pypi.org/project/oracledb/">python-oracledb</a> driver adds native support for <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/txn_management.html#sessionless-transactions">this</a> feature, enabling Python developers to write stateless, scalable transaction flows with ease.</p><p>This unlocks better pool utilization, easier scaling, and reduced overhead, especially in apps with user “think time” or back-end delays.</p><p>It delivers what the title promised: <strong>speed without strings</strong>. No sticky sessions. No wasted connections. Just clean, fast commits when you’re ready.</p><p>In this post, you’ll see how Sessionless Transactions work, what makes them different from older approaches, and how to use them in Python with real code examples. Whether you’re building a back-end service or trying to squeeze more out of your connection pool, this model gives you control without slowing you down.</p><p>The python-oracledb driver uses the term <em>connection</em>, but each connection maps to a database <em>session</em> under the hood. The terms are used interchangeably throughout this post.</p><h3>The Old Way: Sessions That Wouldn’t Let Go</h3><p>Before Sessionless Transactions, you had two choices when working with Oracle Database transactions.</p><p>One way was to stick with a session from start to finish. You begin a transaction on a connection, and that connection stays tied up until you commit or roll it back. Even if your application is idle in between, the database holds onto that session. This approach is simple, but it wastes connections, especially under heavy load.</p><p>The other option was to use <a href="https://docs.oracle.com/en/database/oracle/oracle-database/19/adfns/xa.html#GUID-1DAB062F-F796-4424-9FFD-9756688AC5B7">XA</a> transactions, which let you pause and resume a transaction across sessions. While this gave more flexibility, it introduced added complexity, especially around coordinating the final commit and handling failures. If something went wrong mid-transaction, you could end up with in-doubt states and locked resources in the database. Now you’re troubleshooting state issues, not writing features.</p><p>Both options forced you to trade off between simplicity and scalability. And neither felt quite right.</p><h3>Sessionless Transactions: Stateless and Scalable</h3><p>Oracle Database 23ai introduced <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/developing-applications-sessionless-transactions.html#GUID-C1F67D04-CE72-416E-8CED-243E5710E83D"><strong>Sessionless Transactions</strong></a>, a new way to manage transactions without locking a session or connection. With this model, you can begin a transaction, release the connection back to the pool, and later resume the same transaction on a completely different connection, even in a different database instance.</p><p>The transaction state travels with a unique identifier, not the connection it started on. This lets your application switch connections freely without losing context.</p><p>This gives you scalability without needing any external coordination logic. You&#39;re no longer stuck holding a connection hostage during think time or while waiting for user input. And unlike XA, there’s no risk of in-doubt transactions due to a failed coordinator.</p><p>Behind the scenes, the database tracks the transaction state. Your application just holds the transaction identifier and resumes when it’s ready to continue.</p><p>Want to dig deeper into the benefits of Sessionless transactions ? Check out this <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/developing-applications-sessionless-transactions.html#GUID-5045682E-4CD7-40DC-98BA-FA658E275D75">link</a>.</p><p><strong>How It Works</strong></p><p>Each Sessionless Transaction is tagged with a unique identifier, transaction ID. You begin a Sessionless Transaction by passing in this ID (if none is provided, the python-oracledb driver generates one for you). After doing part of the work, you can suspend the transaction, release the session back to the pool, and later resume the same transaction on another session using the same ID. The transaction stays intact across sessions and ends only when you explicitly commit or roll it back.</p><p><strong>New APIs That Make It Work</strong></p><p><a href="https://python-oracledb.readthedocs.io/en/latest/">Python-oracledb</a> introduces three new methods to support <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/txn_management.html#sessionless-transactions">Sessionless Transactions</a>:<br><a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.begin_sessionless_transaction">begin_sessionless_transaction()</a>, <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.suspend_sessionless_transaction">suspend_sessionless_transaction()</a> and <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.resume_sessionless_transaction">resume_sessionless_transaction()</a>.</p><pre># To Begin a Sessionless Transaction<br>begin_sessionless_transaction(<br>    transaction_id = None, <br>    timeout = 60, <br>    defer_round_trip = False<br>)<br><br><br># To Suspend a Sessionless Transaction<br>suspend_sessionless_transaction()<br><br><br># To Resume a Sessionless Transaction<br>resume_sessionless_transaction(<br>    transaction_id,<br>    timeout = 60,<br>    defer_round_trip = False<br>)</pre><p>You use these just like they sound. Begin a transaction with a unique ID. Suspend it when you’re done with part of the work. Resume it later using the same ID on a different connection.</p><p>The transaction ID acts as the handle. You can generate your own or let the driver create one for you. The transaction itself lives in the database until you explicitly commit or roll it back. See the <a href="https://python-oracledb.readthedocs.io/en/latest/">documentation</a> for complete method signatures and what each function parameter mean.</p><p><strong>Code Example</strong></p><p>You will walk through a simple use case where a transaction starts on one session, continues on another, and commits from a third, without holding on to any session in between.</p><p><strong>In Session1:</strong></p><p>You begin by starting a new Sessionless Transaction. The python-oracledb driver either uses the transaction ID you provide or generates one for you. In this example, let the driver handle it. The begin_sessionless_transaction call returns a <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.begin_sessionless_transaction">transaction ID</a>, which you save in <em>txn_id</em>. This ID will be used later to resume the same transaction.</p><p>You insert a row in to the table which was already created beforehand. Then, instead of committing or rolling back, you suspend the transaction. This releases the database session back to the pool, freeing up resources.</p><pre># Start a new sessionless transaction on connection 1<br>txn_id = connection1.begin_sessionless_transaction()<br><br># Insert a row<br>cursor1 = connection1.cursor()<br>cursor1.execute(&quot;INSERT INTO TBL_SLST VALUES(1, &#39;row1&#39;)&quot;)<br><br># Suspend the sessionless transaction<br>connection1.suspend_sessionless_transaction()</pre><p><strong>In Session2:</strong></p><p>Later, you acquire a new session from the pool and resume the transaction using the saved <em>txn_id</em>. You add another row and this time suspend using the new <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/cursor.html#Cursor.execute">suspend_on_success</a> flag in the execute() call, to demonstrate how the flag works as an alternative to explicitly calling <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.suspend_sessionless_transaction">suspend_sessionless_transaction()</a>. Instead of making a separate round-trip to suspend, setting suspend_on_success=True performs the suspension right after the successful operation executed in the execute() call. This avoids the extra round-trip and lets you wrap execution and suspension in a single round-trip. Once suspended, the session is released back to the pool.</p><pre># Resume the transaction on connection 2<br>connection2.resume_sessionless_transaction(transaction_id=txn_id)<br><br># Suspend using suspend_on_success flag, after successful execution of DML<br>cursor2 = connection2.cursor()<br>cursor2.execute(<br>    &quot;INSERT INTO TBL_SLST VALUES(2, &#39;row2&#39;)&quot;, <br>    suspend_on_success=True<br>)</pre><p><strong>In Session3</strong></p><p>Finally, you resume the transaction from a third session. Here, you also use the <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.resume_sessionless_transaction">defer_round_trip</a> flag to demonstrate how it can delay the resume until the next database interaction. In this case, both the resume and the insert happen in a single round trip. This helps avoid the extra round trip that would occur with an immediate resume_sessionless_transaction() call, offering a meaningful performance optimization in round-trip-sensitive scenarios. You then query the table and see all the inserted rows—confirmation that the transaction state carried across sessions. A final commit() completes the Sessionless Transaction.</p><pre># Resume the transaction on connection 3 on the next round trip<br>connection3.resume_sessionless_transaction(<br>    transaction_id = txn_id,<br>    defer_round_trip = True<br>)<br><br># Insert another row<br>cursor3 = connection3.cursor()<br>cursor3.execute(&quot;INSERT INTO TBL_SLST VALUES(3, &#39;row3&#39;)&quot;)<br><br># Query rows<br>results = cursor3.execute(&quot;SELECT * FROM TBL_SLST&quot;)<br>rows = results.fetchall()<br>assert len(rows) == 3<br>print(rows)<br><br># Commit<br>connection3.commit()</pre><p>A complete runnable example is available <a href="https://gist.github.com/vignanv/7f9c30d6f26159651c0468348b803677">here</a>. It simulates three separate connections participating in the same Sessionless Transaction. The output shows how inserts happen across connections, and how the transaction state resumes cleanly — even after suspension.</p><h3>When to Use It (and What to Watch For)</h3><p>Sessionless Transactions shine when you want to free up Oracle Database sessions during idle time, like waiting on user input or external APIs. They let you suspend the transaction, release the session, and continue later from a different session without losing the transaction context.</p><p>However, they aren’t suitable for every use case. For instance, if a DDL statement like CREATE TABLE is executed within a Sessionless Transaction, it triggers an implicit commit and ends the transaction immediately.</p><p>It’s worth noting that suspending a Sessionless Transaction only detaches it from the current connection — it doesn’t end the transaction. The transaction continues to exist on the server and expires if it’s not resumed within the timeout you specify when starting it.</p><p><strong>Timeout Behavior</strong></p><p>There are two timeout values to keep in mind:</p><ul><li>The <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.begin_sessionless_transaction">timeout</a> in begin_sessionless_transaction() defines how long the transaction stays alive on the server after being suspended. If it&#39;s not resumed within that window, it expires and is rolled back.<br>For example, in begin_sessionless_transaction(timeout=15), the transaction will expire if not resumed within 15 seconds after being suspended.</li><li>The <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.resume_sessionless_transaction">timeout</a> in resume_sessionless_transaction() controls how long the current connection waits for another connection to finish suspending the transaction before it can resume it. If the other connection doesn&#39;t suspend in time, you get an <a href="https://docs.oracle.com/en/error-help/db/ora-25351/?r=23ai">ORA-25351</a> error. This timeout is short-lived and only matters at resume time. <br>For example, in resume_sessionless_transaction(..., timeout=5), the connection waits up to 5 seconds for another connection to finish suspending the transaction. If it doesn&#39;t happen, it raises <a href="https://docs.oracle.com/en/error-help/db/ora-25351/?r=23ai">ORA-25351</a>.</li></ul><p>Be aware that client-side and server-side (PL/SQL) <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/arpls/DBMS_TRANSACTION.html#GUID-CDFC3371-A0F3-43DA-968F-4C370A2E6FC3">APIs</a> aren’t interchangeable during an active Sessionless Transaction. For example, if you <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.begin_sessionless_transaction">start</a> or <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.resume_sessionless_transaction">resume</a> a transaction using the python-oracledb driver’s client-side API, you must also <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.suspend_sessionless_transaction">suspend</a> and <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.resume_sessionless_transaction">resume</a> it using the same client-side API. Mixing contexts mid-transaction, like starting on the client and trying to <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/arpls/DBMS_TRANSACTION.html#GUID-D884B99F-891C-4668-8FAA-FE2EADD1C903">suspend</a> it from the server, results in <a href="https://docs.oracle.com/en/error-help/db/ora-26211/?r=23ai">ORA-26211</a>. You can safely switch between client and server only after the transaction is suspended, committed, or rolled back.</p><p>To explore further constraints, please refer <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/developing-applications-sessionless-transactions.html#GUID-7F76D67C-4470-4DA3-BAAE-8E243D9FA87B">this</a> link.</p><h3><strong>Wrapping Up</strong></h3><p><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/txn_management.html#sessionless-transactions">Sessionless Transactions</a> in python-oracledb, powered by Oracle Database 23ai, give you precise control without holding connections hostage. You can start, suspend, and resume work across sessions, all while keeping the transaction intact.</p><p>No session hogging. No heavyweight transaction manager. Just a clean, scalable way to manage distributed work. Give it a try.</p><p><a href="https://blogs.oracle.com/dbstorage/post/new-sessionless-transactions-capability-with-oracle-database-23ai">Sessionless Transactions</a> are also supported in other Oracle client drivers, including <a href="https://medium.com/oracledevs/oracle-database-23ai-sessionless-transactions-in-node-oracledb-stateless-and-efficient-50d9fe165c23">Node.js</a> and <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/sessionless-transactions.html#GUID-8330DD73-FB2C-486B-98FC-D3183C5F655E">Java</a>. See the official documentation for details.</p><h3>Python-oracledb Resources</h3><p>Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul><li><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">Installation instructions</a></li><li><a href="https://python-oracledb.readthedocs.io/en/latest/index.html">Documentation</a></li><li><a href="https://github.com/oracle/python-oracledb/discussions">Discussions</a></li><li><a href="https://github.com/oracle/python-oracledb">Source code on GitHub</a></li><li><a href="https://pypi.org/project/oracledb/">PyPI</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b218c6ff62f2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/sessionless-transactions-in-python-oracledb-speed-without-strings-b218c6ff62f2">Sessionless Transactions in Python-oracledb: Speed without Strings</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[No More Credentials: Connect to Oracle Autonomous Database Using Instance Principals in…]]></title>
            <link>https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-instance-principals-in-e213e1f40c44?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/e213e1f40c44</guid>
            <category><![CDATA[instance-principal]]></category>
            <category><![CDATA[token-based-auth]]></category>
            <category><![CDATA[oracle]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Fri, 27 Jun 2025 03:52:08 GMT</pubDate>
            <atom:updated>2025-06-29T07:04:43.323Z</atom:updated>
            <content:encoded><![CDATA[<h3>No More Credentials: Connect to Oracle Autonomous Database Using Instance Principals in python-oracledb 3.2</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*RnDKvdvvWjJfq6R2" /><figcaption>Photo by <a href="https://unsplash.com/@growtika?utm_source=medium&amp;utm_medium=referral">Growtika</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Starting with version 1.1, <a href="https://oracle.github.io/python-oracledb/index.html">python-oracledb</a> introduced support for <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#token-based-authentication">token-based authentication</a>. This capability was enhanced in version 3.0 to include cloud-native authentication using Oracle Cloud Infrastructure (OCI) <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/overview.htm">Identity and Access Management</a> (IAM) tokens. With the 3.2 release, python-oracledb takes it a step further by adding support for Instance Principal authentication: enabling secure, credential-free access from OCI compute resources. This blog walks you through what that means, why it matters, and how to use it.</p><h3><strong>ELI5: What is Instance Principal ?</strong></h3><p>Imagine you have a bunch of computers (called compute instances) running in the cloud, and each one needs permission to talk to other Oracle Cloud services, like a database. In the old way, you’d have to give each computer a secret key (like a password) and keep track of all those keys. That’s hard to manage, not very safe, and quickly becomes a mess.</p><p><strong>Instance Principals</strong> are OCI’s way of saying: <em>“Let me handle that for you.”</em> Each compute instance is treated as a new type of IAM principal (an IAM entity authorized to access OCI resources), similar to a user or group, and is automatically assigned a unique identity in the form of a digital certificate, which it can use to prove who it is. This identity is fully managed by OCI: certificates are created, refreshed, and rotated behind the scenes.</p><p>From a technical perspective, the instance authenticates with OCI IAM using this identity and obtains a short-lived token. That token can then be used to access services like <a href="https://www.oracle.com/in/autonomous-database/">Oracle Autonomous Database</a>, without storing or managing any secrets in your application code.</p><h3><strong>How Instance Principals work ?</strong></h3><h4><strong>Dynamic Groups</strong></h4><p>OCI uses <a href="https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm"><strong>Dynamic Groups</strong></a> to manage access policies for instances. Think of these as IAM groups, but for compute instances. You define <strong>matching rules</strong> (based on instance attributes like compartment ID or tags), and instances that match the criteria are automatically added to the group.</p><p>Example Matching Rule:</p><p><em>ALL {instance.compartment.id = ‘ocid1.compartment.oc1..exampleuniqueID’}</em></p><p>Once instances are part of a dynamic group, you can assign policies that grant them access to specific OCI services-just like you would for user groups.</p><h4><strong>IAM Policies</strong></h4><p>After defining a dynamic group, you need to create IAM policies that specify what those instances are allowed to do. For example:</p><p><em>Allow dynamic-group my-dg to manage autonomous-database-family in tenancy</em></p><p>This policy allows all instances in the my-dg dynamic group full access to Oracle Autonomous Database operations across the tenancy.</p><h3>How to use Instance Principals ?</h3><h4><strong>Prerequisites</strong></h4><ol><li>You should have one or more OCI compute instances already created. For provisioning compute instances, the steps in this <a href="https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/launchinginstance.htm">link</a> can be followed.</li><li>Ensure that OCI Command Line Interface (CLI) is installed on your compute instance(s). You can follow the installation instructions provided <a href="https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm">here</a> for different environments.</li><li>Also, make sure python-oracledb is installed. To install or upgrade it, run:</li></ol><pre>python3 -m pip install oracledb --upgrade</pre><p>See <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb Installation</a> for details.</p><h4><strong>Steps to set up Instance Principals</strong></h4><ol><li><strong>Create a Dynamic Group</strong><br>Define rules to group the compute instances that require access.</li><li><strong>Create an IAM Policy</strong><br>Grant the dynamic group permissions to access the required OCI services (e.g., Oracle Autonomous Database).</li><li><strong>Map Principals to Oracle Database users<br></strong>In the database, create user mappings for your instance principals or dynamic groups.</li><li><strong>Deploy Application on the Compute Instance</strong><br>Developers can now configure their applications to use the Instance Principals provider from OCI SDK. The application will authenticate and make API/database calls — no API keys or config files required.</li></ol><p><strong>Create a Dynamic group</strong></p><p>Create a Dynamic group that matches a set of instances.</p><p>Login to your Oracle Cloud console. Go to<em> Navigation menu → Identity &amp; Security</em>. Under <em>Identity</em>, select <em>Domains</em>. Under <em>Identity domain</em>, select <em>Dynamic groups</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/699/1*7mxXMAvAxAtvn4qHALDueQ.png" /><figcaption>Dynamic groups interface</figcaption></figure><p>Click <em>Create dynamic group</em> and enter the following details.</p><p><em>Name</em>. Provide a unique name for the group. The name must be unique across all groups in your tenancy, dynamic groups, and user groups.</p><p><em>Description. </em>Provide a friendly description (optional).</p><p>The next step is to create matching rules.</p><p>For this, you can use the <em>Rule Builder</em>, or use the text box provided. Resources that meet the rule criteria are members of the group. In this example, let’s use the <em>Rule Builder</em>, which makes it very easy to define the matching rules for a dynamic group and auto-constructs the rule.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/884/1*3tupui4r0O5zWPhnAEzzyA.png" /><figcaption>Create dynamic group</figcaption></figure><p>Choose the attributes that you want to group instances on and add them to the dynamic group. Keep in handy the <a href="https://docs.oracle.com/en-us/iaas/Content/libraries/glossary/ocid.htm">OCID</a>s of compartment(<em>Identity → Compartments → Compartment details</em>) and instance(<em>Compute → Instances → Instance details</em>).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/891/1*USE3dKB-t9nJ6MDSuzkXeg.png" /><figcaption>Create matching rule</figcaption></figure><p>The Rule Builder will auto-populate the matching rule text box with the rule.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/877/1*N3jYXT2ho8u2lzxbgBSguA.png" /><figcaption>Rule builder</figcaption></figure><p>After the Rules are added, click on ‘<em>Create</em>’ button to create a dynamic group. You can see the dynamic group created.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/557/1*OzuF6T5ddh1ACTJ-5fnI4Q.png" /><figcaption>Dynamic group created</figcaption></figure><p><strong>Create an IAM Policy</strong></p><p>Now, create a policy dictating what permissions those instances should receive.</p><p>Go to <em>Identity &amp; Security → Policies → Create Policy</em>.</p><p>Give <em>Name </em>and <em>Description </em>and click on ‘<em>Show manual Editor</em>’. You can give the statement in the text box available.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/773/1*_SYoCbL7NKgawyqvZKOE1A.png" /><figcaption>Create Policy</figcaption></figure><p>The policy gets created.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eBX30xVLGsISY2dZyW-jBg.png" /><figcaption>Policy created</figcaption></figure><p>From the <em>Statements </em>tab, you can verify the policy statements provided, as well as, you can edit the policy further, if required.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*3iGgwXewrefXnGwZoqZ-tw.png" /><figcaption>Edit Policy Statements</figcaption></figure><p><strong>Map Principals to Oracle Database users</strong></p><p>So far so good, your compute instance is authenticated using an instance principal. However, the database still needs to know: <em>“Who is this principal, and what Oracle Database user should I map it to?”</em></p><p>This mapping is not automatic — you must explicitly create users or mappings in the database. Refer this <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/authenticating-and-authorizing-iam-users-oracle-dbaas-databases.html#GUID-1B648FB0-BE86-4BCE-91D0-239D287C638B">link</a> on accessing the database using instance principal.</p><p>There are two ways to map instance principals to database users:</p><p><strong>Option1:</strong> Map your instance OCID to an Oracle Database user (exclusive mapping)</p><p>You create a dedicated database user for a specific OCI principal (e.g., a compute instance).</p><pre>CREATE USER mycomputeuser2 IDENTIFIED GLOBALLY<br>AS &#39;IAM_PRINCIPAL_OCID=ocid1.instance.oc1.ap-mumbai-1.xxxyyy&#39;;<br><br>GRANT CREATE SESSION TO mycomputeuser2;</pre><p>This maps the specified instance OCID to the Oracle Database user mycomputeuser2</p><p><strong>Option2:</strong> Map your dynamic group to a shared Oracle Database user.</p><p>You map a dynamic group of instances to a single shared database user.</p><pre>CREATE USER shared_user IDENTIFIED GLOBALLY<br>AS &#39;IAM_GROUP_NAME=demodg&#39;;<br><br>GRANT CREATE SESSION TO shared_user;</pre><p>This means <em>any</em> instance in the specified dynamic group can log in as shared_user.</p><p>Also, make sure that External authentication is enabled on ADB and <em>identity_provider_type</em> is set to OCI_IAM. Refer ‘Enable IAM Authentication on ADB’ from this <a href="https://medium.com/oracledevs/cloud-native-authentication-in-python-oracledb-using-oci-iam-tokens-96d73db59fe1">link</a> for the steps involved.</p><pre>BEGIN<br> DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION(<br> type =&gt; &#39;OCI_IAM&#39; );<br>END;<br>/<br> <br>SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = &#39;identity_provider_type&#39;;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/951/1*-WfYWqJdez2B5Wz4AvuBfg.png" /><figcaption>Enable External Authentication; Map group to user</figcaption></figure><p>For this demonstration, I’ve used <strong>Option 2</strong> — mapping the dynamic group to a shared database user — which allows all instances in the group to authenticate as shared_user.</p><p><strong>Deploy Application on the Compute Instance</strong></p><p>Now, deploy your application code to the compute instance. The Python example below demonstrates how to connect to Oracle Autonomous Database using <strong>Instance Principal authentication</strong> — with no need for user-managed credentials or configuration files.</p><p>To enable this, the application uses the <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/module.html#oracle-cloud-infrastructure-oci-cloud-native-authentication-plugin">oci_tokens</a> plugin in <a href="https://oracle.github.io/python-oracledb/index.html">python-oracledb</a>.</p><p>To use Instance Principal authentication, set the <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin">auth_type</a> to &quot;<a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin">instanceprincipal</a>&quot; and pass it through <a href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connect_params.html">extra_auth_params</a> in the connection call.</p><pre>import oracledb<br>import oracledb.plugins.oci_tokens<br> <br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3)<br>                    (address=(protocol=tcps)(port=1521)<br>                    (host=adb.ap-mumbai-1.oraclecloud.com))(connect_data=<br>                    (service_name=myclouddb_high.adb.oraclecloud.com))<br>                    (security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br> <br>token_based_auth = {<br>      &quot;auth_type&quot;: &quot;instanceprincipal&quot;<br>}<br> <br>connection = oracledb.connect(<br>              dsn=connect_string, <br>              extra_auth_params=token_based_auth<br>)<br> <br>curr = connection.cursor()<br>sqlText = &quot;select user from dual&quot;<br>curr.execute(sqlText)<br>record = curr.fetchone()<br>print(record)</pre><p>When the application runs, you can verify that instance principal authentication happens successfully and the connection goes through as shared_user, because the dynamic group, demodg, your compute instance belongs to is mapped to that user in the database.</p><pre>$ python ip_demo.py<br>(&#39;SHARED_USER&#39;,)</pre><h3><strong>Conclusion</strong></h3><p>Instance Principals make it easier and safer to authenticate from OCI compute instances without managing user credentials. With support now available in python-oracledb 3.2, you can connect to Oracle Autonomous Database in a secure, cloud-native way using short-lived IAM tokens.<br>Give it a try in your next deployment, and say goodbye to hard-coded secrets :)</p><h3>Python-oracledb Resources</h3><p>Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul><li><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">Installation instructions</a></li><li><a href="https://python-oracledb.readthedocs.io/en/latest/index.html">Documentation</a></li><li><a href="https://github.com/oracle/python-oracledb/discussions">Discussions</a></li><li><a href="https://github.com/oracle/python-oracledb">Source code on GitHub</a></li><li><a href="https://pypi.org/project/oracledb/">PyPI</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e213e1f40c44" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/no-more-credentials-connect-to-oracle-autonomous-database-using-instance-principals-in-e213e1f40c44">No More Credentials: Connect to Oracle Autonomous Database Using Instance Principals in…</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Guide to Creating an OCI IAM User and Password and Connecting to Oracle Autonomous Database]]></title>
            <link>https://medium.com/oracledevs/guide-to-creating-an-oci-iam-user-and-password-and-connecting-to-oracle-autonomous-database-555763127cf9?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/555763127cf9</guid>
            <category><![CDATA[oracle]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[iam-roles]]></category>
            <category><![CDATA[python-oracledb]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Tue, 18 Mar 2025 06:28:50 GMT</pubDate>
            <atom:updated>2025-03-18T19:20:21.995Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qLJJlXOrTX06qpgR" /><figcaption>Photo by <a href="https://unsplash.com/@towfiqu999999?utm_source=medium&amp;utm_medium=referral">Towfiqu barbhuiya</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Oracle Cloud Infrastructure(OCI) provides Identity and Access Management (IAM) to securely authenticate users across its services, enhancing security and streamlining user management. While IAM token-based authentication is commonly used, OCI IAM users can also connect to Autonomous Database (ADB) using an IAM username and password. This guide outlines the steps to configure OCI IAM user credentials, set up the necessary permissions, and connect to ADB using <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb</a>. For detailed configuration steps, refer to the <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/authenticating-and-authorizing-iam-users-oracle-dbaas-databases.html">Oracle Database Security Guide</a>, and explore a series of <a href="https://www.youtube.com/playlist?list=PLdtXkK5KBY5600tYKz2ZJFMGyqn6wWeK0">videos</a> that provide guidance on OCI IAM.</p><h4>Prerequisites</h4><p>Before configuring IAM for the Oracle ADB instance, it is necessary to first provision an Autonomous Database on Oracle Cloud. This can be easily accomplished using an <a href="https://www.oracle.com/cloud/free/"><strong>Always Free</strong></a> account, which provides access at no cost.</p><h4>IAM Setup</h4><p>You need to create an IAM user, group, policies, and configure a database password. Below are the detailed steps.</p><h4>IAM User Creation</h4><p>Login to your Oracle Cloud console. <br>Go to <em>Navigation menu → Identity &amp; Security → Identity → Domains[Domain name] → Users</em>. Click on the ‘Create user’ button. This will take you to the screen below. Provide the details for the IAM user by filling in the details for First name, Last name, Username, Email. Click on the ‘Create’ button to create user ‘<em>vk</em>v’.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/745/1*NmMK2ExbEIXxt5qN05d-tQ.png" /><figcaption>Create user</figcaption></figure><h4>IAM Group Creation</h4><p>A new group for the IAM Users should be created. IAM users can be added to the group.</p><p>Navigate to <em>Identity &amp; Security → Identity → Domains[Domain name] → Groups</em>. Click on the ‘Create group’ button. Give the Name and Description and select the user(<em>vk</em>v) you want to be in this group. Then click the ‘Create’ button to create a group.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/671/1*z_P9-hUGQJMppSeaUr_tPA.png" /><figcaption>Create group</figcaption></figure><p>You can see the group being created and the user ‘<em>vk</em>v’ being in that group. More users can be added by clicking ‘Assign user to groups’ if needed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/656/1*MvLjY9d8T-p_9JzTuwqVhw.png" /><figcaption>Group created</figcaption></figure><h4>Create Policy</h4><p>In order to allow the users in the IAM group to access ADB, we need to create a policy.</p><p>Navigate to <em>Identity &amp; Security → Policies</em>. Click on the ‘Create Policy’ button. In the Create Policy page, provide details for the Name, Description. Enable ‘Show manual editor’ toggle in the ‘Policy Builder’ section and insert the policy statement as ‘allow group IAMUsers19Group to use autonomous-database-family in tenancy’.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/552/1*b_Xi7SqX-71je_RipEoVXA.png" /><figcaption>Create policy</figcaption></figure><p>You can see the policy being created.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/803/1*78ON2mFiJW_4P2jwv0xJnw.png" /><figcaption>Policy created</figcaption></figure><h4>Enable IAM Authentication on ADB</h4><p>The ADB must be configured to use OCI IAM for authentication. To do this, set the Identity Provider type to OCI IAM for the ADB.</p><p>Navigate to the provisioned ADB screen and click ‘SQL’ from the ‘Database actions’ drop down.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/615/1*Gn9MlwCNqnY_EbW3JmH18g.png" /><figcaption>Database actions</figcaption></figure><p>The SQL page is by default logged in as ADMIN. In the console, execute below commands and verify that the ‘identity_provider_type’ is set to OCI_IAM.</p><pre>BEGIN<br>     DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION(<br>              type =&gt; &#39;OCI_IAM&#39; );<br>END;<br><br>SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = &#39;identity_provider_type&#39;;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/968/1*8Wtb88Int3woPPG8s0oqVw.png" /><figcaption>Enable external authentication</figcaption></figure><p>This indicates that External Authentication is enabled on Oracle ADB.</p><h4>Map User and Role</h4><p>Next, we need to map a database global user schema to the IAM group. This can be done with the following command:</p><pre>CREATE USER vkv IDENTIFIED GLOBALLY AS &#39;IAM_GROUP_NAME=IAMUsers19Group&#39;;</pre><p>Then, create a global role for database authorization:</p><pre>CREATE ROLE nwexport_role IDENTIFIED GLOBALLY AS &#39;IAM_GROUP_NAME=IAMUsers19Group&#39;;</pre><p>Finally, grant the required permissions to the newly created global role for the IAM group:</p><pre>GRANT CREATE SESSION TO nwexport_role;<br>GRANT DWROLE TO nwexport_role;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/990/1*SH7Z4nllcQCKLFDh7rJeYg.png" /><figcaption>Grant roles</figcaption></figure><h4>IAM User Database Password creation</h4><p>To access ADB-S, IAM users must configure a new attribute in their user profile — the IAM database password. This password will be used alongside the IAM username, distinct from the existing OCI console password.</p><p>Navigate to <em>Identity &amp; Security → Identity → Domains[Domain name] → Users[vkv]</em>. At the bottom left, under ‘Resources’ tab, click on the ‘Database passwords’ field.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/737/1*AIUvmzJ8cRLjdSUxQojUtw.png" /><figcaption>Database passwords</figcaption></figure><p>Now, click on the ‘Create database password’ button to set a password for the ‘<em>vk</em>v’ user by entering the desired password in the provided field. (To delete the password, click on the three vertical dots at the bottom-right of the screen).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/963/1*5F07lZJVAy-pco5B41Rmlg.png" /><figcaption>Create database password</figcaption></figure><p>Now that we have the IAM user credentials (username/password), let’s explore how to connect to ADB using these credentials using python-oracledb.</p><h4>Connect using python-oracledb</h4><p>Connecting to ADB using IAM user credentials (username/password) follows the same process as a standard user/password connection. Below is a sample for reference that uses <a href="https://blogs.oracle.com/opal/post/how-to-connect-to-oracle-autonomous-cloud-databases">mTLS</a> mode for connection.</p><pre># Example of connecting to ADB using IAM user and password credentials<br> <br>import oracledb<br> <br>user = &quot;vkv&quot;<br>pwd = &quot;password1&quot;<br>wallet_pwd = &quot;password2&quot;<br>wallet_location = &quot;/home/username/Downloads/Wallet_myclouddb19&quot;<br> <br>dsn = &quot;(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps) \<br>       (port=1522)(host=host.oraclecloud.com))(connect_data= \<br>       (service_name=myclouddb19_high.adb.oraclecloud.com)) \<br>       (security=(ssl_server_dn_match=yes)))&quot;<br> <br>conn = oracledb.connect(<br>        user=user, <br>        password=pwd, <br>        dsn=dsn, <br>        wallet_location=wallet_location, <br>        wallet_password=wallet_pwd<br>)<br>print(&quot;Database version is:&quot;, conn.version)<br> <br>curr = conn.cursor()<br> <br>sql_txt = &quot;select sys_context(&#39;userenv&#39;, &#39;current_user&#39;) from dual&quot;<br>curr.execute(sql_txt)<br>records = curr.fetchall()<br>print(f&quot;current_user: {records}&quot;)<br> <br>sql_txt = &quot;select * from session_roles&quot;<br>curr.execute(sql_txt)<br>records = curr.fetchall()<br>print(f&quot;session_roles: {records}&quot;)<br> <br>sql_txt = &quot;select sys_context(&#39;userenv&#39;, &#39;authenticated_identity&#39;) from dual&quot;<br>curr.execute(sql_txt)<br>records = curr.fetchall()<br>print(f&quot;authenticated_identity: {records}&quot;)<br> <br>sql_txt = &quot;select sys_context(&#39;userenv&#39;, &#39;authentication_method&#39;) from dual&quot;<br>curr.execute(sql_txt)<br>records = curr.fetchall()<br>print(f&quot;authenication_method: {records}&quot;)<br></pre><p>Here is the output of the program:</p><pre>$ python3.12 iam_pwd.py<br>Database version is: 19.27.0.1.0<br>current_user: [(&#39;VKV&#39;,)]<br>session_roles: [(&#39;NWEXPORT_ROLE&#39;,), (&#39;DWROLE&#39;,)]<br>authenticated_identity: [(&#39;vkv&#39;,)]<br>authentication_method: [(&#39;PASSWORD_GLOBAL&#39;,)]</pre><p>To verify session-related details, you can execute the following queries and check their outputs.</p><p>The query SELECT sys_context(&#39;userenv&#39;, &#39;current_user&#39;) FROM dual; will display the current user, ensuring that you’re working under the correct session.</p><p>Running SELECT * FROM session_roles; will list the roles assigned to the session, allowing you to confirm the user’s privileges.</p><p>You can verify the authenticated identity with SELECT sys_context(&#39;userenv&#39;, &#39;authenticated_identity&#39;) FROM dual;and determine the method of authentication used with SELECT sys_context(&#39;userenv&#39;, &#39;authentication_method&#39;) FROM dual;.</p><p>These outputs will help you verify the relevant session and authentication details.</p><h4>Conclusion</h4><p>OCI IAM authentication provides a secure and centralized way to manage user access to Oracle Autonomous Database. This guide provided step-by-step instructions to set up an OCI IAM user and password and use those credentials to connect to Oracle Autonomous Database. By leveraging IAM authentication, users can centrally manage access, enforce security policies, and eliminate the need for database-specific credentials, resulting in a more secure, scalable, and streamlined authentication process.</p><h4>Python-oracledb Resources</h4><p>Home page: <a href="https://oracle.github.io/python-oracledb/index.html">oracle.github.io/python-oracledb/index.html</a></p><p>Installation instructions: <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p>Documentation: <a href="https://python-oracledb.readthedocs.io/en/latest/index.html">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p>Release Notes: <a href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p>Discussions: <a href="https://github.com/oracle/python-oracledb/discussions">github.com/oracle/python-oracledb/discussions</a></p><p>Issues: <a href="https://github.com/oracle/python-oracledb/issues">github.com/oracle/python-oracledb/issues</a></p><p>Source Code Repository: <a href="https://github.com/oracle/python-oracledb">github.com/oracle/python-oracledb</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=555763127cf9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/guide-to-creating-an-oci-iam-user-and-password-and-connecting-to-oracle-autonomous-database-555763127cf9">Guide to Creating an OCI IAM User and Password and Connecting to Oracle Autonomous Database</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Handling SSLCertVerificationError in 1-way TLS Connection to Oracle Autonomous Database]]></title>
            <link>https://medium.com/oracledevs/handling-sslcertverificationerror-in-1-way-tls-connection-to-oracle-autonomous-database-fcdcdb237ec1?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/fcdcdb237ec1</guid>
            <category><![CDATA[iam-roles]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-oracledb]]></category>
            <category><![CDATA[ssl]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Sat, 15 Mar 2025 05:43:45 GMT</pubDate>
            <atom:updated>2025-03-18T19:22:15.728Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*zye35ziG2zfNvVXp" /><figcaption>Photo by <a href="https://unsplash.com/@martinsanchez?utm_source=medium&amp;utm_medium=referral">Martin Sanchez</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Oracle Autonomous Database (ADB) supports 1-way TLS authentication, allowing secure connections without requiring a client certificate. However, while connecting using<strong> </strong><a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb</a>, users may encounter an SSLCertVerificationError, preventing successful authentication. This blog explores practical workarounds to resolve the error and establish a smooth connection.</p><p>Before diving into the SSLCertVerificationError, let’s first get a brief overview of 1-way TLS and how ADB can be configured to use it. There are other blogs, like <a href="https://blogs.oracle.com/opal/post/easy-way-to-connect-python-applications-to-oracle-autonomous-databases">this</a> one, that provide a deeper dive into 1-way TLS, which you can refer to for more details.</p><h4>What is 1-way TLS ?</h4><p>1-way TLS (TLS) is a secure communication protocol where only the server’s identity is authenticated using its SSL certificate. The client verifies the server’s certificate to establish trust, but the server does not authenticate the client. This is typically used for secure web browsing or database connections without additional client authentication.</p><p>Applications have the capability to connect to an Oracle Cloud Autonomous Database (ADB) without using a wallet on the client side through 1-way TLS.</p><h4>Configure 1-way TLS on Oracle ADB-S instances</h4><h4>Prerequisites</h4><p>Before configuring 1-way TLS on an Oracle ADB instance, it is necessary to first provision an Autonomous Database on Oracle Cloud. This can be easily accomplished using an <a href="https://www.oracle.com/cloud/free/"><strong>Always Free</strong></a> account, which provides access at no cost.</p><p>By default when an ADB instance is provisioned, it is set to use mTLS authentication:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/431/1*J4IRQEFAgS6c4xCxqIyc9g.png" /><figcaption>Default mTLS</figcaption></figure><p>In order to configure for 1-way TLS, one has to change the <em>Access control list</em> from the above Network configuration. <em>Access control list → Edit.</em></p><p>In the <em>Edit access control list</em> window that pops up, enter your IP address in the <em>Values</em> by selecting <em>IP notation type</em> as <em>IP address. </em>An access control list blocks all IP addresses that are not in the list from accessing the database.</p><p><em>IP notation type → IP address → Add my IP address → Save</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qO7cmzetEnFFDb_0b2Q_iQ.png" /><figcaption>Edit ACL</figcaption></figure><p>Now, after adding the IP address to the ACL, you can disable Mutual TLS(mTLS) authentication by unchecking below checkbox.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/543/1*P1VU9M8XkSDAjiLqJCXvCQ.png" /><figcaption>mTLS check</figcaption></figure><p>The Network section now looks:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*d-cti4SQtfpxaCvKItn3rQ.png" /><figcaption>1-way TLS enabled</figcaption></figure><h4>Get the ADB connection string</h4><p>You are now ready to use 1-way TLS for Oracle ADB in your applications. As we no longer have the <em>tnsnames.ora</em> file, we need to get an ADB connection string to plug into our Python app.</p><p>First, click the ‘<em>Database connection</em>’ button on the ADB instance details page. Under <em>Connection strings, </em>select<em> TLS </em>for<em> TLS authentication </em>and copy the required connection string for the given<em> TNS name.</em></p><p><em>Database connection → Connection strings → TLS authentication → TLS → Connection string → Show → Copy</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/919/1*q7otto2BujuGruK8NsIevg.png" /><figcaption>TLS connection string</figcaption></figure><h4>Connect using 1-way TLS in Python</h4><p>Now that we have the connection string, let’s establish a connection to ADB using python-oracledb.</p><pre>import oracledb<br> <br>username = &quot;admin&quot;<br>password = &quot;password1&quot;<br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3) \<br>                    (address=(protocol=tcps)(port=1521) \<br>                    (host=host.oraclecloud.com))(connect_data= \<br>                    (service_name=myclouddb_high.adb.oraclecloud.com)) \<br>                    (security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br> <br>connection = oracledb.connect(<br>              user=username, <br>              password=password, <br>              dsn=connect_string<br>)<br>print(connection.version)</pre><h4>Understanding SSLCertVerificationError</h4><p>When above program is run, users may encounter SSLCertVerificationError.</p><pre>  <br>ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain</pre><p>The SSLCertVerificationError indicates that the server&#39;s certificate could not be trusted by the client. This can be caused by a missing or outdated CA certificate, an incorrectly configured SSL context, or the client not trusting the certificate presented by the server.</p><p>Ensuring that the correct root certificates are available and properly configured helps resolve this issue. For wallet-less connections, the required trust anchors must be present in the system&#39;s certificate store. Alternatively, if a wallet-based connection is used, the provided wallet must include the necessary trust points.</p><p>Below are a few alternatives to address this issue. You can choose the most suitable solution based on your specific security requirements.</p><h4>Fix 1 — Ensure required certificates included in the connection configuration</h4><p>The required certificate is present in the wallet location, and you can explicitly specify the wallet location in the connect() call. You can refer to <a href="https://blogs.oracle.com/opal/post/how-to-connect-to-oracle-autonomous-cloud-databases">this</a> guide to learn how to download the wallet files.</p><pre>connection = oracledb.connect(<br>              user=username, <br>              password=password, <br>              dsn=connect_string, <br>              wallet_location=&quot;/home/username/Downloads/Wallet_myclouddb&quot;<br>)</pre><h4>Fix 2 — Ensure the certificate is added to the trust store</h4><p>For TLS (one-way) connections, if you prefer not to provide the wallet, you will need to import the server certificate into the system’s (Python’s) certificate store.</p><p>A trust store is a collection of trusted certificates used by the application or system to validate SSL/TLS connections. By adding the self-signed certificate to the trust store, it will be recognized as trusted for future connections.</p><p>On Linux, you can add the self-signed certificate to the system trust store(e.g., <em>/etc/ssl/certs/ca-bundle.crt</em>)</p><p>From Python, you can add the certificate to your application-specific trust store by creating an SSL context with the certificate explicitly trusted:</p><ol><li>Extract the server’s certificate chain using <em>openssl</em>:</li></ol><pre>openssl s_client -connect host.oraclecloud.com:1521 -showcerts</pre><p>This will output the entire certificate chain. Look for sections like:</p><pre>-----BEGIN CERTIFICATE -----<br>(certificate contents)<br>-----END CERTIFICATE -----</pre><p>Save the <strong>root certificate </strong>(the last certificate in the chain) to a file, e.g., <em>/home/username/root_cert.pem</em></p><p>2. In your Python code, create an SSL context that explicitly trusts the saved root certificate. Pass this context to the connect() call when establishing the connection.</p><pre>import oracledb<br>import ssl<br> <br>username = &quot;admin&quot;<br>password = &quot;password1&quot;<br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3) \<br>                    (address=(protocol=tcps)(port=1521) \<br>                    (host=host.oraclecloud.com))(connect_data= \<br>                    (service_name=myclouddb_high.adb.oraclecloud.com)) \<br>                    (security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br> <br># Create an SSL context with the root certificate<br>context = ssl.create_default_context()<br>context.load_verify_locations(&quot;/home/username/root_cert.pem&quot;)<br> <br>connection = oracledb.connect(<br>              user=username, <br>              password=password, <br>              dsn=connect_string, <br>              ssl_context=context<br>)<br> <br>print(connection.version)</pre><h4>Fix 3 — Use a Custom Trust Store with Certifi</h4><p><em>certifi </em>provides a trusted Certificate Authority (CA) bundle, which is a collection of root certificates used to verify the authenticity of server certificates. When you use <em>certifi </em>in your Python application, your connection verifies the server’s SSL certificate against this trusted CA bundle. If the server’s certificate is signed by a CA included in the <em>certifi </em>bundle, SSL verification succeeds.</p><p>Make sure you have <em>certifi </em>installed, if not then run<em> ‘pip install certifi’.</em></p><p>Locate the <em>certifi</em> CA Bundle. Below command will output the path to the <em>certifi</em> CA bundle.</p><pre>$ python3.12 -c &quot;import certifi;print(certifi.where())&quot;<br>/home/username/latest3.12python/newenv/lib/python3.12/site-packages/certifi/cacert.pem</pre><p>Now, adjust your Python script to utilize the <em>certifi</em> CA bundle for SSL verification:</p><pre>import oracledb<br>import ssl<br>import certifi<br> <br>username = &quot;admin&quot;<br>password = &quot;password1&quot;<br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3) \<br>                    (address=(protocol=tcps)(port=1521) \<br>                    (host=host.oraclecloud.com))(connect_data= \<br>                    (service_name=myclouddb_high.adb.oraclecloud.com)) \<br>                    (security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br> <br># Create an SSL context using certifi&#39;s CA bundle<br>ssl_context = ssl.create_default_context(cafile=certifi.where())<br> <br># Connect using the SSL context<br>connection = oracledb.connect(<br>              user=username, <br>              password=password, <br>              dsn=connect_string, <br>              ssl_context=ssl_context<br>)<br>print(connection.version) <br></pre><p>This solution is effective because:</p><ul><li>The <em>certifi</em> library provides a CA certificate bundle, allowing Python to verify the Oracle server’s certificate.</li><li>Using ssl.create_default_context(cafile=certifi.where()) tells Python to trust the CA bundle provided by <em>certifi</em>, avoiding the need to manually specify root certificates.</li><li>The certifi.where() function offers a set of globally trusted root certificates, so if the server’s certificate chain leads to one of these, the verification will succeed without additional configuration.</li></ul><h3>Conclusion</h3><p>Establishing a wallet-less 1-way TLS connection to Oracle Autonomous Database may sometimes lead to SSLCertVerificationError due to missing or untrusted certificates. By ensuring the required certificates are available in the system&#39;s or Python&#39;s certificate store, you can successfully establish a secure connection without relying on a wallet. The fixes outlined above provide alternative solutions to address SSL verification issues, allowing users to select the approach that best aligns with their security requirements.</p><h3>Python-oracledb Resources</h3><p>Home page: <a href="https://oracle.github.io/python-oracledb/index.html">oracle.github.io/python-oracledb/index.html</a></p><p>Installation instructions: <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p>Documentation: <a href="https://python-oracledb.readthedocs.io/en/latest/index.html">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p>Release Notes: <a href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p>Discussions: <a href="https://github.com/oracle/python-oracledb/discussions">github.com/oracle/python-oracledb/discussions</a></p><p>Issues: <a href="https://github.com/oracle/python-oracledb/issues">github.com/oracle/python-oracledb/issues</a></p><p>Source Code Repository: <a href="https://github.com/oracle/python-oracledb">github.com/oracle/python-oracledb</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fcdcdb237ec1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/handling-sslcertverificationerror-in-1-way-tls-connection-to-oracle-autonomous-database-fcdcdb237ec1">Handling SSLCertVerificationError in 1-way TLS Connection to Oracle Autonomous Database</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cloud Native Authentication in python-oracledb using OCI-IAM Tokens]]></title>
            <link>https://medium.com/oracledevs/cloud-native-authentication-in-python-oracledb-using-oci-iam-tokens-96d73db59fe1?source=rss-3861953a94b4------2</link>
            <guid isPermaLink="false">https://medium.com/p/96d73db59fe1</guid>
            <category><![CDATA[oracle]]></category>
            <category><![CDATA[python-oracledb]]></category>
            <category><![CDATA[cloud-native]]></category>
            <category><![CDATA[oracle-cloud]]></category>
            <category><![CDATA[oracle-database]]></category>
            <dc:creator><![CDATA[Vignan. V]]></dc:creator>
            <pubDate>Wed, 05 Mar 2025 04:13:55 GMT</pubDate>
            <atom:updated>2025-03-14T17:39:00.688Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8bVzlahce7XHhkF-" /><figcaption>Photo by <a href="https://unsplash.com/@growtika?utm_source=medium&amp;utm_medium=referral">Growtika</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Authentication is a critical aspect of database security. Traditionally, applications authenticate to databases using usernames and passwords. However, with cloud-native authentication, we can eliminate password-based authentication and instead use tokens issued by an Identity Provider (IdP). This enhances security, simplifies credential management, and improves compliance.</p><p>Cloud-native Authentication allows users to connect to Oracle Database securely without managing passwords. Python-oracledb introduced support for token authentication in version 1.1, and this functionality has now been expanded in the 3.0 release to support cloud-native authentication using Oracle Cloud Infrastructure (OCI) Identity and Access Management (IAM) tokens and Microsoft Azure tokens. This type of authentication is crucial for securing applications interacting with cloud services like Oracle Cloud Infrastructure (OCI) and Azure. Instead of using static credentials, cloud-native authentication leverages temporary access tokens that are automatically generated and refreshed as needed. This approach improves security by reducing the risk of exposing long-lived credentials.</p><p>This blog will guide you on how to use this feature to connect to Oracle Database without a traditional username-password combination.</p><h4>Why Cloud-native Authentication?</h4><ul><li><strong>Improved Security</strong>: Eliminates the need to store and manage passwords.</li><li><strong>Simplified Access Management</strong>: Uses IAM policies to control Database access.</li><li><strong>Better Integration</strong>: Works seamlessly with cloud authentication providers like OCI IAM and Azure.</li></ul><h4>Using OCI IAM Tokens for Authentication</h4><p><strong>Prerequisites</strong></p><p>Before using cloud-native Authentication with OCI IAM with python-Oracledb, ensure you have.</p><ol><li>Access to the Oracle Cloud Autonomous Database(ADB) instance that supports IAM authentication.</li><li>An OCI account with IAM configured.</li><li>The <em>oci </em>Python SDK installed (<em>pip install oci</em>).</li><li>The latest <a href="https://pypi.org/project/oracledb/"><em>python-oracledb</em></a> package installed(<em>pip install oracledb</em>).</li></ol><p><strong>Create Autonomous Database on Oracle Cloud</strong></p><p>You can easily create one using an ‘<a href="https://www.oracle.com/cloud/free/">Always Free</a>’ account at no cost. There are other blogs and documentation available that explain this process in detail. You can look at <a href="https://blogs.oracle.com/database/post/introducing-oracle-autonomous-json-database-for-application-developers">this </a>blog, for instance.</p><p>In short, log in to your cloud account, navigate to the menu, and go to ‘<em>Oracle Database.</em>’ Select the ‘<em>Autonomous Transaction Processing</em>’ section, then click ‘<em>Create Autonomous Database</em>.’ Follow the prompts and enter the required details, such as the database name (e.g., ‘<em>myclouddb</em>’).</p><p>After creating the database, you need to establish a connection with the Autonomous Database (ADB). You can do this using either mTLS or one-way TLS. You can look at the steps mentioned in <a href="https://blogs.oracle.com/opal/post/how-to-connect-to-oracle-autonomous-cloud-databases">this </a>blog for mTLS mode and <a href="https://blogs.oracle.com/opal/post/easy-way-to-connect-python-applications-to-oracle-autonomous-databases">this </a>one for 1-way TLS.</p><p><strong>IAM Setup</strong></p><p>The next step is to setup IAM for the ADB created above.</p><p>One needs to create an IAM user, group, policies before enabling IAM authentication on ADB. Below are the detailed steps.</p><p><strong>IAM User Creation</strong></p><p>Login to your Oracle Cloud console. <br>Go to <em>Navigation menu → Identity &amp; Security → Identity → Domains[Domain name] → Users</em>. This will bring you to below screen, click on the ‘Create user’ button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/1*k6p0rYCFfvljgQVxtt07Vw.png" /><figcaption>IAM Users</figcaption></figure><p>Provide the details for the IAM user by filling in the details for First name, Last name, Username, Email. Click on the ‘Create’ button to create user ‘<em>vk23c</em>’.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/371/1*0Sg6IXxP5oEYQ-Qx5_czBQ.png" /><figcaption>Create User</figcaption></figure><p><strong>IAM Group Creation</strong></p><p>A new group for the IAM Users should be created. IAM users can be added to the group.</p><p>Navigate to <em>Identity &amp; Security → Identity → Domains[Domain name] → Groups</em>. This will bring you the the following page. Click on the ‘Create group’ button.</p><p>Give the <em>Name</em> and <em>Description</em> and select the user you want to be in this group. Then click the ‘Create’ button to create a group.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/397/1*MXl-6loOmOr-AYcheXCZcw.png" /><figcaption>Create group</figcaption></figure><p>You can see the group being created and the user ‘vk23c’ being in that group. More users can be added by clicking ‘Assign user to groups’ if needed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/858/1*oXwcrN8tZRLT_9sizfoFQQ.png" /><figcaption>Created Group</figcaption></figure><p><strong>Create Policy</strong></p><p>In order to allow the users in the IAM group to access ADB, we need to create a policy.</p><p>Navigate to <em>Identity &amp; Security → Policies</em>. Click on the ‘Create Policy’ button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/668/1*gu1dArXLx4YaYzTAMtzXyA.png" /><figcaption>Policies</figcaption></figure><p>In the ‘<em>Create Policy</em>’ page, provide details for the <em>Name</em>, <em>Description</em>. Enable ‘<em>Show manual editor</em>’ toggle in the ‘<em>Policy Builder</em>’ section and insert the policy statement as ‘<em>allow group IAMUsers23c to use autonomous-database-family in tenancy</em>’</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/461/1*-HBF2kVzplmijbZyzyAmwg.png" /><figcaption>Create Policy</figcaption></figure><p>You can see the policy being created.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/592/1*k96Gk92vejTsrI2_rywfEQ.png" /><figcaption>Created Policy</figcaption></figure><p><strong>Enable IAM Authentication on ADB</strong></p><p>The ADB needs to be told to use OCI IAM. For this we need to set the Identity Provider type to OCI IAM for the ADB.</p><p>Navigate to the provisioned ADB screen and click ‘<em>SQL</em>’ from the ‘<em>Database actions</em>’ drop down.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/536/1*EYp9zFQxqpVfqWz6OzjPYQ.png" /></figure><p>The SQL page is by default logged in as ADMIN. In the console, execute below commands and verify that the ‘identity_provider_type’ is set to OCI_IAM.</p><pre>BEGIN<br> DBMS_CLOUD_ADMIN.ENABLE_EXTERNAL_AUTHENTICATION( <br> type =&gt; &#39;OCI_IAM&#39; );<br>END;<br>/<br><br>SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = &#39;identity_provider_type&#39;;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DpY1yMJAT_Hv2wt66xUv5A.png" /><figcaption>IdP set</figcaption></figure><p>This indicates that External Authentication is enabled on Oracle ADB.</p><p><strong>Map User and Role</strong></p><p>Now we need to map a database global user schema to the IAM group</p><pre>CREATE USER vk23c IDENTIFIED GLOBALLY AS &#39;IAM_GROUP_NAME = IAMUsers23c&#39;;</pre><p>Create a global role for database authorization</p><pre>CREATE ROLE export_role IDENTIFIED GLOBALLY AS &#39;IAM_GROUP_NAME=IAMUsers23c&#39;;</pre><p>And finally, grant the required permissions to the newly created global role for the IAM group.</p><pre>GRANT CREATE SESSION TO export_role;<br>GRANT DWROLE TO export_role;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lm9QW5AHWP3lDOUXe8Xr1g.png" /><figcaption>Map User, Role. Grants</figcaption></figure><h4>OCI-CLI Configuration</h4><p>OCI-CLI is a command line interface, it provides the same core functionality as the Oracle Cloud Console.</p><p>You may follow the instructions on <a href="https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm">this </a>page to install the OCI-CLI. Alternatively, you can use the command pip install oci for installation. Once installed, you can verify the success of the installation.</p><pre>$ oci --version<br>3.51.1</pre><p>You need to create an OCI configuration file. For this run,</p><pre>$ oci setup config</pre><p>It will ask for few inputs:.</p><pre>Enter a location for your config[/home/username/.oci/config]:</pre><p>Give a new location or let it take the default location</p><pre>Enter user OCID:</pre><p>One can copy the OCID of the user from <em>Identity &amp; Security -&gt; Domains[Domain name] -&gt; Users[vk23c] -&gt; OCID</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/1*2DWzGU3TMVFtwcX7ci-iWQ.png" /><figcaption>User OCID</figcaption></figure><pre>Enter a tenancy OCID:</pre><p>One can copy the tenancy OCI from <em>Profile(top right) -&gt; Tenancy -&gt; OCID</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*VWoAFKQpBRzuY8i94rUoyQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/644/1*iQRLXLkEXuXl34504YKNPg.png" /><figcaption>Tenancy OCID</figcaption></figure><pre>Enter a region by index or name:</pre><p>You can select from the given list. It’s found on the top right of the OCI Cloud console. Ex: India West(Mumbai)</p><pre>Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to an existing key.) [Y/n]: y</pre><p>Enter <em>y</em></p><pre>Enter a directory for your keys to be created [/home/username/.oci]:</pre><p>You can give a new location or let it be default.</p><pre>Enter a name for your key [oci_api_key]:</pre><p>You can let it to be default value.</p><p>Now, you will get the following output. Note down the path to the public key file.</p><pre>Public key written to: /home/username/.oci/oci_api_key_public.pem</pre><p>It will now ask for a passphrase for private key. Press <em>Enter</em>.</p><pre>Enter a passphrase for your private key (empty for no passphrase):</pre><p>You can see the following output. Both the public and private keys are now generated.</p><pre>Private key written to: /home/username/.oci/oci_api_key.pem<br>Config written to /home/username/.oci/conf</pre><p>The public key is to be uploaded to the OCI cloud. For this, navigate to <em>Identity &amp; Security -&gt; Domains[Domain name] -&gt; Users[vk23c]</em> page.<br>Go to the <em>API Keys -&gt; Add API Keys -&gt; Paste a public key</em>. Paste the contents of public key file(<em>/home/username/.oci/oci_api_key_public.pem</em>) in there.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9LIMWMo0jw9jwCPVoF5_yA.png" /></figure><p>As a final step, cross-check that the following details are present in the OCI config file(<em>~/.oci/config</em>)</p><pre>[DEFAULT]<br>tenancy=&lt;tenancy_ocid&gt;<br>user=&lt;user_ocid&gt;<br>fingerprint=&lt;fingerprint&gt;<br>key_file=~/.oci/oci_api_key.pem<br>region=&lt;region&gt;</pre><p>OCI-CLI configuration is now successful.</p><h4>Connecting to ADB using Cloud-Native Authentication</h4><p>Now in order to use the cloud-native authentication with <a href="https://python-oracledb.readthedocs.io/en/latest/">python-oracledb</a>, ensure you have the latest package. You can install or upgrade python-oracledb by running:</p><pre>python3 -m pip install oracledb --upgrade</pre><p>See <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb Installation</a> for details.</p><p>After successfully installing python-oracledb, you can now connect to ADB without the need for a password. Let’s examine a Python example that demonstrates how authentication is performed using OCI IAM tokens to establish a connection to ADB. To facilitate this, the <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#oci-cloud-native-authentication-with-the-oci-tokens-plugin"><em>oci_tokens</em></a><em> </em>plugin is imported. It is a built-in hook that handles IAM token generation using the OCI Python SDK. The configuration parameters necessary for the cloud provider APIs are supplied via an additional parameter, <em>extra_auth_params</em>, in the connection call.</p><p>Below examples uses TLS mode where you don’t need to provide the wallet location. The configuration parameters are identical to those in the configuration file and are set within the environment, making them available for the application.</p><pre>import oracledb<br>import oracledb.plugins.oci_tokens<br>import os<br><br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=xx.xx.oraclecloud.com))(connect_data=(service_name=xxx_myclouddbname.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br><br>token_based_auth = {<br>      &quot;auth_type&quot;: &quot;simpleAuthentication&quot;,<br>      &quot;user&quot;: os.getenv(&quot;PYO_OCI_USER_OCID&quot;),<br>      &quot;key_file&quot;: os.getenv(&quot;PYO_OCI_KEYFILE&quot;),<br>      &quot;fingerprint&quot;: os.getenv(&quot;PYO_OCI_FINGERPRINT&quot;),<br>      &quot;tenancy&quot;: os.getenv(&quot;PYO_OCI_TENANCY&quot;),<br>      &quot;region&quot;: os.getenv(&quot;PYO_OCI_REGION&quot;),<br>      &quot;profile&quot;: os.getenv(&quot;PYO_OCI_PROFILE&quot;)<br>}<br><br>connection = oracledb.connect(dsn=connect_string, extra_auth_params=token_based_auth)</pre><p>Another supported authentication type for the <em>oci_tokens</em> plugin is shown below. In this method, you only need to provide the configuration file location(default location <em>~/.oci/config</em>) instead of listing all configuration parameters. The built-in plugin automatically reads the required parameters from the specified file. If no location is provided, the default path (<em>~/.oci/config</em>) is used. This configuration file contains all the essential parameters required for the cloud-provider APIs to generate authentication tokens.</p><pre>import oracledb<br>import oracledb.plugins.oci_tokens<br>import os<br><br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=xx.xx.oraclecloud.com))(connect_data=(service_name=xxx_myclouddbname.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br><br>token_based_auth = {<br>      &quot;auth_type&quot;: &quot;configFileAuthentication&quot;,<br>      &quot;file_location&quot;: os.getenv(&quot;PYO_OCI_CONFIG_FILE_LOCATION&quot;)<br>}<br><br>connection = oracledb.connect(dsn=connect_string, extra_auth_params=token_based_auth)</pre><p>Python-oracledb also supports Azure authentication using MSAL (Microsoft Authentication Library). Users can utilize the <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#azure-cloud-native-authentication-with-the-azure-tokens-plugin"><em>azure_tokens</em></a><em> </em>plugin to connect with Azure OAuth2 tokens.</p><p>Here is a sample program illustrating this method (Azure setup is required to run the program. For configuration parameters, more details, refer to the python-oracledb <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#cloudnativeauthoauth">user</a> documentation).</p><pre>import oracledb<br>import oracledb.plugins.azure_tokens<br>import os<br><br>connect_string = &#39;&#39;&#39;(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=xx.xx.oraclecloud.com))(connect_data=(service_name=xxx_myclouddbname.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))&#39;&#39;&#39;<br><br>token_based_auth = {<br>        &quot;auth_type&quot;: os.getenv(&quot;PYO_AZURE_AUTHTYPE&quot;),<br>        &quot;authority&quot;: os.getenv(&quot;PYO_AZURE_AUTHORITY&quot;),<br>        &quot;client_id&quot;: os.getenv(&quot;PYO_AZURE_CLIENTID&quot;),<br>        &quot;client_credential&quot;: os.getenv(&quot;PYO_AZURE_CLIENTSECRET&quot;),<br>        &quot;scopes&quot;: os.getenv(&quot;PYO_AZURE_SCOPES&quot;)<br>}<br><br>connection = oracledb.connect(dsn=connect_string, extra_auth_params=token_based_auth)</pre><h3>Conclusion</h3><p>Cloud-native authentication in python-oracledb enhances security by eliminating stored passwords and leveraging OCI IAM tokens for secure database access. This method aligns with modern cloud security standards, ensuring authorized access through identity-based policies. With support for Azure authentication, it also offers flexibility for multi-cloud environments.</p><p>As cloud-native applications evolve, adopting modern authentication methods like IAM tokens will reduce security risks, improve operational efficiency, and future-proof your applications against credential-based vulnerabilities. Start using cloud-native authentication in python-oracledb today and take advantage of a simpler, safer, and more scalable authentication mechanism!</p><h3>Python-oracledb Resources</h3><p>Home page: <a href="https://oracle.github.io/python-oracledb/index.html">oracle.github.io/python-oracledb/index.html</a></p><p>Installation instructions: <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p>Documentation: <a href="https://python-oracledb.readthedocs.io/en/latest/index.html">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p>Release Notes: <a href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p>Discussions: <a href="https://github.com/oracle/python-oracledb/discussions">github.com/oracle/python-oracledb/discussions</a></p><p>Issues: <a href="https://github.com/oracle/python-oracledb/issues">github.com/oracle/python-oracledb/issues</a></p><p>Source Code Repository: <a href="https://github.com/oracle/python-oracledb">github.com/oracle/python-oracledb</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=96d73db59fe1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/oracledevs/cloud-native-authentication-in-python-oracledb-using-oci-iam-tokens-96d73db59fe1">Cloud Native Authentication in python-oracledb using OCI-IAM Tokens</a> was originally published in <a href="https://medium.com/oracledevs">Oracle Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>