50 · Role Collections

Trace the full scope → role template → role → role collection → user assignment chain in BTP Cockpit.

Episode 50 — Roles, Scopes & Role Collections

What you'll learn

Why this matters

You can write perfect CDS security annotations and still have 403 errors because the role isn't assigned in BTP Cockpit. Understanding the assignment chain — scope → role template → role → role collection → user — lets you diagnose any "access denied" quickly.

The assignment chain

xs-security.json                    BTP Cockpit
──────────────────                  ───────────────────────
scope: bookshop.Admin          ←──  role-template "Admin" references it
                                         │
                               ──────────┘
                              role "Bookshop Admin" (instance of template)
                                   │ (with optional attribute values)
                              role collection "Bookshop Administrators"
                                   │
                              User: alice@company.com  ← assigned here

Step-by-step in BTP Cockpit

  1. Security → Roles → Find role templates for your app
  2. Click + to create a role from a template → set attribute values if any
  3. Security → Role Collections → Create "Bookshop Admins"
  4. Edit → Add Roles → find and add "Bookshop Admin"
  5. Security → Users → Find alice@company.com
  6. Assign Role Collections → "Bookshop Admins"

Automated role assignment via Cockpit API

For CI/CD:

# Using BTP CLI
btp assign security/role-collection "Bookshop Admins" \
  --to-user alice@company.com \
  --subaccount <id>

JWT scope format

// Alice's JWT after role collection assignment
{
  "scope": [
    "bookshop.Admin",       // from xs-security.json scope name
    "openid",               // standard OIDC scope
    "uaa.user"              // XSUAA internal scope
  ]
}
// CAP strips the app prefix automatically
req.user.is('Admin')    // true — checks scope includes 'bookshop.Admin'
req.user.roles          // ['Admin'] — stripped of 'bookshop.' prefix

JWT debugger — verify what Alice actually gets

# Get Alice's JWT (password flow — dev only)
curl -s -X POST "https://<subdomain>.authentication.eu10.hana.ondemand.com/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d "grant_type=password&username=alice&password=<pass>&scope=openid" \
  | jq .access_token -r \
  | cut -d'.' -f2 | base64 -d 2>/dev/null | jq .scope

Or use jwt.io — paste the token, check scope array.

Service-to-service scopes (client credentials)

When CAP calls an external service:

// xs-security.json — declare what this app can grant to callers
{
  "scopes": [
    {
      "name":        "$XSAPPNAME.Integrate",
      "description": "Allow external services to call this app",
      "granted-apps": ["<other-app-xsappname>"]   // only this app can get the scope
    }
  ]
}
// External CAP service calling this app
const externalClient = await cds.connect.to('BookshopAPI')
// Uses client credentials with 'bookshop.Integrate' scope
// No user in req.user.id — it's a service call
req.user.is('system-user')   // true for service-to-service calls

Role collection templates in mta.yaml (auto-assignment on deploy)

# mta.yaml
modules:
  - name: bookshop-srv
    parameters:
      role-collections:
        - name: "Bookshop Admins"
          description: "Full admin access to Bookshop"
          role-template-references:
            - "$XSAPPNAME.Admin"
        - name: "Bookshop Buyers"
          description: "Purchase books"
          role-template-references:
            - "$XSAPPNAME.Buyer"

These role collections are created automatically on cf deploy.

Hands-on exercise

  1. In BTP Cockpit, create roles from your Admin and Buyer templates
  2. Create role collections "Bookshop Admins" and "Bookshop Buyers"
  3. Assign your test user to "Bookshop Admins"
  4. Get a JWT and verify the scope array contains bookshop.Admin
  5. Test a @requires: 'Buyer' protected endpoint — verify you get 403 without the Buyer scope

Checkpoint ✓

Sign in for progress tracking & Q&A →