Oracle Cloud Infrastructure (OCI) is Oracle's next generation IaaS platform that enables building and running a wide range of applications and services in a highly available, hosted environment. OCI offers high-performance compute, storage, overlay virtual network, database, load balancing and numerous other capabilities.
One of the best features of OCI is that it uniformly presents all of its capabilities through the OCI UI Console, SDK, CLI and REST API.
In this blog we will explore how to invoke OCI REST APIs, and examine OCI's REST authentication scheme in detail. I will also provide a sample POSTMAN Collection and Environment script that automates most of the messy details and allows us to seamlessly call OCI APIs.
If the reader is interested in invoking OCI REST API through cURL, please see my colleague Michael Shanley's blog here.
In order to use any of the SDK, CLI or REST API, OCI has a few pre-requisites:
Only an IAM User can can invoke the API. So make sure the users are created.
Generate an RSA key pair and its fingerprint, as mentioned here .
Make note of your OCI tenancy's OCID and the specific user's ( created in #1 above) OCID, as described here .
Upload the generated RSA public key from the key pair , as described here .
Generate the required header and authentication bits and invoke the API.
The steps 1-4 above are relatively straightforward.
Step 5 is already done for you if using the SDK or CLI, but the authentication pieces need to be constructed manually if invoking REST APIs manually, and that is what this blog post is mainly about.
In the sections below we will first understand the authentication scheme for invoking the OCI REST APIs, and then we will explore how we use POSTMAN to invoke the API.
PS: Clients invoking OCI CLI or REST APIs cannot have its clock skewed more than 5 minutes from OCI, otherwise a 401 unauthorized error will be thrown.
PPS: OCI REST APIs require SSL TLS1.2 protocol.
OCI uses the IETF-draft-cavage-http-signatures-08 specification as its authentication scheme, which guarantees that the client is authenticated and the message integrity is preserved (HTTPS or SSL establishes confidentiality).
Understanding the above authentication scheme is a little challenging, below is a summary of the core requirements:
Generate Current Date
Generate API_Key as “tenancyOCID/UserOCID/APIKeyFingerprint”
Generate Signing String
If POST/PUT , generate SHA256, base64 encoded hash of the body and include as part of signing string .
Generate RSA Digital Signature of the SHA256 hash of the Signing String generated above.
Set the formatted Authorization header that includes API Key, Digital Signature(from above step) and other parameters.
Invoke the API with ‘Authorization’, ‘Date’, ‘Content-Type’, and ‘x-content-sha256’ hash of the body(3.a) as Header parameters.
Postman is a GUI-based REST API invocation tool that is very popular among developers. However, even though Postman provides a lot of features, using the authentication scheme above for OCI REST APIs can be challenging.
Hence, I provide some scripts and steps below that can be used to allow invoking OCI REST APIs through Postman . Please follow the steps in the order described.
Download the Postman Collections and Environment from github .
Import the environment into Postman using the 'Import' button at the top, and activate it by selecting it from the top right drop-down as shown below
Open and Edit the newly imported environment, and set the variables tenancyId, authUserId, keyFingerprint and private Key. These are same as what we collected in the Basics section above.Also, make sure to set both Initial Value and Current Value of the variables.
Now import the two collections into Postman.
From the OCI_REST_INITIALIZATION collection, invoke the Initializer GET for 'jsrsasign-all-min.js' , which imports and initializes a required library jsrsasign for encryption and digital signatures. This is a one-time setup task.
That's it. Now you can use the other oci_rest_collection to invoke any OCI REST APIs. The collection provides a sample GET and POST request, which can be extrapolated to invoke any OCI REST API.