SAP Cloud Identity Services — IAS / IPS / AMS
1. Download IAS Tenant Metadata
# Download IAS SAML metadata
curl -s https://<tenant>.accounts.ondemand.com/saml2/metadata -o ias-metadata.xml
# Download OIDC discovery document
curl -s https://<tenant>.accounts.ondemand.com/.well-known/openid-configuration | jq .
2. Configure Corporate IdP Federation (IAS)
In Corporate IdP (Azure AD / Okta / Keycloak):
- Create Enterprise Application (SAML)
- Upload
ias-metadata.xmlas Service Provider metadata - Configure nameID format as
emailAddress - Export corporate IdP SAML metadata XML
In IAS Admin Console (https://<tenant>.accounts.ondemand.com/admin):
- Navigate to Applications → select your BTP subaccount app
- Trust → Corporate Identity Provider → Add
- Upload corporate IdP metadata XML
- Configure conditional authentication:
- Corporate IP range → password only
- External → password + TOTP (Microsoft/Google Authenticator)
- Save and enable
3. Configure IPS — User Provisioning
In IPS Admin Console (https://<tenant>.accounts.ondemand.com/ips):
- Source Systems → Add → select type (e.g. SAP SuccessFactors, Azure AD)
- Configure source connection properties (URL, credentials)
- Target Systems → Add → select type (e.g. SAP BTP XSUAA, S/4HANA)
- Configure target connection properties
- Mapping → define attribute mappings:
userName→userNameemails[0].value→emails[0].valuegroups→groups
- Jobs → Create → select source + target → Run
4. Manage Users via SCIM 2.0 API
# Create user
curl -X POST https://<tenant>.accounts.ondemand.com/service/scim/Users \
-H "Content-Type: application/scim+json" \
-H "Authorization: Bearer <token>" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "john.doe@corp.com",
"name": { "givenName": "John", "familyName": "Doe" },
"emails": [{ "value": "john.doe@corp.com", "primary": true }],
"active": true
}'
# List users with filter
curl "https://<tenant>.accounts.ondemand.com/service/scim/Users?filter=userName+eq+%22john.doe%22" \
-H "Authorization: Bearer <token>"
# Delete user
curl -X DELETE \
"https://<tenant>.accounts.ondemand.com/service/scim/Users/<user-id>" \
-H "Authorization: Bearer <token>"
5. XSUAA → IAS Migration
# Step 1: Export current XSUAA trust config (BTP Cockpit → Security → Trust Configuration)
# Step 2: In BTP Cockpit → Security → Trust Configuration → New Trust
# → Select IAS tenant → Save
# Step 3: In IAS → Applications → BTP subaccount → SAML 2.0 →
# Enable "Default IDP" = Corporate IdP
# Step 4: Map role collections:
# BTP Cockpit → Security → Role Collections →
# Assign to IAS user groups instead of individual users
# Step 5: Test login with corporate IdP user
# BTP Cockpit → click "Go to Application" → should redirect to corporate IdP
# Step 6: After 30-day grace period, disable XSUAA local IdP
6. Shadow User Cleanup
# List orphaned shadow users (exist in XSUAA but not in IdP)
curl "https://<tenant>.accounts.ondemand.com/service/scim/Users?filter=active+eq+true" \
-H "Authorization: Bearer <token>" | jq '.Resources[] | .userName'
# Deactivate orphaned users via IPS cleanup job:
# IPS Admin Console → Jobs → "Cleanup" → Run
Verification
# Verify IAS metadata is accessible
curl -s https://<tenant>.accounts.ondemand.com/saml2/metadata | head -5
# Expected: XML with EntityDescriptor
# Verify OIDC endpoint
curl -s https://<tenant>.accounts.ondemand.com/.well-known/openid-configuration | jq .issuer
# Expected: "https://<tenant>.accounts.ondemand.com"
# Verify SSO flow: open BTP app URL in browser
# Expected: redirect to corporate IdP login page, then back to BTP app
# Verify IPS provisioning job status
# IPS Admin Console → Jobs → View job log → Status = "Finished"
# Verify SCIM API is working
curl -s https://<tenant>.accounts.ondemand.com/service/scim/Users \
-H "Authorization: Bearer <token>" | jq '.totalResults'
# Expected: number > 0
Pitfalls
Shadow user orphans after IdP deletion
- Cause: Deleting a user in corporate IdP does not remove the shadow user in XSUAA.
- Solution: Configure IPS cleanup job to run daily. Job deactivates users not present in source system.
SAML certificate expiry breaks SSO
- Cause: Signing certificates expire every 1-2 years. No automatic alert by default.
- Solution: Monitor expiry date in IAS Admin Console → Settings → Certificates. Rotate 30 days before expiry and update corporate IdP trust.
IPS job frequency limit
- Cause: IPS minimum sync interval is 5 minutes. Sub-minute syncs are not supported.
- Solution: Use real-time SCIM API for immediate user creation instead of batch jobs.
Attribute mapping case mismatch
- Cause: SCIM/OpenID attribute names are case-sensitive.
givenName≠givenname. - Solution: Use exact casing from SCIM 2.0 RFC. Test with
curlbefore enabling the mapping in production.
- Cause: SCIM/OpenID attribute names are case-sensitive.
XSUAA → IAS migration is one-way
- Cause: Once BTP subaccount trust is switched to IAS, reverting requires manual trust reconfiguration.
- Solution: Keep XSUAA local IdP active for 30-day rollback window. Test with pilot users before full cutover.
IAS tenant URL format confusion
- Cause: Different URLs for admin console vs SCIM API vs SAML metadata.
- Solution: Admin =
https://<tenant>.accounts.ondemand.com/admin. SCIM =https://<tenant>.accounts.ondemand.com/service/scim. SAML metadata =https://<tenant>.accounts.ondemand.com/saml2/metadata.
MFA not triggered for external access
- Cause: Conditional authentication rules not applied, or corporate IP range too broad.
- Solution: Verify IP ranges in IAS → Applications → Conditional Authentication. Use CIDR notation (e.g.
10.0.0.0/8).