Oracle APEX Web Credentials
Oracle APEX Web Credentials provides a convenient and secure mechanism for storing the following types of credentials:
- Basic Authentication (Username & password)
- OAuth2 Client Credentials (Client ID & Client Secret)
- OCI Native Authentication (Access Oracle Cloud Resources, e.g., Object Storage)
- HTTP Header (The credential is added to the REST request as an HTTP Header)
- URL Query String (The credential is added to the URL of the REST request as a Query String Parameter)
- Web Credentials are stored at the Workspace level and can be referenced by all applications in the workspace. 🧭 Workspace Utilities > Web Credentials
- Once an APEX Web Credential has been created, developers cannot see the secrets associated with the credential (e.g., password, client secret).
- APEX components can utilize Web Credentials to authenticate into the related services (e.g., REST Enabled SQL, Authentication Schemes, and REST Data Sources). Some APEX PL/SQL APIs can also utilize Web Credentials (e.g., APEX_WEB_SERVICE).
This means developers can focus on development, and the security team can focus on securing the credentials.
Web Credentials & Deployment
When you export an APEX application that references a Web Credential, APEX also exports the definition of the credential. ❗APEX never exports the secret part of the credential (e.g., password, client secret).
Different things can happen when you import an application that references a Web Credential, depending on the import method and whether the credential already exists in the target workspace.
Manual Import (APEX Builder)
- If the Web Credential doesn't exist in the target instance, then APEX will prompt you to enter the user name & password, client id & secret, etc., during the application import. In the screenshot below, the credential 'Credentials for CNCD_LOOKUPS' did not exist in the target instance, and I entered the credentials during the import
- If the Web Credential exists in the target instance, it will still be listed, but you cannot update its values. Web credentials already in the target instance will not be updated.
If you import an application using SQLPlus or SQLcl, then you will not be prompted, and the application will be imported as usual.
- If the Web Credential doesn't exist in the target instance, then the definition will be imported without the secret values. You will have to set the secret values manually using APEX Builder or automatically using the APEX_CREDENTIAL API (see below)
- If the Web Credential exists in the target instance, then the existing secret values will not be updated
✏️ APEX uses the Web Credential Static ID to determine if the Web Credential exists in the target workspace.
Automating Creation & Update
If you have many credentials to update, logging into APEX Builder to maintain them is a tedious and error-prone task. There are several situations where credential maintenance is necessary, including; Initial creation, when identity provider credentials expire, and when rotating ORDS OAuth2 credentials.
The excellent news is that you can use the APEX_CREDENTIAL PL/SQL API to script Web Credential maintenance.
Creating a Credential
The code snippet below will create the Web Credential in the screen shot above.
BEGIN -- Set the Workspace. apex_util.set_workspace(p_workspace => 'ABCDEF'); -- Create the Credential apex_credential.create_credential (p_credential_name => 'Test Credentials', p_credential_static_id => 'TEST_CREDENTIALS', p_authentication_type => apex_credential.c_type_oauth_client_cred, p_scope => NULL, p_allowed_urls => apex_t_varchar2('https://example.com/ords/demo/' ), p_prompt_on_install => false, p_credential_comment => 'Test Creating Credential Using API'); -- Set the Client ID and Client Secret for the new Web Credential apex_credential.set_persistent_credentials (p_credential_static_id => 'TEST_CREDENTIALS', p_client_id => 'RZMDcd3FJeqRWAy_DcWokA..', p_client_secret => '8339399393939393393939..' ); COMMIT; END;
Updating a Credential
The code snippet below will update an existing credential.
BEGIN -- Update the Client ID and Client Secret apex_credential.set_persistent_credentials (p_credential_static_id => 'TEST_CREDENTIALS', p_client_id => 'RZMDcd3FJeqRW_CHANGED..', p_client_secret => '8339399393939_CHANGED..' ); COMMIT; END;