Difficulty: Advanced
Series — Passwordless Fusion integration (part 3) Earlier: Fusion Apps: Call OIC Synchronously as the Real User by using a Native IDCS OAuth Connection (Jul 2026) · Fusion OTBI: Securely obtain a session ID from OIC by using OCI Vault and an Oracle Function (May 2026)
TL;DR
Problem: You can build an OIC estate with no stored passwords — right up to the point where you need BI Publisher. The Oracle ERP Cloud adapter and every Fusion REST connection support JWT User Assertion and OAuth 2.0 Client Credentials, so those connections hold no password. BI Publisher’s report execution API is SOAP (ExternalReportWSSService), the native BIP REST endpoints return 404 in Fusion, and the stock SOAP adapter’s authentication is WS-Security UsernameToken. So one connection in your instance ends up storing a Fusion username and password — and it is usually the one with the widest reach, because reporting touches everything.
What we found: Fusion accepts an OAuth 2.0 bearer token on the BI Publisher SOAP endpoints with no wsse:Security header at all. The password is a limitation of the adapter, not of the service.
Solution: We built CID Fusion BIP, a custom OIC adapter (Rapid Adapter Builder) that exposes both ExternalReportWSSService and ScheduleReportWSSService as typed JSON actions — 48 of them — and posts the SOAP envelope internally with a bearer token. Integration developers map ordinary JSON fields; nobody sees XML, and no connection stores a password.
Download: the adapter definition and setup guides are at the end of this post.
Tested on / Prerequisites
Tested on Fusion 26B · OIC Gen 3 (Gen 2 cannot host RAB adapters) · Fusion and OIC in the same OCI identity domain · an OCI IAM/IDCS Confidential Application allowing the jwt-bearer grant · a signing key uploaded to the OIC keystore with its certificate trusted in the Fusion identity domain · VS Code with the Oracle.oic-rapid-adapter-builder extension (v1.2.0) · an IAM application with the ServiceDeveloper role to register the bundle.
Status note, in the interest of not overselling this: runReport is proven end to end on a live instance — with and without parameters, single and multi-value parameters, PDF output decoding to a valid file, values containing &, < and >, business errors normalized, and reportBytes written to a stage file. The other 47 actions are generated from the instance WSDLs and verified offline (887 checks, including parsing every request envelope with an XML parser), but they have not each been exercised against Fusion. Treat the first live call to any of them as a test. Where that matters is called out below.
Related patterns on this blog
This is the third post in a chain about removing stored credentials from Fusion↔OIC integration. Part 1 brokered OTBI credentials through OCI Vault so they never appear in an OIC flow. Part 2 replaced a username/password BIP HTTP connection — and a hand-rolled OAuth hop — with a native IDCS OAuth connection, so the OIC log shows the real user. This post closes the remaining hole: the BIP connection in the other direction, OIC calling Fusion.
It is also worth reading alongside Groovy → ESS → BIP(HTTP) → OIC async offload, because that pattern is still the right answer for long-running reports. This adapter is for synchronous, bounded calls and for job control — it does not replace ESS-with-wait.
Business Challenge
“No stored passwords” is not a purist position. A password in a connection is a credential nobody rotates, that survives a Production-to-Test clone, that appears in an audit as a shared service account, and that grants whatever that Fusion user can do — which for a reporting account is usually a great deal of data.
The state of play on Fusion connections in OIC:
| Connection | Passwordless option | Status |
|---|---|---|
| Oracle ERP Cloud adapter (REST) | JWT User Assertion, OAuth Client Credentials | Supported [Confirmed] |
| Fusion REST via the REST adapter | OAuth 2.0, JWT assertion | Supported [Confirmed] |
| Fusion SOAP via the SOAP adapter | — WS-Security UsernameToken | Not supported [Confirmed] |
| BI Publisher native REST | — endpoints return 404 in Fusion | Not available [Confirmed] |
So the design that is otherwise clean acquires one exception, and that exception is BI Publisher: ExternalReportWSSService.runReport is the supported synchronous path for running a report from OIC, and the stock route to it wants a username and password.
The usual workarounds are all worse than they look. Storing the password in the connection and “reviewing it later” means it is still there at the next P2T. Brokering it from OCI Vault at runtime — our own pattern P7 — protects the secret in transit and in logs but does not eliminate it; you still have a Fusion password, just better hidden. Wrapping BIP behind an OCI Function to do the auth adds a component, a deployment and a cold start to every report call.
Solution Overview
Oracle Integration 3 ships the Rapid Adapter Builder (RAB): you describe a custom adapter in a JSON adapter definition document, build it into a .rab bundle from VS Code, and register it to an OIC instance, where it appears in Design → Adapters and can be used to create connections like any Oracle-supplied adapter.
The critical enabler is the finding above. We verified it outside OIC first, with a plain HTTP call carrying only Authorization: Bearer … and no wsse:Security header, against /xmlpserver/services/ExternalReportWSSService. Fusion returned the report. [Confirmed by testing]
That means a custom adapter can:
- Declare the managed OAuth security policies — Client Credentials, Authorization Code, and JWT User Assertion — and no password property. The managed policy acquires and attaches the token; the adapter never handles a credential.
- Expose each SOAP operation as a JSON action whose input schema mirrors the SOAP structure, so the mapper shows typed fields.
- Build the SOAP envelope internally from those fields, escaping
&,<and>, POST it, and extract the response back into named JSON fields. - Normalize faults into a uniform
errorCode/errorMessagecontract, so a business error is never a bare HTTP 500 and never passes as success.
Coverage in 2.1.0, from the instance WSDLs rather than from documentation:
| Service | Path | Actions | Group in the wizard |
|---|---|---|---|
ExternalReportWSSService | /xmlpserver/services/ExternalReportWSSService | 29 | BI Publisher — Reports |
ScheduleReportWSSService | /xmlpserver/services/ScheduleReportWSSService | 19 | BI Publisher — Scheduling |
Reports covers execution, catalog access, templates and data chunks. Scheduling covers job submission, history, output retrieval, delivery info, and cancel/suspend/resume/resend.
Implementation Details
1. What the integration developer actually sees
An invoke, the connection, and an action list grouped by service. For a report:
{
"reportAbsolutePath": "/Custom/Project/Utils/TestReport.xdo",
"attributeFormat": "pdf",
"attributeLocale": "en-US",
"parameterNameValues": [
{ "name": "P_LEDGER", "values": ["Primary Ledger"] },
{ "name": "P_PERIOD", "values": ["AUG-26", "SEP-26"] }
]
}
and back:
{
"httpStatus": 200,
"reportBytes": "<base64>",
"reportContentType": "application/pdf",
"metaDataTag": "",
"errorCode": "",
"errorMessage": ""
}
No envelope, no namespaces, no wsse header, no password. Multi-value parameters work; values containing &, < or > are escaped by the adapter, so there is nothing to pre-encode.
reportBytes is base64 exactly as BIP returned it. Map it through the mapper’s base64-decode into a Stage File → Write File and use the staged file reference downstream. Do not decode a PDF or XLSX into a string variable — that corrupts it by construction.
2. Two WSDL details that will bite anyone building this themselves
Both are the kind of thing that produces a well-formed envelope which Fusion rejects, and neither is visible in any structural validation.
elementFormDefault differs between the two services. ExternalReportWSSService is qualified — every child element carries the namespace prefix. ScheduleReportWSSService is unqualified — only the operation element is prefixed and the children are bare:
<!-- ExternalReportWSSService: children prefixed -->
<pub:isReportExist><pub:reportAbsolutePath>/Custom/…</pub:reportAbsolutePath></pub:isReportExist>
<!-- ScheduleReportWSSService: children bare -->
<sch:getReportHistoryInfo><jobInstanceID>12345</jobInstanceID></sch:getReportHistoryInfo>
Get it backwards and every call to that service fails while the other works perfectly.
Both services are SOAP 1.2. Envelope namespace http://www.w3.org/2003/05/soap-envelope, Content-Type: application/soap+xml. A SOAP 1.1 envelope with text/xml is refused. We lost time here because a SOAP fault came back gzipped and read as a small binary body that looked like a successful document. If you test a BIP endpoint with curl, always use curl --compressed.
3. Install the adapter
Full detail is in INSTALL.md in the download; the shape of it:
Cmd+Shift+P→ RAB: Initialize Workspace in an empty folder, then copy the downloaded.add.jsonover thedefinitions/main.add.jsonthe initializer created.- Configure a publisher profile from the OIC Rapid Adapter Builder sidebar → Publisher Profiles → Edit. It needs
publisherId,host,integrationInstance, andauthfor an IAM application with the ServiceDeveloper role. On macOS this file lives under$TMPDIR, which is periodically purged — keep the values somewhere durable. - RAB: Validate → RAB: Create RAB Bundle → RAB: Register RAB Bundle. Check the active profile first: there is no confirmation prompt.
- Design → Adapters to confirm the version.
Bundles are per OIC instance and are not carried by integration or configuration-set export. DEV, TEST and PROD are three separate registrations, and this belongs in your P2T runbook next to connection re-creation. A missing bundle in TEST presents as an integration that cannot be activated — a confusing symptom if nobody wrote the step down.
4. Create the connection
Design → Connections → Create → CID Fusion BIP.
| Field | Value |
|---|---|
| Fusion Base URL | the Fusion host; a trailing slash is tolerated |
| Assertion Issuer (iss) | client id of the IDCS Confidential Application |
| Assertion Subject (sub) | a real Fusion username — the identity every report runs as |
| Assertion Audience (aud) | e.g. https://identity.oraclecloud.com/ |
| Signing Key Alias (kid) | alias of the signing key in the OIC keystore |
| Security policy | OAuth using JWT User Assertion |
| Access Token URI | the identity domain’s token endpoint |
| JWT Private Key Alias | the same alias |
| Scope | as on a working Fusion/ERP Cloud connection |
The signing key must be in that instance’s keystore and its certificate trusted in that identity domain — both are per environment. The IDCS application must allow the jwt-bearer grant, and ideally authenticate the client with client_assertion; if it insists on Basic, an access-token-request override is needed, which stores a client secret in a string property. That is fine for a proof of concept and not fine beyond it — fix the IDCS application instead.
5. Choose the sub before anyone builds against the connection
Every call through one connection runs as that one Fusion user, and the adapter exposes catalog and job administration alongside execution — deleteReport, deleteFolder, purgeJobHistory, updateReportDefinition, the upload family. Fusion privileges on the asserted user are the only control. The adapter enforces nothing, and the identity is shared by every consumer of the connection.
Our recommendation: give the shared connection a read/execute-only BI Publisher identity, and provision a second connection with an authoring identity only in the environment and for the flow that genuinely needs to write. Two connections, not two adapters — the adapter is identity-agnostic.
How to verify
- Test the connection — it should go green.
- Then actually invoke it. Build a one-step integration calling Run BI Publisher Report against a known report and confirm
reportBytesis populated.
Step 2 is not optional, and this is the gotcha we would most like to save you: OIC caches the access token per connection. A green connection test can be reusing a token minted by a configuration you have since changed. We spent an hour convinced an auth change worked because the test was green; it was serving a cached token from a previous attempt. A connection test is not evidence that authentication works.
If you plan to use actions beyond runReport, start with Is Report Exist (smallest possible envelope, proves the Reports path) and one Scheduling action such as Get Report History Info (proves the bare child-element qualification). Those two passing validates the riskiest assumption for the whole set.
Limits, and what this is not
- Synchronous and bounded. The call is limited by report runtime and the OIC invoke timeout. Large or slow reports still belong on ESS-with-wait — that remains our standard for asynchronous BIP, and it also gives you a request id and an audit trail.
- Chunked retrieval is not implemented.
sizeOfDataChunkDownloadis exposed but the whole document returns in one response. Measure the practical size ceiling in your environment before relying on it for large outputs. - The envelope is hand-built and not schema-validated, so a Fusion-side change appears as a runtime fault rather than a design-time error. Run a smoke test per environment after each quarterly Fusion update, and re-verify after each OIC release, which can move the RAB engine underneath the adapter. Name an owner.
scheduleReportis untested at size. Its 114 mappable fields compile to a single 32 KB expression. It is well-formed and correct offline, but whether the runtime expression engine accepts something that large is genuinely unknown. If you need scheduling with exotic delivery channels, prove that action early.- One adapter, not a framework. Wrapping a different SOAP service means new schemas and a new envelope template. The connection shape, the three auth policies, the fault normalization and the offline checks are all reusable; the per-operation mapping is not free.
Download
[cid-fusion-bip-2.1.0.zip] — contains:
cid-fusion-bip-2.1.0.add.json— the adapter definition document, 48 actionsINSTALL.md— prerequisites through to a verified connectionUSAGE.md— for the integration developers who will consume itOPERATION_INVENTORY.md— every action, its input size, the caveats, the governance notesCHANGELOG.md— version history and the rule class of each change
The definition contains no hostnames, no identity-domain ids, no keys and no customer references — every environment-specific value is a connection property you supply, which is what makes it P2T-safe. Provided as-is; test it in a non-production environment first.
Conclusion
The password in your BI Publisher connection is not a Fusion constraint. Fusion has accepted a bearer token on those SOAP endpoints all along; what was missing was an adapter willing to send one. A Rapid Adapter Builder wrapper supplies that, and while it is doing so it can also remove SOAP from the developer experience entirely — 48 operations across both BI Publisher services become typed JSON in a mapper, with one uniform error contract and no envelope anywhere in an integration.
The wider point is about where the exception lives. Before this, a passwordless OIC estate had one documented exception that everybody worked around individually. Now it has a component, in one place, that someone owns — and “no stored passwords” becomes a rule you can actually enforce in a design review rather than an aspiration with a footnote.
Want this in your environment?
Sitting on a BI Publisher connection with a stored Fusion password, and not keen on an OCI Function in the middle of every report call? We proved the bearer-token path end to end, built the adapter, and can register it in your DEV/TEST/PROD instances and wire the IDCS trust, the signing keys and the connection identity correctly — including the part most people get wrong, which is deciding which Fusion user your reporting connection asserts. Reach out at info@cidsolutions.co.il or WhatsApp — let’s get it solved.
Related posts
- Fusion Apps: Call OIC Synchronously as the Real User by using a Native IDCS OAuth Connection
- Fusion OTBI: Securely obtain a session ID from OIC by using OCI Vault and an Oracle Function
- Overcome Groovy execution limits by submitting an OIC integration through an ESS job
- Allow Fusion Cloud ERP users to upload an input file and process it by an OIC interface
- OIC: Fix business event filters that validate but never fire