Skip to content

Commit 2012b3d

Browse files
Added Instance Principal authentication support when using OCI Cloud
Native Authentication.
1 parent 41adca1 commit 2012b3d

File tree

3 files changed

+47
-33
lines changed

3 files changed

+47
-33
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Thick Mode Changes
3737
Common Changes
3838
++++++++++++++
3939

40+
#) Added Instance Principal authentication support when using
41+
:ref:`OCI Cloud Native Authentication <cloudnativeauthoci>`.
4042
#) Use GitHub Arm Linux runner for builds. Supplied by wojiushixiaobai
4143
(`PR 496 <https://github.com/oracle/python-oracledb/pull/496>`__).
4244
#) Fix bug with GitHub build action merge artifacts step

doc/src/user_guide/connection_handling.rst

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4528,11 +4528,15 @@ the following table.
45284528
- Description
45294529
- Required or Optional
45304530
* - ``auth_type``
4531-
- The authentication type. The value should be the string "ConfigFileAuthentication" or "SimpleAuthentication".
4531+
- The authentication type. The value should be the string "ConfigFileAuthentication", "SimpleAuthentication", or "InstancePrincipal".
45324532

4533-
In Configuration File Authentication, the location of the configuration file containing the necessary information must be provided. By default, this file is located at */home/username/.oci/config*, unless a custom location is specified during OCI IAM setup.
4533+
With Configuration File Authentication, the location of a configuration file containing the necessary information must be provided. By default, this file is located at */home/username/.oci/config*, unless a custom location is specified during OCI IAM setup.
45344534

4535-
In Simple Authentication, the individual configuration parameters can be provided at runtime.
4535+
With Simple Authentication, the individual configuration parameters can be provided at runtime.
4536+
4537+
With Instance Principal Authentication, OCI compute instances can be authorized to access services on Oracle Cloud such as Oracle Autonomous Database. Python-oracledb applications running on such a compute instance are automatically authenticated, eliminating the need to provide database user credentials. This authentication method will only work on compute instances where internal network endpoints are reachable. For more information on OCI compute instances, see `OCI Compute Instances <https://docs.oracle.com/en-us/iaas/compute-cloud-at-customer/topics/compute/compute-instances.htm>`__, `Creating a Compute Instance <https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/launchinginstance.htm>`__, and `Calling Services from a Compute Instance <https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm>`__.
4538+
4539+
See `OCI SDK Authentication Methods <https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdk_authentication_methods.htm>`__ for more information.
45364540
- Required
45374541
* - ``user``
45384542
- The Oracle Cloud Identifier (OCID) of the user invoking the API. For example, *ocid1.user.oc1..<unique_ID>*.
@@ -4571,6 +4575,15 @@ the following table.
45714575

45724576
This parameter can be specified when the value of the ``auth_type`` key is "ConfigFileAuthentication".
45734577
- Optional
4578+
* - ``scope``
4579+
- This parameter identifies all databases in the cloud tenancy of the authenticated user. The default value is *urn:oracle:db::id::**.
4580+
4581+
A scope that authorizes access to all databases within a compartment has the format *urn:oracle:db::id::<compartment-ocid>*, for example, urn:oracle:db::id::ocid1.compartment.oc1..xxxxxxxx.
4582+
4583+
A scope that authorizes access to a single database within a compartment has the format *urn:oracle:db::id::<compartment-ocid>::<database-ocid>*, for example, urn:oracle:db::id::ocid1.compartment.oc1..xxxxxx::ocid1.autonomousdatabase.oc1.phx.xxxxxx.
4584+
4585+
This parameter can be specified when the value of the ``auth_type`` key is "SimpleAuthentication", "ConfigFileAuthentication", or "InstancePrincipal".
4586+
- Optional
45744587

45754588
All keys and values other than ``auth_type`` are used by the `OCI SDK
45764589
<https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm>`__ API

src/oracledb/plugins/oci_tokens.py

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ def generate_token(token_auth_config, refresh=False):
4444
return _config_file_based_authentication(token_auth_config)
4545
elif auth_type == "simpleauthentication":
4646
return _simple_authentication(token_auth_config)
47+
elif auth_type == "instanceprincipal":
48+
return _instance_principal_authentication(token_auth_config)
4749
else:
4850
raise ValueError(
4951
f"Unrecognized auth_type authentication method {user_auth_type}"
@@ -86,6 +88,23 @@ def _get_key_pair():
8688
return {"private_key": private_key_pem, "public_key": public_key_pem}
8789

8890

91+
def _generate_access_token(client, token_auth_config):
92+
"""
93+
Token generation logic used by authentication methods.
94+
"""
95+
key_pair = _get_key_pair()
96+
scope = token_auth_config.get("scope", "urn:oracle:db::id::*")
97+
98+
details = oci.identity_data_plane.models.GenerateScopedAccessTokenDetails(
99+
scope=scope, public_key=key_pair["public_key"]
100+
)
101+
response = client.generate_scoped_access_token(
102+
generate_scoped_access_token_details=details
103+
)
104+
105+
return (response.data.token, key_pair["private_key"])
106+
107+
89108
def _config_file_based_authentication(token_auth_config):
90109
"""
91110
Config file base authentication implementation: config parameters
@@ -103,21 +122,7 @@ def _config_file_based_authentication(token_auth_config):
103122
# Initialize service client with default config file
104123
client = oci.identity_data_plane.DataplaneClient(config)
105124

106-
key_pair = _get_key_pair()
107-
108-
response = client.generate_scoped_access_token(
109-
generate_scoped_access_token_details=oci.identity_data_plane.models.GenerateScopedAccessTokenDetails(
110-
scope="urn:oracle:db::id::*", public_key=key_pair["public_key"]
111-
)
112-
)
113-
114-
# access_token is a tuple holding token and private key
115-
access_token = (
116-
response.data.token,
117-
key_pair["private_key"],
118-
)
119-
120-
return access_token
125+
return _generate_access_token(client, token_auth_config)
121126

122127

123128
def _simple_authentication(token_auth_config):
@@ -134,24 +139,18 @@ def _simple_authentication(token_auth_config):
134139
}
135140
oci.config.validate_config(config)
136141

137-
# Initialize service client with given configuration
138142
client = oci.identity_data_plane.DataplaneClient(config)
143+
return _generate_access_token(client, token_auth_config)
139144

140-
key_pair = _get_key_pair()
141145

142-
response = client.generate_scoped_access_token(
143-
generate_scoped_access_token_details=oci.identity_data_plane.models.GenerateScopedAccessTokenDetails(
144-
scope="urn:oracle:db::id::*", public_key=key_pair["public_key"]
145-
)
146-
)
147-
148-
# access_token is a tuple holding token and private key
149-
access_token = (
150-
response.data.token,
151-
key_pair["private_key"],
152-
)
153-
154-
return access_token
146+
def _instance_principal_authentication(token_auth_config):
147+
"""
148+
Instance principal authentication: for compute instances
149+
with dynamic group access.
150+
"""
151+
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
152+
client = oci.identity_data_plane.DataplaneClient(config={}, signer=signer)
153+
return _generate_access_token(client, token_auth_config)
155154

156155

157156
def oci_token_hook(params: oracledb.ConnectParams):

0 commit comments

Comments
 (0)