BTP Auth Deep Dive

How XSUAA, BTP Trust Configuration, and corporate SSO work together so every user gets the right role automatically.

Architecture overview

CPI Studio uses XSUAA as the single OAuth2 authority. When the XSUAA service is bound, it becomes the gatekeeper for all logins — including corporate identity providers like IAS, Azure AD, or Okta.

User browser
  │
  ▼ /auth/sso → /auth/btp
XSUAA (CF OAuth2 server)
  │  ← federates via BTP Trust Configuration
  ▼
Corporate IdP (IAS / Azure AD / Okta)
  │  ← user authenticates with company credentials
  ▼
XSUAA issues JWT with BTP Role Collection scopes
  │
  ▼
CPI Studio reads scopes → maps to admin / developer / viewer

This is exactly how FIGAF and other BTP tools work. The key insight: role assignment happens in BTP Cockpit, not in CPI Studio config files. Any user at any company gets the correct role as long as their BTP Role Collection is assigned correctly.

Why XSUAA (not IAS direct)?

If the app were to authenticate against IAS directly, it would receive an IAS JWT — which contains IAS user groups but no BTP Role Collection scopes. BTP Role Collections only appear in tokens issued by XSUAA. Going through XSUAA means:


The xs-security.json file

This file defines the three CPI Studio roles and pre-creates the BTP Role Collections automatically on first deploy. The redirect-uris use wildcards so the same file works for every BTP region and every customer subdomain — no edits needed.

{
  "xsappname": "cpi-studio",
  "tenant-mode": "dedicated",
  "scopes": [
    { "name": "$XSAPPNAME.admin",     "description": "Full admin access" },
    { "name": "$XSAPPNAME.developer", "description": "Read/write iFlows"  },
    { "name": "$XSAPPNAME.viewer",    "description": "Read-only access"   }
  ],
  "role-templates": [
    { "name": "Admin",     "scope-references": ["$XSAPPNAME.admin"]     },
    { "name": "Developer", "scope-references": ["$XSAPPNAME.developer"] },
    { "name": "Viewer",    "scope-references": ["$XSAPPNAME.viewer"]    }
  ],
  "oauth2-configuration": {
    "redirect-uris": [
      "https://*.cfapps.*.hana.ondemand.com/auth/btp/callback",
      "https://*.hana.ondemand.com/auth/btp/callback",
      "http://localhost:*/auth/btp/callback"
    ]
  },
  "role-collections": [
    {
      "name": "CPI Studio Admin",
      "description": "Assign to administrators",
      "role-template-references": ["$XSAPPNAME.Admin"]
    },
    {
      "name": "CPI Studio Developer",
      "description": "Assign to integration developers",
      "role-template-references": ["$XSAPPNAME.Developer"]
    },
    {
      "name": "CPI Studio Viewer",
      "description": "Assign to read-only users",
      "role-template-references": ["$XSAPPNAME.Viewer"]
    }
  ]
}

Do not hardcode your CF app URL in redirect-uris. The wildcard patterns cover all BTP regions (eu10, us10, ap10, etc.) and all subdomains automatically.


First-time setup

1. Create the XSUAA service instance

cf create-service xsuaa application cpi-studio-xsuaa -c xs-security.json

This registers the OAuth2 app in your BTP subaccount and creates the three Role Collections.

2. Bind and deploy

The manifest.yml already lists cpi-studio-xsuaa under services, so cf push binds it automatically. See Getting Started for the full manifest.

cf push

3. Register your corporate IdP in BTP Trust Configuration

This one-time step, done per subaccount, tells XSUAA which identity provider to federate with for corporate users.

  1. Open BTP Cockpit → your subaccount → Trust Configuration
  2. Click Establish Trust (or New Trust Configuration)
  3. Select your IAS tenant or paste your corporate IdP metadata
  4. Save

Already using FIGAF or another BTP tool with corporate SSO? Trust Configuration is already done for your subaccount — skip this step entirely.

4. Assign BTP Role Collections to users

  1. Go to BTP Cockpit → Security → Role Collections
  2. Open CPI Studio Admin, CPI Studio Developer, or CPI Studio Viewer
  3. Click Edit → Users tab → add users by email
  4. The user's identity provider must match what was configured in Trust Configuration

Tip: You can assign Role Collections to IdP groups instead of individual users (e.g., an Azure AD group or IAS user group). This scales well for larger teams — everyone in the group automatically gets the correct role.


Updating an existing deployment

When you update xs-security.json (e.g., to add new redirect URIs or change role definitions), the XSUAA service instance must be updated separately from the app:

cf update-service cpi-studio-xsuaa -c xs-security.json
cf push

cf push alone does not update the XSUAA service instance. If users see invalid_grant errors after a redeploy, run cf update-service first.


Role mapping

BTP Role CollectionCPI Studio RolePermissions
CPI Studio AdminadminAll features + user management, settings
CPI Studio DeveloperdeveloperEdit, deploy, promote iFlows; view logs
CPI Studio ViewerviewerRead-only: view iFlows, logs, runtime status
(none assigned)viewerDefault fallback — assign a Role Collection to elevate

Troubleshooting

SymptomCauseFix
User shows "viewer" despite having admin Role Collection User's corporate IdP is not registered in BTP Trust Configuration — XSUAA can't match their login to their Role Collection Complete Trust Configuration step (Step 3 above). This is a one-time per-subaccount setup.
invalid_grant on login XSUAA service instance has old redirect URI list that doesn't include your app's callback URL Run cf update-service cpi-studio-xsuaa -c xs-security.json with the wildcard xs-security.json above, then cf push
mismatch_state CSRF warning CF container was restarted during login flow, wiping the in-memory OAuth2 session state Click "Sign in with Corporate SSO" again — CPI Studio detects this and automatically retries the login flow
Login button not shown XSUAA service not bound, or app not restaged after binding Verify cf env cpi-developer-studio shows VCAP_SERVICES.xsuaa. If missing, check services in manifest.yml and re-push.