← All notes
2026-02-08·4 min read

Creating and Configuring Network ACLs in Oracle Databases (12c+)

OracleDatabaseACL

Scope and Considerations

  • Applies to Oracle Database 12c+
  • Procedure validated against official documentation
  • Requires execution by a SYS or DBA user
  • Compatible with CDB / PDB environments

Problem

By default, Oracle blocks all outbound network access from the database. If a schema attempts to use packages such as:

  • UTL_HTTP
  • UTL_SMTP
  • UTL_TCP
  • UTL_MAIL

without a properly configured ACL, the following error is raised:

ORA-24247: network access denied by access control list (ACL)


Diagnosis

Step 1: Check existing ACLs

Before creating a new ACL, verify whether one already exists:

SELECT * FROM dba_network_acls;

To review existing privileges:

SELECT * FROM dba_network_acl_privileges;

This prevents duplication and configuration conflicts.


Solution

Step 1: Create the ACL

Create a new ACL (using fictitious values):

BEGIN
  DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(
    acl         => 'acl_external_api.xml',
    description => 'ACL for HTTPS access to external API',
    principal   => 'APP_USER',
    is_grant    => TRUE,
    privilege   => 'connect'
  );
END;
/

Important notes

  • ACL file names must be unique
  • The user APP_USER must already exist
  • The recommended initial privilege is CONNECT

Step 2: Grant additional privileges

Grant CONNECT and RESOLVE privileges:

BEGIN
  DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(
    acl       => 'acl_external_api.xml',
    principal => 'APP_USER',
    is_grant  => TRUE,
    privilege => 'connect'
  );

  DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(
    acl       => 'acl_external_api.xml',
    principal => 'APP_USER',
    is_grant  => TRUE,
    privilege => 'resolve'
  );
END;
/

Best practices

  • Grant only required privileges
  • Never grant network privileges to PUBLIC

Step 3: Assign host and port to the ACL

Associate the ACL with a specific host and port:

BEGIN
  DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(
    acl        => 'acl_external_api.xml',
    host       => 'api.example.com',
    lower_port => 443,
    upper_port => 443
  );
END;
/

Recommendations

  • Avoid wildcards (*) unless explicitly approved
  • Restrict port ranges to the minimum required

Step 4: Validate the configuration

SELECT host, lower_port, upper_port, acl
FROM dba_network_acls;
SELECT principal, privilege
FROM dba_network_acl_privileges
WHERE acl = 'acl_external_api.xml';

ACL Validation Script

After configuring the ACL, validate it by performing a simple HTTP request.

SQL Test Script using UTL_HTTP

SET SERVEROUTPUT ON

DECLARE
  l_response CLOB;
BEGIN
  l_response := UTL_HTTP.REQUEST('https://api.example.com');
  DBMS_OUTPUT.PUT_LINE('Connection successful. Response received.');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/

Expected result

  • ACL correctly configured → successful connection
  • Failure → review privileges, host mapping, or certificates

Optional Step: Digital Certificate Configuration (HTTPS)

If the target endpoint uses internal or non-public certificates, Oracle must explicitly trust the certificate chain.

1. Create a wallet

orapki wallet create -wallet /u01/app/oracle/wallets/api_wallet -pwd StrongPassword -auto_login

2. Import root or intermediate certificates

orapki wallet add -wallet /u01/app/oracle/wallets/api_wallet   -trusted_cert -cert api_root_ca.pem -pwd StrongPassword

3. Configure the wallet in the database

With this approach, no database system parameters are configured. The wallet is explicitly referenced at code level, which is more flexible and avoids unnecessary database restarts.

Prerequisites

  • The wallet has already been created using orapki
  • The root or intermediate certificate of the HTTPS endpoint has been imported
  • The database OS user has read permissions on the wallet directory

(The wallet is explicitly defined when making the HTTPS request)

BEGIN
  UTL_HTTP.set_wallet(
    wallet_path => 'file:/u01/app/oracle/wallets/api_wallet',
    wallet_password => 'wallet_password'
  );

  DBMS_OUTPUT.put_line(
    UTL_HTTP.request('https://api.example.com/health')
  );
END;
/

Results

  • Controlled outbound network access enabled
  • Compliance with Oracle security standards
  • HTTPS connectivity from the database validated
  • Auditable and reproducible configuration

Lessons Learned

  • Network ACLs are mandatory in modern Oracle databases
  • Always review existing ACLs before creating new ones
  • Restrict hosts, ports, and users
  • Document and version every change

Recommendation: Use this procedure as a standard for all external integrations from Oracle databases.

Creating and Configuring Network ACLs in Oracle Databases (12c+) · gvargas.site