As always, the complete, official list of enhancements and fixes can be found here. Contained in this brief post are some of the highlights from this latest release.
My top enhancements
Of the new features the team has published, I’d say these next two are probably going to be the “most sought after” for folks.
Managed service connections
In short, you can now use either Instance Principal and OCI Profile credentials for the db.connectionType in your ORDS configuration settings. Details can be found here.
My takeaways from this:
It is going to make credential storage a LOT easier
Use Instance Principal for when you are using a VM to host ORDS in OCI, and OCI Profile for all else (easy way to look at this without getting too complicated)
I am working on a tutorial for this, using the OCI Profile method. Once I’m back from traveling, I’ll publish on the official Oracle blog site.
JWT Profile at the pool level
The elevator pitch for this: “You know how you could only set a JWT profile for a schema? Well this makes it possible to set this profile at the pool level, for all consumers (schemas) of that pool.” Meaning, this makes it optional, should you want to “share” a JWT Profile across schemas. Details can be found here. Expect an official tutorial soon.
Pre-Authenticated Requests (PARs)
ORDS recently introduced support for Pre-Authenticated Requests (PARs). Well, we now have updates in the SQL Developer Web UI. You can create PARs from within the Resource Handler Dashboard. You can revoke PARs too.
SQL Developer Web UI
Creating a new PAR
Creating a new PAR from an existing Resource Handler is fairly effortless now. After creating the PAR, you’ll be provided a Token, Alias, and complete PAR URI. You’ll see how the URI is a concatenation of the existing URI and the PAR token. But what if you want to revoke access?
Revoking a PAR
PARs are automatically revoked when they expire. You can alternatively revoke the PAR:
In the PAR dashboard, or
From within the same Resource Handler dashboard
PAR Expiration by Alias function
We have introduced a new function that will ingest the PAR alias, and return the time left till expiration. You can find this new function under the ORDS_PAR package of the ORDS_METADATA schema.
I’d like to know, how would you use this though? Would you use this in some sort of automation, or would you somehow display the remaining time on screen (if we are talking about a client application)?
MLE/JS
Now, when a Resource Handler has anything to do with MLE and you encounter an MLE error, you’ll receive a message with a callout to MLE.
Exception handling
In the example below, I’ve created a simple MLE/JS Resource Handler that should display some details about a specified employee (identified by their employee number). However, since this test schema has zero objects in it, I’d expect to receive an error.
In the example below, I use a random employee number, for a non-existent “employees” table. And to truly see the benefits, you’ll want to have the ORDS printDebugToScreen configuration setting set to TRUE.
ORDS CLI
Verify command
I cannot tell you how many times people ask questions that can be answered with this one command.
On its face, it seems trivial, but this is such a nice shortcut to determining if an ORDS installation is valid. I can see this being used in your shell scripts too, for validation. Something like:
sed'ords config --db-pool default verify'
Or perhaps, add it to the compose.yaml file that we include in our ORDS container?
Other/Misc
Want to share your story?
If you’ve stopped by the ORDS product page recently, then you may have seen our latest customer testimonial. Sphere is a heavy consumer of ORDS, and they love the product. If you have an ORDS story to share email me. Let’s collab on a similar write-up.
GitHub
Apparently the oracle/docker-images/ords repo has been “dormant” for quite sometime. Well no more. We (Adrian and I) are now in full control of the ORDS content. So we are updating the Dockerfiles and README. They should be ready in a week or so (end of July 2025), we are finalizing the drafts now. And if you have an outstanding/pending issue you can expect to see some movement on your ticket.
Oracle Container Registry
We have taken your feedback and updated the README for the ORDS official container. You can see the latest here. However, we have another update planned, so if you don’t see your suggestions yet, give us another week! We are updating the README to make it more approachable for a container newbie, and we are adding in some additional, helpful comments in the compose.yaml file too!
Oracle Cloud World 2025
We are in full Cloud World mode now, till the end October. View the details and register here. Kris, Jeff, and I will be there. We’ll be presenting on several topics. But if travel isn’t in your future, never fear, we’ll have recordings of the presentations once Cloud World has wrapped up.
Official Release Notes
And finally, the official release notes can be found here.
ORDS 25.1 is now available, here are the highlights 😀
JWT roles-based scopes
You are probably well aware of our current JWTs authentication and authorization support. But shortly after releasing this functionality, one of our long-time customers asked us to enhance ORDS JWT Profiles so they could also support roles “claims” (and scopes). So now, when creating your ORDS JWT Profile, you can set your p_role_claim_name => '/roles'. This setting would “point” to the roles you have configured within your identity provider (like IAM, IDCS, Auth0, etc.).1
🛎️ Come back to my blog in about two days, and you’ll see a new updated tutorial illustrating this new functionality (with JSON Pointers for the roles-based claim).
In the meantime, be sure to check out my current JWT-related blog posts:
The most significant changes are available options for users you’ve granted the ORDS_ADMINISTRATOR_ROLE.2 Now, you can export another user’s entire schema, including the details for their JWT Profile. In the screenshots below, you’ll see examples of the ORDS_EXPORT_ADMIN.EXPORT_SCHEMA procedure, using various optional parameters.
You have a lot of flexibility here; you can choose which optional parameters to include. Can you spot the differences?
An example showing the ENABLE_SCHEMA and RUNNABLE_AS_ADMIN parameters.An example that consists of the SCHEMA parameter but turns off the RUNNABLE_AS_ADMIN parameter.An example showing the new INCLUDE_JWT_PROFILES parameter.
ORDS_SECURITY updates
The next time you create an ORDS OAuth client, you might notice some changes to the UI. Under the covers, this action is made possible by the ORDS_SECURITY PL/SQL package. You can still use the older, now deprecated OAUTH packages, but we now default to these newer ORDS_SECURITY procedures and functions.
One of the most notable changes is that these procedures now follow the standard convention (you’ve probably seen elsewhere) of showing a Client’s Secret once and only once. The procedure is now more succinct, organized, and secure.
💡When you need a new Client Secret, you can “rotate” it with the new ROTATE_CLIENT_SECRET functions (using the Client Name, Client Id, ORDS/internal Id).
Dark mode
Dark mode is activated. You can set SQL Developer Web (aka Database Actions) to Light, Dark, or Same as browser. I quite like the third option, as it makes shifting from Apple’s Light to Dark Mode seamless.
Including this here to remind you of the other available configurable settings.
DBA_ORDS views
These views aren’t new for this release, but I don’t think we’ve mentioned them recently. Any of your REST-enabled schemas can access these DBA_ORDS_[View Name] views (for their respective schemas), and they are really helpful when you need to quickly view your most important configurations.
Like always, you can drag and drop “objects” into the SQL Worksheet. After dropping, a modal will appear with different options (depending on the object type), allowing you to choose an action.
That’s all for now. I am working on a JWT-using-roles tutorial, which should be out by Friday this week. I’ll update this post when it is live.
And I have another new ORDS plug-in tutorial that I’d like to share; this one is Java-based. My friend Reydan from the Oracle Health (via Cerner) side is integrating the heck out of their stuff with ORDS, and this example is something he came up with as an exploratory exercise. It’s nothing fancy, but I thought it would be great for the beginner.
And that’s all for now!
References
This is known as a JavaScript Object Notation Pointer (JSON Pointer). An upcoming JWT tutorial using role-based claims will provide more details. The technical specifications for the JSON Pointer can be found here. ↩︎
If you are using the Autonomous Database (ADB, ATP, JSON), then you’ll know this ORDS Administrator as your “ADMIN” user. ↩︎
So what even is new in ORDS 24.4? How about an abbreviated list of some fan favorites?
Pre-Authenticated endpoints
Using the new ORDS_PAR PL/SQL package, users can create, revoke, issue and set tokens and token life for specific resources. Your REST-enabled schema will automatically have access to this new feature in 24.4. You can execute these functions and procedures from within the Database Actions SQL Worksheet, the SQL Developer for VS Code extension, the SQL Developer desktop client, and SQLcl (new version out) too!
A mini-tutorial
Here is an easy way to test these new PAR functions and procedures from the SQL Worksheet. First, Select the ORDS_METADATA schema from the SQL Worksheet Navigator. Then, select “All Objects,” scroll down to, and right-mouse-click on the ORDS_PAR PL/SQL package. Then select Run.
The first function you see will be the DEFINE_FOR_HANDLER function. Enter your details in the required fields, and execute the code in the SQL Worksheet. You’ll see a new URI populate.
You can now share that URI (or use it in your test). And it will remain valid for however long you set for the P_DURATION parameter.
Finally, here is an example of using that same PAR URI in a curl command.A reminder of where you can locate all these required fields
Navigate to the REST Workshop; choose your target Resource Module, then…
Next, click the Export Module option.Export your target module in PL/SQL.You can now easily decide which Module, Template, and Handler to use for your PAR.
ORDS Central Configuration
ORDS Central Configuration now natively supports pool identifiers in URLs. We still have the Header method of mapping for Central Configuration. But now we support the Request Host Method, too. For instance, if your Global configuration’s (when using a Central Configuration deployment) URI is:
Your ORDS Central Configuration will take that database pool “prefix” and use it to “look up” that database pool’s settings (in the Central Configuration server). From there, your ORDS instance would have both Global and Pool configuration settings, and it would then be able to satisfy the above GET request.
Previously, to “inform” the Central Configuration of the {host} value (the URI you see in the first code block), you’d have to pass in a request header. YOU CAN STILL DO THIS! But we support both methods now. Depending on your use case, you may prefer one method over the other. Details here.
Plain-text in XML Files
ORDS will notify users when plain-text “secrets,” such as passwords, are present in the ORDS configuration XML files. What does this look like? You can “test” this new functionality by retrieving something like the db.password configuration property.
Typically, ORDS looks for this value in the cwallet.sso file, but you can add it here (it will just be redundant).
Adding the password, in plain text, to a pool.xml configuration file.
We then warn you not once but twice! Once when ORDS first starts up and then again when it fully initializes.
A new ORDS CLI option
The ORDS CLI now includes a script-friendly --quiet option, which hides banner, copyright, and configuration location information from the ORDS STDOUT.
Here is an example where we use the standard command:
ordsconfiggetdb.servicename
Followed by the much leaner version:
ordsconfig--quietgetdb.servicename
As you can see, this makes it much easier for scripts and automation tools to navigate the ORDS STDOUT.
APEX updates to ORDS access logs
Standalone access log records now include an APEX app_id and APEX page_id for records, where applicable. The end of the log captures both app_id and page_id (in this example, 4550:1, respectively).
[0:0:0:0:0:0:0:1] - [21/Nov/2024:17:37:42 +0000] "POST /ords/wwv_flow.accept?p_context=workspace-sign-in/oracle-apex-sign-in/12558700474753 HTTP/1.1" 200 6494 "http://localhost:8080/""Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" 1362 localhost:8080 - 4550:1
In cases where APEX is absent, dashes will replace these fields.
JSON Syntax highlighting
When viewing JSON data from a query result in the SQL Worksheet, pretty printing, and JSON syntax highlighting are now applied. In this example, you’ll notice a single-row table with the column “Glossary.” Clicking the “Eyeball” icon on the Select * From... results reveal this gorgeously formatted and highlighted JSON object.
Click to add Implicit, Handler parameters
You can now add user-defined parameters (i.e., Handler parameters) and Implicit parameters to Handler code blocks with a single mouse click of the parameter name. Take a look at the examples below:
README: We have a TON of additions planned for the Implicit parameters chapter in the ORDS Developer's Guide. You might notice some new additions already. Either way, bookmark this chapter now, as we are also rolling out new in-context code examples and mini-tutorials from now till...we can't anymore.
SQL Worksheet file functionality
You can now rename SQL Worksheet files (from within Database Actions and the OCI console). This update applies to browser files and OCI object storage files. You can now open, rename, and trash these files.
And those are just some of the highlights. But be sure to review the links below!
In response to various support requests and internal feedback, we've expanded on the existing ORDS Status Codes (the current list can be found here)!
Why? The TL;DR is that in many cases, the error or exception caught was being "bucketed" into a category of codes, like a 400 Bad Request or a 500 Internal Service Error. While true, we can be more explicit with some of these error codes. Now, we just have to ask, at what level do we stop?!
Ahem, this sounds like our entire dev team is lazy; it’s quite the opposite. Let me illustrate what’s actually going on with an example from one of our related tickets.
Say a user receives a 503 Service Unavailable server error response. In their Java logs (trace files, access logs, etc.), they also observe an oracle.net.ns.NetException error. While classifying this as a 503 is accurate, we can do better. For instance, you may encounter an oracle.net.ns.NetException with any of the following ORA codes:
In this example, moving forward, instead of receiving a 503, you’ll now receive a 571 server error response.
We’ve done this for several other scenarios, too! Why keep everything generic, as a 503, when we can be more discrete and specific with the information provided? It makes no sense. So, by shifting some of these exceptions to unique response codes, we make it easier for you to identify what is happening.
What if everything was either 200, 400, or 500? Could you imagine?! It would be nearly impossible to quickly identify what is happening in your stack.
ORDS Central Configuration
ORDS now supports deployment in a Central Configuration type deployment.
This one is big. The short version is that we’ve made it so you can dynamically start up and shut down individual ORDS “nodes.” This requires three main pieces, but I’ll try to be brief.
This all assumes you’ve already configured ORDS globally (i.e., you have a global.xml file) as well as your database pools (i.e., the default.xml, database_pool_one.xml, database_pool_two.xml, etc. files). But the idea is such that you’ll have stored in a central Vault/Secrets storage/Key Store your:
ORDS global configuration – which will be in a JSON format (basically a JSON version of the global.xml file)
ORDS database pool configuration/s – the individual configuration files for your ORDS “nodes” (again, just JSON versions of your database-pool.xml files)
A mechanism for the ORDS_PUBLIC_USER to authenticate with the Vault or Keystore (this could also be something as simple as an ORDS webhook that has been protected with an OAuth2.0 client)
*And a conditional fourth item, the makestore or orapki utilities (for creating SSO Wallets).
One way to “do” this (we’ve tested this internally; we just can’t, and won’t endorse, a “one-size fits all” method) is to store your “secrets” in a vault-type service and retrieve them securely and dynamically.
NOTE: The vault contains "secrets," including your global configuration and database pool files. Each of those secrets might be behind an OAuth 2.0-protected endpoint/s.
Separately, and before starting up ORDS, you’d create an SSO Wallet with the credentials for the ORDS_PUBLIC_USER, its password, and additional hostname information (all can be found in our documentation). You’d also choose where to store that Wallet.
Then, before launching ORDS, you’d include two Java options:
Your wallet location (so when ORDS starts up, it is aware of the location of the Wallet and the credentials) and
The REST endpoint (the URI) for your global configuration
Authentication can take several forms here. You can use Basic Authentication (but…don’t, even though we support it, perhaps for testing, but please don’t use it for production), JWTs, or OAuth 2.0. Once the ORDS_PUBLIC_USER has authenticated with its credentials/token, ORDS can acquire its global configuration.
When that HTTP request comes across ORDS, the database pool name can be passed as a header value (we can also read the database pool name if it is appended to the beginning of the URL) and used as a “search” value to retrieve the relevant database_pool-config.json file.
That is ORDS Central Configuration in a nutshell. And since I lost you, I’ll have to write a follow-up blog on this. I don’t blame you; conceptually, it’s tough to envision, but it’s pretty simple in practice. The basic components are laid out in our documents.
OCI Monitoring of ORDS
ORDS now provides a create_alarms.sh script to create ORDS alarms using OCI Monitoring Services, which can be found in the [ords product folder]/examples/ords-metrics directory.
How shall I explain this without getting in trouble with our legal department…? This is being rolled out globally right now for the Oracle Autonomous database. Before this ORDS release, errors or exceptions would be caught and streamed to an OCI metrics dashboard. And you might have seen an ORDS-related exception with a 404 or a 503. Unfortunately, the root-cause analysis would have already been off to a bad start. Because most of these exceptions aren’t just 404s or 503s. There had yet to be a mechanism to make some of these exceptions more discrete. And that is where this create_alarms.sh script enters the chat.
If you review the now-included create_alarms.sh file, you can get an idea of what will now be streamed to your OCI Metrics/Monitoring Explorer. We’ve made it so the ORDS access logs and more appropriate response codes can be streamed to OCI. This makes root-cause analysis and troubleshooting far more straightforward. So if you elect to configure a customer-managed ORDS node, then be sure to take advantage of this new capability.
A new standalone configuration option
New standalone.access.log.retainDays configuration option for ORDS standalone.
Users can now customize the number of days before access log files are overwritten. The default is 90 days, but you can now select the exact number. This, along with numerous other standalone settings can be found in the Understanding Configurable Settings appendix of our ORDS Installation and Configuration Guide.
Java options in the ORDS CLI
Users may now include Java Options parameters when executing ORDS CLI commands.
For instance, a user may execute the following command:
In the above example, you’ve told ORDS to start up, and then, first thing, go to the target URL to retrieve ORDS’ global configuration settings.
You may wonder about JAVA_OPTIONS and JDK_JAVA_OPTIONS; how are those settings impacted? Well, here are some essential details:
ords --java-options only apply to the current ORDS execution.
In order of precedence, options will be picked up like this:
JAVA_OPTIONS are of the highest precedence >>> then >>> ords --java-options >>> then >>> JDK_JAVA_OPTIONS
INFO: Where conflicts arise, ORDS will pick up and use the left-most option.
Jetty 10.0.21
ORDS standalone updates the embedded Jetty Web Sever version 10.0.21.
There’s not much to say here, but if you’d like to learn more about Jetty, I’m including the Operations and Programming guides. When using ORDS in standalone mode, the idea is that Jetty is just there—and it just works.
We’ve architected Standalone mode so that any ORDS configuration can be achieved via the ORDS CLI or by directly manipulating the XML configuration files (while you can do this, you shouldn’t; you might mess up one of the properties in the files). Designing ORDS Standalone mode this way makes it so you don’t really need to do anything Jetty-related. I’m just including the docs if you want something to read on your lunch break 🤪.
Database Actions’ Data Pump
Data Pump allows you to delete jobs and their files from within the Database Actions Data Pump UI. And the Data Pump Import Wizard features some major upgrades and visual enhancements.
Users who have DBMS credentials to access Oracle Cloud Services (via the DBMS_CLOUD.CREATE_CREDENTIAL PL/SQL procedure) can now perform Data Pump Imports from OCI Buckets (previously, it was Resource Principals only). And we’ve added the following abilities/changes:
Buckets from any Compartment level are now accessible
Auto-generated Import Patterns for DMP Files are now included
Automatic mapping for Schemas and Tablespaces is now present
A new “Append Timestamp to Log and Job Names” toggle option has been added
NDJSON files
Users can now import Newline Delimited JSON (NDJSON) or .ndjson files into the SQL Worksheet.
This actually arose from a bug we encountered. After some investigation, the user attempted to import a “Newline Delimited” JSON document. I’m not familiar with this document type, but cursory research reveals the following:
There is currently no standard for transporting instances of JSON text within a stream protocol apart from [Websockets], which is unnecessarily complex for non-browser applications.
A common use case for NDJSON is delivering multiple instances of JSON text through streaming protocols like TCP or UNIX Pipes. It can also store semi-structured data.
If you’d like to learn more about this specification, I recommend visiting this site. It doesn’t seem affiliated with the project, but it is very informative compared to the official NDJSON GitHub page.
Are you using NDJSON now? Or did you just learn of its existence? Do you think you’d start using it, or do you have any use for it? Let me know. I’m curious about the potential applications.
New Walkthroughs (Tours) for Charts and Data Modeler
Updates to the Database Actions Launchpad.
We continue to refine the Launchpad, and these are but two more examples. The Data Modeler and Charts pages have Walkthrough Tours (and documentation too):
What are your thoughts on the new Launchpad? Do you use the “pin” feature? Is it intuitive? What else could we include or improve? Or is it perfect (it’s perfect, isn’t it? …I knew it!)
Java
ORDS requires Oracle Java or Oracle GraalVM Enterprise Edition 11, 17, or 21 to run ORDS 24.2.
If you intend to do anything GraphQL-related, use GraalVM 17. Instructions for downloading can be found here. Just make sure you set your JAVA_HOME to GraalVM 17 so that when ORDS starts up, it does so with GraalVM 17! At this time, ORDS GraphQL support only works with GraalVM 17.