This card covers Oracle Fusion Cloud ERP (Releases 25A through 25D, covering 2025-2026) and how its data security framework affects REST API responses for integration users. The data security model applies uniformly across all Oracle Fusion Cloud ERP modules including Financials (GL, AP, AR, FA), Procurement, Project Portfolio Management, and Supply Chain Management. This card does NOT cover Oracle HCM Cloud security profiles, Oracle Integration Cloud adapter-level security, or OCI IAM policies.
| Property | Value |
|---|---|
| Vendor | Oracle |
| System | Oracle Fusion Cloud ERP (Release 25A-25D) |
| API Surface | REST (fscmRestApi) |
| Current API Version | 11.13.18.05 (Release 25A) |
| Editions Covered | All editions (data security is consistent across editions) |
| Deployment | Cloud |
| API Docs | Oracle Financials REST API |
| Status | GA |
Oracle ERP Cloud exposes multiple API surfaces. Data security policies apply to all of them -- REST, SOAP, FBDI file imports, and BIP report extracts all respect the same underlying data security grants.
| API Surface | Protocol | Best For | Data Security Enforced? | Security Mechanism | Notes |
|---|---|---|---|---|---|
| REST (fscmRestApi) | HTTPS/JSON | Individual CRUD, queries, real-time | Yes | DB-layer WHERE clauses via ADF security | Primary integration surface |
| SOAP (composite services) | HTTPS/XML | Legacy integrations | Yes | Same OPSS/data security framework | Being phased out |
| FBDI (File-Based Data Import) | CSV via UCM | Bulk imports, data migration | Partially | Validates on write; user needs target BU access | Bypasses read-side filtering |
| BIP Reports | HTTPS/XML-CSV | Bulk data extracts, scheduled reporting | Yes | Report data security parameters | Ledger/BU parameters required |
| Business Events | REST/webhook | Event-driven, outbound notifications | Yes | Events fire only for data the user can access | Payload scope matches user scope |
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Default page size | 25 records | REST API collection responses | Configurable via limit parameter |
| Max page size | 500 records | REST API collection responses | Use offset for pagination beyond 500 |
| Max request body size | 50 MB | REST API POST/PATCH | Split larger payloads |
| FBDI file size | 250 MB | File-Based Data Import | Split across multiple files for larger loads |
| Limit Type | Value | Window | Notes |
|---|---|---|---|
| REST API calls | No published per-day cap | N/A | Oracle uses fair-use throttling |
| FBDI import jobs | No published cap | N/A | Throttled by ESS queue depth |
| BIP report executions | Configurable by admin | Per-tenant | Default concurrent limit configurable |
| Concurrent long-running requests | Managed by ESS | Per-tenant | ESS work manager thread pool limits |
| Security Dimension | Performance Impact | Mitigation |
|---|---|---|
| Business unit grants (< 5 BUs) | Negligible | Standard configuration |
| Business unit grants (> 20 BUs) | Noticeable query slowdown | Use "All Values" grant where audit allows |
| Cross-module security joins | Moderate (ledger + BU + legal entity) | Pre-build data roles with combined grants |
| Custom policies with complex SQL | Significant | Avoid subqueries; use indexed columns |
Data security is independent of authentication method. All three supported auth flows respect the same data security policies.
| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| Basic Auth over SSL | Testing, simple integrations | Session-based (default 8h) | No | Easiest to set up |
| SAML 2.0 Bearer Token | Enterprise SSO, federated identity | Configurable (1-2h) | Yes (via IdP) | Requires SAML IdP configuration |
| JWT Token | Server-to-server, modern integrations | Configurable (1-2h) | New JWT per request | Recommended for production |
| OAuth 2.0 (via OCI IAM) | Cloud-native integrations | Access: 1h | Yes | Requires OCI IAM domain federation |
items array, not a 401 or 403. This is the most common misdiagnosis. [src1]START -- Integration user gets empty/incomplete data from Oracle ERP Cloud REST API
|
+-- Is authentication succeeding? (HTTP 200 returned?)
| +-- NO (401/403) --> Fix authentication credentials; NOT a data security issue
| +-- YES (200 with empty or partial results) --> Data security filtering is the cause
| |
| +-- Check 1: Does the integration user have a DATA ROLE (not just a job role)?
| | +-- NO --> Create a data role that inherits the job role + security profile
| | +-- YES --> Continue
| |
| +-- Check 2: Correct security context assignments?
| | +-- For Financials (AP/AR): BU assigned? Ledger via Data Access Set? Legal Entity?
| | +-- For Procurement: Procurement BU? Requisitioning BU?
| | +-- For Inventory/SCM: Inventory Organization? Manufacturing Plant?
| | +-- NO --> Add missing security context values
| | +-- YES --> Continue
| |
| +-- Check 3: Session refreshed after grant changes?
| | +-- NO --> Force new session (re-authenticate)
| | +-- YES --> Continue
| |
| +-- Check 4: Custom data security policies with restrictive conditions?
| | +-- YES --> Review instance set SQL WHERE clauses in Security Console
| | +-- NO --> Check module-specific feature opt-in requirements
| |
| +-- Check 5: Data visible in UI when logged in as integration user?
| +-- NO --> Data security configuration issue (fix in Security Console)
| +-- YES --> REST API-specific privilege requirements (check API duty roles)
| Component | Definition | Scope | API Impact |
|---|---|---|---|
| Privilege | Single action on a business object | Per-object/action | Determines which CRUD operations succeed |
| Duty Role | Bundle of related privileges | Per-module | Must include REST API-specific duty roles |
| Job Role | Business role with multiple duty roles | Cross-module | Grants functional access but NOT data access alone |
| Data Role | Job role + security profile | Data-scoped | Controls which records API responses include |
| Security Profile | Defines which data a role can see | Per-dimension | WHERE-clause generator for DB queries |
| Data Access Set | GL-specific: which ledgers a user can access | GL module | Required separately from BU access for GL API calls |
| Security Context | Category of securable values (BU, Ledger, etc.) | Per-module | Each context is an independent filter dimension |
| Instance Set | SQL condition defining which records match | Per-grant | Directly translates to API response filtering |
| Grant | Authorization linking role + privilege + instance set | Per-user/role | The actual enforcement mechanism |
| Module | Security Context | Typical Grant | API Resource Affected |
|---|---|---|---|
| General Ledger | Data Access Set (Ledger) | Specific ledgers or "All Ledgers" | /journals, /accountingPeriods |
| Accounts Payable | Business Unit | Specific BUs or "All BUs" | /invoices, /payments, /suppliers |
| Accounts Receivable | Business Unit | Specific BUs or "All BUs" | /receivablesInvoices, /receipts |
| Fixed Assets | Asset Book | Specific books | /assets, /assetBooks |
| Procurement | Procurement BU + Requisitioning BU | Specific BUs | /purchaseOrders, /requisitions |
| Inventory | Inventory Organization | Specific orgs | /inventoryItems, /inventoryTransactions |
| Project | Project Organization | Specific orgs | /projects, /projectTasks |
Query the data securities REST endpoint to see what access the integration user currently has. [src7]
curl -u "INTEGRATION_USER:password" \
-X GET "https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/dataSecurities?q=UserName=INTEGRATION_USER" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json"
Verify: Response items array contains entries for each required security context. If empty, the user has no data access grants.
Navigate to Security Console and assign the job role that includes the necessary REST API duty roles. [src2]
Navigation: Setup and Maintenance > Security Console > Users
1. Search for integration user
2. Click "Edit" > "Roles" tab
3. Add required job role (e.g., "Accounts Payable Manager")
4. Verify the job role includes REST API duty roles
Verify: In Security Console > Roles > search for the job role > "Privilege" tab, confirm REST-related privileges are present.
The data role pairs the job role with a security profile to scope data visibility. [src1, src5]
Navigation: Setup and Maintenance > Manage Data Access for Users
1. Search for the integration user
2. Click "Add Data Access"
3. Select the role (e.g., "Accounts Payable Manager")
4. Select the security context (e.g., "Business Unit")
5. Select the value(s) (e.g., "US Operations BU", "EU Operations BU")
6. Save
Verify: curl the invoices endpoint and confirm records from the assigned BU appear.
GL access requires separate Data Access Set assignment -- BU grants do not cascade to ledger access. [src1]
Navigation: Setup and Maintenance > Manage Data Access Set Assignments
1. Search for integration user
2. Add data access set (e.g., "US Primary Ledger Access Set")
3. Set access privileges: Read-Only or Read/Write
4. Save
Verify: Query the journals endpoint -- records from the assigned ledger should appear.
Data security changes require a fresh session. Re-authenticate after making grant changes. [src4]
curl -u "INTEGRATION_USER:password" \
-X GET "https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/invoices?limit=5&fields=InvoiceId,InvoiceNumber,BusinessUnit" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json" \
-H "Cache-Control: no-cache"
Verify: Response items array contains records with BusinessUnit values matching your assigned BUs.
# Input: Oracle Fusion Cloud base URL, integration user credentials
# Output: Dictionary of security context assignments per module
import requests
from requests.auth import HTTPBasicAuth
FUSION_BASE = "https://your-instance.fa.us2.oraclecloud.com"
API_PATH = "/fscmRestApi/resources/11.13.18.05"
USERNAME = "INTEGRATION_USER"
PASSWORD = "secure_password"
def get_data_security_assignments(username):
url = f"{FUSION_BASE}{API_PATH}/dataSecurities"
params = {"q": f"UserName={username}", "limit": "500"}
headers = {"Content-Type": "application/vnd.oracle.adf.resourcecollection+json"}
resp = requests.get(url, params=params,
auth=HTTPBasicAuth(USERNAME, PASSWORD),
headers=headers, timeout=30)
resp.raise_for_status()
return resp.json().get("items", [])
def diagnose_missing_data(username):
assignments = get_data_security_assignments(username)
contexts = {}
for a in assignments:
ctx = a.get("SecurityContext", "Unknown")
if ctx not in contexts:
contexts[ctx] = []
contexts[ctx].append(a.get("SecurityContextValue", "N/A"))
required = ["BusinessUnit", "Ledger", "LegalEntity"]
for r in required:
if r not in contexts:
print(f"WARNING: No {r} assignment found for {username}")
else:
print(f"OK: {r} -> {contexts[r]}")
return contexts
# Input: Valid credentials for the integration user
# Output: Record counts per module to verify data security grants
FUSION_BASE="https://your-instance.fa.us2.oraclecloud.com"
API="$FUSION_BASE/fscmRestApi/resources/11.13.18.05"
AUTH="INTEGRATION_USER:password"
echo "=== AP Invoices ==="
curl -s -u "$AUTH" "$API/invoices?limit=1&totalResults=true" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Total: {d.get(\"totalResults\",\"N/A\")}')"
echo "=== GL Journals ==="
curl -s -u "$AUTH" "$API/journals?limit=1&totalResults=true" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Total: {d.get(\"totalResults\",\"N/A\")}')"
# If any module returns Total: 0, the integration user
# is missing data security grants for that module
| Security Context | Grant Type | API Resources Filtered | How to Check Assignment |
|---|---|---|---|
| Business Unit (AP) | Manage Data Access for Users | /invoices, /payments, /suppliers | GET /dataSecurities?q=SecurityContext=BusinessUnit |
| Business Unit (AR) | Manage Data Access for Users | /receivablesInvoices, /receipts | GET /dataSecurities?q=SecurityContext=BusinessUnit |
| Data Access Set (GL) | Manage Data Access Set Assignments | /journals, /accountingPeriods | Separate admin page; not in /dataSecurities |
| Legal Entity | Manage Data Access for Users | /legalEntities, tax resources | GET /dataSecurities?q=SecurityContext=LegalEntity |
| Asset Book | Manage Data Access for Users | /assets, /assetBooks | GET /dataSecurities?q=SecurityContext=AssetBook |
| Inventory Organization | Manage Inventory Org Data Access | /inventoryItems, /inventoryTransactions | Separate admin page for SCM |
| Procurement BU | Manage Data Access for Users | /purchaseOrders, /requisitions | GET /dataSecurities?q=SecurityContext=ProcurementBU |
BusinessUnitId field for comparison, not BusinessUnit. [src1]| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| HTTP 200 + empty items | Data security filtering | User has no grants for requested dimension | Add data role / security context assignment |
| HTTP 200 + partial results | Partial data security grants | Grants for some BUs/ledgers but not all | Add missing security context values |
| HTTP 403 | Functional privilege denied | User lacks duty role / privilege for resource | Add required job role with API duty roles |
| HTTP 401 | Authentication failure | Invalid credentials or expired session | Re-authenticate; check password expiry |
| JBO-27122 | SQL data security error | Custom policy has invalid SQL in instance set | Fix instance set WHERE clause in Security Console |
| APJ-1 | Application privilege error | User role missing specific object privilege | Add missing privilege to duty/job role |
Compare API totalResults against known-good count; alert on discrepancy. [src1]Include integration user access in org change management process. [src1]Always configure Data Access Sets when integration touches GL data. [src1]Ensure read and write grants match for all data dimensions. [src2]After any change, invalidate existing API sessions by re-authenticating. [src4]Audit policies for performance; use indexed columns, avoid correlated subqueries. [src1]# WRONG -- job role alone gives functional access but zero data visibility
Setup steps (incorrect):
1. Create integration user
2. Assign job role: "Accounts Payable Manager"
3. Call /invoices API
4. Result: HTTP 200, items: [] (empty -- no error!)
# CORRECT -- data role = job role + security profile (data dimension)
Setup steps (correct):
1. Create integration user
2. Assign job role: "Accounts Payable Manager"
3. Navigate to: Manage Data Access for Users
4. Add data access: Role = AP Manager, Context = Business Unit, Value = "US Operations"
5. Call /invoices API
6. Result: HTTP 200, items: [invoices from US Operations BU]
# WRONG -- BU and Ledger are independent security dimensions
Steps (incorrect):
1. Assign data access: BU = "US Operations" for AP Manager role
2. Call /journals API (General Ledger)
3. Result: HTTP 200, items: [] (empty -- ledger not granted!)
# CORRECT -- grant BU access AND Data Access Set for GL separately
Steps (correct):
1. Assign data access: BU = "US Operations" for AP Manager role
2. ALSO: Manage Data Access Set Assignments > add "US Primary Ledger" for GL role
3. Call /journals API
4. Result: HTTP 200, items: [journal entries from US Primary Ledger]
# WRONG -- violates least privilege, creates audit risk
Steps (incorrect):
1. Create integration user "INT_SUPER_USER"
2. Grant "All Values" for every security context
3. Use for all integrations regardless of scope
# CORRECT -- each integration has its own user with minimum required access
Steps (correct):
1. Create "INT_AP_US" for US AP integration (AP Manager + BU = "US Operations" only)
2. Create "INT_GL_GLOBAL" for GL consolidation (GL Accountant + All Ledgers)
3. Create "INT_PO_EU" for EU procurement (Buyer + Procurement BU = "EU Procurement")
Always configure both functional AND data security for integration users. [src1, src5]Always test using actual integration user credentials. [src4]After modifying data access, always re-authenticate before testing. [src4]Map all security dimensions touched by each integration flow and grant all of them. [src1]Document business justification for every "All Values" grant. [src5]Integrate security access reviews into org change management. [src1]# Check integration user's data security assignments
curl -s -u "INT_USER:password" \
"https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/dataSecurities" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json" \
| python3 -m json.tool
# Test AP invoice visibility (should return records if BU access granted)
curl -s -u "INT_USER:password" \
"https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/invoices?limit=1&totalResults=true" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json"
# Test GL journal visibility (requires separate Data Access Set)
curl -s -u "INT_USER:password" \
"https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/journals?limit=1&totalResults=true" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json"
# Verify which business units the user can see
curl -s -u "INT_USER:password" \
"https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/businessUnits?limit=500&totalResults=true" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json"
# Describe an API resource to check available fields and privileges
curl -s -u "INT_USER:password" \
"https://your-instance.fa.us2.oraclecloud.com/fscmRestApi/resources/11.13.18.05/invoices/describe" \
-H "Content-Type: application/vnd.oracle.adf.resourcecollection+json"
| Release | Date | Status | Data Security Changes | Notes |
|---|---|---|---|---|
| 25D | 2025-11 | Current | Enhanced data sovereignty controls | AI analytics for security audit |
| 25C | 2025-08 | Supported | No breaking changes | Minor security UI improvements |
| 25B | 2025-05 | Supported | No breaking changes | -- |
| 25A | 2025-02 | Supported | Data securities REST endpoint added | First release with programmatic security query |
| 24D | 2024-11 | Supported | Improved security context management UI | -- |
| 24C | 2024-08 | Supported | No breaking changes | -- |
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Integration user returns empty API results despite valid auth | User gets HTTP 401/403 | Standard auth troubleshooting |
| Need to scope integration data to specific business units | Need to control which REST endpoints are accessible | Functional security (job roles and API duty roles) |
| Configuring new integration user for cross-module access | Setting up OIC adapter connections | OIC adapter security configuration |
| Auditing what data an integration can see vs should see | Troubleshooting API performance unrelated to security | API performance tuning |