Oracle ERP Cloud (officially "Oracle Fusion Cloud Applications") is Oracle's cloud-native ERP suite covering financials, procurement, project management, supply chain, and HCM. Authentication is handled centrally through OCI IAM identity domains (formerly Oracle Identity Cloud Service / IDCS). All Fusion Cloud Applications are auto-registered as resource applications in the identity domain, and any third-party integrating system must be registered as a confidential client application. [src1]
This card covers authentication for all Oracle Fusion Cloud REST and SOAP APIs across all editions. It does not cover Oracle NetSuite (which uses Token-Based Authentication / TBA) or Oracle E-Business Suite on-premise (which uses Oracle Access Manager). [src2]
| Property | Value |
|---|---|
| Vendor | Oracle |
| System | Oracle ERP Cloud (Fusion Cloud Applications) Release 25A |
| API Surface | REST, SOAP |
| Current API Version | Release 25A (quarterly: 25A, 25B, 25C, 25D) |
| Editions Covered | All Oracle Fusion Cloud editions |
| Deployment | Cloud |
| API Docs | Oracle Fusion Cloud OAuth Configuration |
| Status | GA |
Oracle ERP Cloud exposes multiple API surfaces for integration. Authentication applies uniformly across all. [src2, src3]
| API Surface | Protocol | Best For | Auth Methods | Real-time? | Bulk? |
|---|---|---|---|---|---|
| REST API | HTTPS/JSON | Individual record CRUD, queries, business object operations | Basic Auth, OAuth 2.0, JWT | Yes | Limited (via FBDI) |
| SOAP API | HTTPS/XML | Web service operations, ERP integration events, legacy | Basic Auth, OAuth 2.0, JWT | Yes | Via ERP Integration Service |
| FBDI (File-Based Data Import) | HTTPS + UCM | High-volume batch imports (journals, invoices, POs) | OAuth 2.0 (via UCM upload) | No | Yes |
| BI Publisher Reports | HTTPS/SOAP | Scheduled extracts, report generation | Basic Auth, OAuth 2.0 | No | Yes |
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Max request body size | Varies by endpoint | REST API | Typically 10 MB; larger payloads via UCM/FBDI |
| Max concurrent requests | Varies by pod/tenant | All API surfaces | No fixed published limit; adaptive throttling |
| Session timeout (default) | 8 hours (28,800s) | All sessions | Configurable in identity domain settings |
| FBDI file size limit | 250 MB | File-Based Data Import | Split larger files into multiple batches |
| Limit Type | Value | Window | Edition Differences |
|---|---|---|---|
| API call rate limit | Not published (fair-use) | Rolling | Oracle uses adaptive throttling; no fixed daily cap |
| Burst throttle | HTTP 429 on excessive calls | Per-minute | Back off exponentially when receiving 429 |
| FBDI jobs | Subject to ESS queue | Per-tenant | Shared with other scheduled processes |
Oracle ERP Cloud supports four authentication methods for API access. OAuth 2.0 is recommended; Basic Auth remains available but should be avoided for production. [src1, src2]
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| OAuth 2.0 Client Credentials (2-legged) | Server-to-server, no user context | Access: 1h (configurable); Refresh: 7d | Yes (with offline_access scope) | Recommended for integrations [src1] |
| OAuth 2.0 Authorization Code (3-legged) | User-context operations, interactive | Access: 1h; Refresh: 7d | Yes | Requires interactive login [src2] |
| OAuth 2.0 Resource Owner (Password) | Highly trusted environments only | Access: 1h | No | Avoid in production; no MFA support [src3] |
| JWT Assertion (Bearer Token) | Server-to-server with certificate trust | Access: 1h (configurable) | New JWT per request | Most secure for M2M [src4] |
| Basic Authentication | Quick testing, legacy only | Session timeout (8h default) | N/A | High credential leakage risk [src3] |
Access token expiry is MIN(configured_expiry, remaining_session_lifetime). Default session lifetime is 8h (28,800s). Configuring a longer token expiry has no effect beyond the session boundary. [src5]
Oracle migrated all IDCS instances to OCI IAM identity domains (Feb 2022 -- mid 2024). Existing OAuth configurations, client IDs, and certificates continue to work. Admin console moved to OCI Console > Identity & Security > Domains. [src7]
| IdP | Protocol | User Provisioning | Notes |
|---|---|---|---|
| Microsoft Entra ID (Azure AD) | SAML 2.0 | Manual or SCIM | Download Entra SAML metadata; configure as IdP in OCI IAM |
| Okta | SAML 2.0 | SCIM (automatic) | Okta as IdP, OCI IAM identity domain as SP |
| Any SAML 2.0-compliant IdP | SAML 2.0 | Manual | Upload IdP metadata document to OCI IAM |
Federation affects interactive (browser-based) authentication only. API-level OAuth flows operate independently. [src7]
START -- Authenticating with Oracle ERP Cloud
|-- What type of integration?
| |-- Server-to-server (unattended, scheduled, middleware)
| | |-- Can you manage certificates?
| | | |-- YES --> JWT Assertion flow (most secure, no shared secrets)
| | | |-- NO --> OAuth 2.0 Client Credentials (simpler setup)
| | |-- Need to act as a specific user?
| | |-- YES --> Client Credentials + service user mapping
| | |-- NO --> Client Credentials with integration user
| |-- User-initiated (interactive, delegated access)
| | |-- Browser-based UI?
| | | |-- YES --> OAuth 2.0 Authorization Code (3-legged)
| | | |-- NO --> Not recommended; use server-side proxy
| | |-- Need SSO with corporate IdP?
| | |-- YES --> SAML 2.0 federation + Authorization Code flow
| | |-- NO --> Authorization Code with identity domain login
| |-- Quick test / debugging
| |-- YES --> Basic Auth (dev/test only, never production)
| |-- NO --> Use OAuth 2.0
|-- Using Oracle Integration Cloud (OIC)?
| |-- YES --> OAuth configured automatically via Fusion Apps identity domain
| |-- NO --> Manual confidential app registration required
|-- LBAC enabled on Fusion Apps?
|-- YES --> Allowlist integration platform NAT Gateway IPs FIRST
|-- NO --> Proceed with auth setup
| Endpoint | URL Pattern | Notes |
|---|---|---|
| Token (IDCS-migrated domain) | https://<tenant>.identity.oraclecloud.com/oauth2/v1/token | For apps in OracleIdentityCloudService domain |
| Token (Default domain) | https://<region>.identity.oraclecloud.com/oauth2/v1/token | For apps in the Default identity domain |
| Authorize (3-legged) | https://<tenant>.identity.oraclecloud.com/oauth2/v1/authorize | Authorization Code flow only |
| JWKS (public keys) | https://<tenant>.identity.oraclecloud.com/admin/v1/SigningCert/jwk | For token validation |
| Userinfo | https://<tenant>.identity.oraclecloud.com/oauth2/v1/userinfo | Returns authenticated user claims |
| Step | Action | Where |
|---|---|---|
| 1 | Navigate to Identity Domain | OCI Console > Identity & Security > Domains |
| 2 | Add Confidential Application | Applications > Add Application |
| 3 | Configure grant types | Client Credentials, Authorization Code, JWT Assertion (as needed) |
| 4 | Set allowed scopes | Add Oracle Fusion Apps resource scopes |
| 5 | Upload certificate (JWT only) | Application > Certificates tab |
| 6 | Note Client ID and Client Secret | Required for token requests |
| 7 | Activate the application | Must be Active to issue tokens |
Create the OAuth client that will authenticate with Oracle ERP Cloud. [src1]
Verify: In the Applications list, confirm Status: Active.
Exchange client credentials for an access token. [src1, src3]
curl -X POST \
"https://<tenant>.identity.oraclecloud.com/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "<CLIENT_ID>:<CLIENT_SECRET>" \
-d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all"
Verify: Response contains "token_type": "Bearer" and "expires_in": 3600.
Use a signed JWT to request a token without sharing a client secret. [src4]
# Generate JWT with claims: iss=CLIENT_ID, sub=CLIENT_ID,
# aud=token_endpoint, exp=now+300, iat=now. Sign with RS256.
curl -X POST \
"https://<tenant>.identity.oraclecloud.com/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer\
&assertion=<SIGNED_JWT>\
&scope=urn:opc:resource:consumer::all"
Verify: Response contains "token_type": "Bearer". No client secret transmitted.
Use the access token to invoke any Fusion Cloud REST endpoint. [src3]
curl -X GET \
"https://<erp-host>.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest/invoices" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json"
Verify: HTTP 200 with JSON payload. If 401, check token expiry and LBAC allowlisting.
For long-running integrations, refresh the token before expiry. [src5]
curl -X POST \
"https://<tenant>.identity.oraclecloud.com/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "<CLIENT_ID>:<CLIENT_SECRET>" \
-d "grant_type=refresh_token&refresh_token=<REFRESH_TOKEN>"
Verify: New access_token and refresh_token in response.
Ensure integration accounts are not blocked by MFA sign-on policies. [src6]
Verify: Service account authenticates via Client Credentials without MFA challenge.
# Input: Oracle ERP Cloud tenant URL, Client ID, Client Secret
# Output: Access token string for API calls
import requests # requests>=2.31.0
def get_oracle_erp_token(tenant_url, client_id, client_secret):
"""Obtain OAuth 2.0 access token from Oracle OCI IAM."""
token_url = f"{tenant_url}/oauth2/v1/token"
response = requests.post(
token_url,
auth=(client_id, client_secret),
data={
"grant_type": "client_credentials",
"scope": "urn:opc:resource:consumer::all"
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
timeout=30
)
response.raise_for_status()
return response.json()["access_token"]
# Input: Private key (PEM), Client ID, Token endpoint
# Output: Access token obtained via JWT assertion
import time
import jwt # PyJWT>=2.8.0
import requests # requests>=2.31.0
def get_oracle_erp_token_jwt(token_endpoint, client_id, private_key_pem):
"""Obtain token using JWT assertion (no shared secret)."""
now = int(time.time())
claims = {
"iss": client_id, "sub": client_id,
"aud": token_endpoint,
"iat": now, "exp": now + 300,
}
signed_jwt = jwt.encode(claims, private_key_pem, algorithm="RS256")
response = requests.post(
token_endpoint,
data={
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": signed_jwt,
"scope": "urn:opc:resource:consumer::all",
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
timeout=30,
)
response.raise_for_status()
return response.json()["access_token"]
// Input: Oracle tenant URL, Client ID, Client Secret
// Output: Cached access token with automatic refresh
class OracleERPAuth {
constructor(tenantUrl, clientId, clientSecret) {
this.tokenUrl = `${tenantUrl}/oauth2/v1/token`;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.token = null;
this.expiresAt = 0;
}
async getToken() {
if (this.token && Date.now() < this.expiresAt - 60000) return this.token;
const credentials = Buffer.from(
`${this.clientId}:${this.clientSecret}`
).toString("base64");
const response = await fetch(this.tokenUrl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${credentials}`,
},
body: "grant_type=client_credentials&scope=urn:opc:resource:consumer::all",
});
if (!response.ok) throw new Error(`Token failed: ${response.status}`);
const data = await response.json();
this.token = data.access_token;
this.expiresAt = Date.now() + data.expires_in * 1000;
return this.token;
}
}
# Test Client Credentials flow
curl -v -X POST \
"https://<tenant>.identity.oraclecloud.com/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "<CLIENT_ID>:<CLIENT_SECRET>" \
-d "grant_type=client_credentials&scope=urn:opc:resource:consumer::all"
# Expected: {"access_token":"eyJ0eXAiOi...","token_type":"Bearer","expires_in":3600}
# Test token against Fusion REST API
curl -X GET \
"https://<erp-host>.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
| Source (Integration Platform) | Target (Oracle OCI IAM) | Type | Transform | Gotcha |
|---|---|---|---|---|
| Client ID | Confidential App Client ID | String | Direct | Must be from the correct identity domain |
| Client Secret | Confidential App Client Secret | String | Direct | Rotate periodically; store in vault |
| Private Key (PEM) | Certificate uploaded to app | RSA Key | Convert from PKCS12 if needed | Must match public cert on app |
| Scope | urn:opc:resource:consumer::all | String | Direct | Or use specific resource scopes |
| Grant type | client_credentials or JWT bearer URN | String | Direct | Must match enabled grant types |
<tenant>.identity.oraclecloud.com; newer domains may use <region>.identity.oraclecloud.com. [src7]openid profile), Oracle uses URN-based scopes. Incorrect scope returns 400 with minimal diagnostics. [src1]client_id:client_secret must be Base64-encoded as a single string. Some HTTP clients handle this automatically. [src3]| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| 401 Unauthorized | Invalid or expired token | Token expired, wrong credentials, or LBAC blocking | Check token expiry; verify LBAC allowlist; re-authenticate |
| 403 Forbidden | Insufficient permissions | Service user lacks required Fusion Cloud role | Assign correct application roles to integration user |
| 400 Bad Request | Invalid token request | Wrong grant_type, missing scope, inactive app | Verify grant type enabled; check scope URN; ensure app Active |
| 429 Too Many Requests | Rate throttled | Excessive API calls | Exponential backoff: wait 2^n seconds, max 5 retries |
| 500 Internal Server Error | Oracle server error | Transient infrastructure issue | Retry with backoff; check Oracle Cloud status page |
| INVALID_CLIENT | Client auth failed | Wrong Client ID or Secret | Verify credentials; check identity domain |
Monitor certificate dates; set reminders 30 days before; automate rotation via OCI Certificate Service. [src4]Use CIDR blocks in LBAC allowlist rather than individual IPs. [src8]Dedicated sign-on policy rule for service accounts positioned above MFA rule. [src6]Verify app's identity domain in OCI Console; use token endpoint from domain config. [src7]Request new token each run for infrequent jobs; or increase refresh token lifetime. [src5]# BAD -- credentials in every request, exposed in logs
response = requests.get(
"https://erp.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest/invoices",
auth=("admin_user", "P@ssw0rd123"), # Credentials in source code!
)
# GOOD -- token-based auth, credentials from environment/vault
import os
token = get_oracle_erp_token(
os.environ["ORACLE_TENANT_URL"],
os.environ["ORACLE_CLIENT_ID"],
os.environ["ORACLE_CLIENT_SECRET"],
)
response = requests.get(url, headers={"Authorization": f"Bearer {token}"})
# BAD -- unnecessary token requests, wastes latency
for invoice_id in invoice_ids:
token = get_oracle_erp_token(tenant, client_id, secret) # New token each time!
response = requests.get(f"{url}/invoices/{invoice_id}",
headers={"Authorization": f"Bearer {token}"})
# GOOD -- single token reused, refreshed proactively
auth = OracleTokenCache(tenant, client_id, secret)
for invoice_id in invoice_ids:
token = auth.get_valid_token() # Cached, auto-refreshes if near expiry
response = requests.get(f"{url}/invoices/{invoice_id}",
headers={"Authorization": f"Bearer {token}"})
-- BAD sign-on policy:
Rule 1: "All Users" --> Require MFA (no exceptions)
-- Service accounts cannot authenticate via OAuth Resource Owner grant
-- GOOD sign-on policy:
Rule 1 (higher priority): "Integration Service Accounts" group --> Allow, no MFA
Rule 2 (lower priority): "All Users" --> Require MFA
-- Service accounts work; human users still require MFA
Migrate to Client Credentials or JWT Assertion for all production integrations. [src3]Cache tokens with expiry tracking; refresh 60s before expiry. [src5]Check LBAC settings first; test from an allowlisted IP to isolate. [src8]Register apps in domain containing Fusion resource apps (typically "OracleIdentityCloudService"). [src7]90-day rotation schedule; use OCI Vault for storage and automation. [src4]Maintain separate OAuth client registrations per environment; use env vars to switch. [src2]# Test token endpoint connectivity
curl -v -X POST \
"https://<tenant>.identity.oraclecloud.com/oauth2/v1/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-u "<CLIENT_ID>:<CLIENT_SECRET>"
# Decode and inspect a JWT access token (without verification)
echo "<ACCESS_TOKEN>" | cut -d'.' -f2 | base64 -d 2>/dev/null | python3 -m json.tool
# Test Fusion Cloud API access with token
curl -w "\nHTTP Status: %{http_code}\n" \
-X GET "https://<erp-host>.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
# Verify identity domain OpenID configuration
curl "https://<tenant>.identity.oraclecloud.com/.well-known/openid-configuration" \
| python3 -m json.tool
# Check if LBAC is causing auth failures (test from known-good IP)
curl -X GET "https://<erp-host>.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-w "\nHTTP: %{http_code}, Remote IP: %{remote_ip}\n"
| Release | Date | Status | Breaking Changes | Migration Notes |
|---|---|---|---|---|
| OCI IAM Identity Domains (GA) | 2022-02 | Current | IDCS admin console moved to OCI Console | All IDCS APIs and endpoints continue to work |
| IDCS Region Migration | 2023-03 to 2024-06 | Complete | Automatic region-by-region migration | No integration changes required |
| Identity Domain Replication | 2024-08 | Current | None | New feature: cross-region DR |
| Fusion Cloud Release 25A | 2025-01 | Current | None auth-related | Quarterly release; API endpoints unchanged |
Deprecation Policy: Oracle has not announced a formal deprecation date for Basic Authentication on Fusion Cloud APIs, but all documentation strongly recommends OAuth 2.0. Plan for eventual deprecation. [src1, src2]
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Building server-to-server integrations with Oracle ERP Cloud | Need Oracle NetSuite authentication (uses TBA) | business/erp-integration/netsuite-api-capabilities/2026 |
| Connecting middleware (OIC, MuleSoft, Boomi) to Fusion Cloud | Need general OAuth 2.0 patterns (not Oracle-specific) | software/patterns/oauth2-client-credentials/2026 |
| Setting up SSO/federation for Oracle ERP Cloud users | Need SAP S/4HANA authentication | business/erp-integration/sap-s4hana-api-capabilities/2026 |
| Migrating from Basic Auth to OAuth 2.0 on Oracle ERP Cloud | Need Oracle E-Business Suite on-premise auth | N/A -- different product line |