IAM policy denied error when accessing Autonomous Database from OCI Compute instance

Our ETL application running on OCI Compute instances is failing to connect to Autonomous Database with an IAM policy denied error. The application uses instance principal authentication to avoid hardcoding credentials.

We’ve created a dynamic group that includes our compute instances and granted it access to the Autonomous Database, but connections still fail with “Authorization failed or requested resource not found” errors.

Our dynamic group matching rule:


ALL {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaa...'}

IAM policy we created:


Allow dynamic-group etl-compute-group to manage autonomous-database-family in compartment ETL-Compartment

The compute instances can access Object Storage using the same instance principal setup, so the dynamic group configuration seems partially working. But Autonomous Database connections keep failing. The ETL failure is blocking our nightly data pipeline. What are we missing in the IAM policy configuration or dynamic group setup?

Instance principal authentication for Autonomous Database requires the instances to have access to the database wallet or use wallet-less connections. If you’re using wallet-less (TLS), make sure your connection string specifies the correct authentication method. Also verify that the Autonomous Database has ‘Allow secure access from everywhere’ enabled or has specific access control rules that include your compute subnet.

That’s likely your issue. Your dynamic group includes instances from Compute-Compartment, but your policy grants access in ETL-Compartment. The instances need to be in the same compartment as specified in the policy, or you need to adjust your policy scope. Try: ‘Allow dynamic-group etl-compute-group to use autonomous-database-family in compartment ETL-Compartment where target.compartment.id = “”’

I’ll provide a comprehensive solution covering your IAM policy configuration, dynamic group setup, and Autonomous Database access issues.

Root Cause Identification:

Your problem stems from three configuration gaps:

  1. Compartment Mismatch: Your dynamic group includes instances from ‘Compute-Compartment’ but the policy grants access to resources in ‘ETL-Compartment’. This creates a scope mismatch.

  2. Overly Broad Permissions: Using ‘manage’ verb for database connectivity is unnecessary and can cause policy evaluation issues.

  3. Missing Network Access Policies: Instance principals need specific permissions to read database connection information and metadata.

Corrected Dynamic Group Configuration:

Your dynamic group matching rule is correct, but verify it includes all necessary compute instances:


ALL {instance.compartment.id = 'ocid1.compartment.oc1...<compute-compartment-ocid>'}

If you have instances across multiple compartments, use:


Any {instance.compartment.id = 'ocid1.compartment.oc1...<compute-comp1>',
     instance.compartment.id = 'ocid1.compartment.oc1...<compute-comp2>'}

Corrected IAM Policy Configuration:

Replace your existing policy with these properly scoped statements:


# Allow database connectivity
Allow dynamic-group etl-compute-group to use autonomous-database-family in compartment ETL-Compartment

# Allow reading database connection strings and metadata
Allow dynamic-group etl-compute-group to read autonomous-databases in compartment ETL-Compartment

# If using Object Storage for wallet (optional)
Allow dynamic-group etl-compute-group to read object-family in compartment ETL-Compartment where target.bucket.name='database-wallets'

Key changes:

  • Changed ‘manage’ to ‘use’ for database access (least privilege)
  • Added ‘read autonomous-databases’ for connection metadata
  • Scoped to specific compartment containing the ADB

Cross-Compartment Access (if needed):

Since your compute and database are in different compartments, you might need tenancy-level policy:


# At tenancy level or in both compartments
Allow dynamic-group etl-compute-group to use autonomous-database-family in compartment ETL-Compartment
Allow dynamic-group etl-compute-group to read autonomous-databases in compartment ETL-Compartment

Autonomous Database Access Configuration:

  1. Network Access: Verify ADB access control list includes your compute subnet or uses ‘Allow secure access from everywhere’

  2. Mutual TLS (mTLS): For wallet-less connections, ensure mTLS is NOT required:

    • In ADB console, go to Network settings
    • Verify ‘Require mutual TLS (mTLS) authentication’ is DISABLED
    • If mTLS is required, you’ll need to download and configure the wallet

Application Code Configuration:

For Java applications using JDBC with instance principal authentication:

// Initialize instance principal provider
InstancePrincipalsAuthenticationDetailsProvider provider =
    InstancePrincipalsAuthenticationDetailsProvider.builder().build();

// JDBC connection string for wallet-less
String url = "jdbc:oracle:thin:@<adb-name>_high?TNS_ADMIN=/path/to/wallet";
// OR for wallet-less with instance principal:
String url = "jdbc:oracle:thin:@<connection-string>";

Properties props = new Properties();
props.put("oracle.net.authentication_services", "(TCPS)");
props.put("javax.net.ssl.trustStore", "/path/to/truststore.jks");
props.put("javax.net.ssl.trustStorePassword", "password");

Connection conn = DriverManager.getConnection(url, props);

For Python applications:

import oci
from oci.auth.signers import InstancePrincipalsSecurityTokenSigner

signer = InstancePrincipalsSecurityTokenSigner()
db_client = oci.database.DatabaseClient(config={}, signer=signer)

Verification Steps:

  1. Test Dynamic Group Membership:
    # From compute instance, test OCI CLI with instance principal
    oci os ns get --auth instance_principal
    
    

   If this works, your dynamic group and basic instance principal setup is correct.

2. **Test Database Access**:
   ```bash
   # List databases to verify IAM permissions
   oci db autonomous-database list --compartment-id <etl-compartment-ocid> --auth instance_principal
   

If this fails, your IAM policy needs adjustment.

  1. Test Database Connection: Use SQLcl or your application to test actual database connectivity with instance principal authentication.

Troubleshooting Tips:

  • Policy Propagation: IAM policy changes can take 30-60 seconds to propagate
  • Audit Logs: Check OCI Audit logs for detailed policy denial reasons
  • Error Messages: “Authorization failed” typically means IAM policy issue, while “Resource not found” might indicate incorrect OCID or compartment
  • SDK Versions: Ensure OCI SDK is up-to-date (instance principal support improved in recent versions)

Common Pitfalls to Avoid:

  1. Don’t use ‘manage’ permissions unless absolutely necessary
  2. Ensure policies exist in the correct compartment hierarchy
  3. Verify compute instances are actually members of the dynamic group (check instance metadata)
  4. For cross-compartment access, policies might need to be at tenancy level
  5. mTLS requirements on ADB will block wallet-less instance principal connections

After applying these changes, restart your ETL application to ensure it picks up the new authentication configuration. The combination of corrected IAM policies, proper dynamic group setup, and verified Autonomous Database access settings should resolve your connectivity issues.

The ‘manage’ verb is too broad and might be causing conflicts. For database connectivity, you don’t need full management permissions. Try using ‘use’ instead: ‘Allow dynamic-group etl-compute-group to use autonomous-database-family in compartment ETL-Compartment’. Also, are your compute instances and the Autonomous Database in the same compartment?

Also check that your application code is correctly requesting instance principal authentication. The OCI SDK needs to be initialized with instance principal provider. For Java it’s ‘InstancePrincipalsAuthenticationDetailsProvider’, for Python it’s ‘oci.auth.signers.InstancePrincipalsSecurityTokenSigner’. If you’re using JDBC, the connection string needs specific parameters for instance principal auth.

The compute instances and ADB are in different compartments - compute is in ‘Compute-Compartment’ and ADB is in ‘ETL-Compartment’. Would that cause the issue? We’re using wallet-less connection with TLS. The ADB access control list shows ‘Allow secure access from everywhere’ is enabled.