Understanding the SAP BTP Application Router in Cloud Foundry
The SAP Application Router (AppRouter) is a key component in the SAP Business Technology Platform (SAP BTP), especially in the Cloud Foundry runtime environment. It functions as the main entry point for accessing applications deployed on SAP BTP, managing how users are authenticated, how requests are routed to backend microservices or UIs, and how security is enforced across the application landscape.
Acting similarly to a reverse proxy or a load balancer, the AppRouter ensures incoming HTTP requests are properly directed—whether to a static HTML5 app, a CAP-based OData API, or an external REST service. In a multi-component, distributed cloud-native setup, this centralizes routing logic and makes it easier to maintain consistent access control and session handling across the stack.
Furthermore, the AppRouter enables user authentication and session management via SAP’s XSUAA service (Authorization and Trust Management), handles CSRF protection, and supports multi-tenant scenarios, making it an essential element of secure, scalable, enterprise-grade applications on SAP BTP.
In this guide, you'll learn:
- What the AppRouter is and how it works in SAP BTP Cloud Foundry.
- The difference between the managed and standalone AppRouter variants.
- How to configure the AppRouter using
xs-app.json
,manifest.yml
, and destinations. - The critical role of XSUAA and how it integrates with the AppRouter.
- Sample configuration and code snippets to get started.
Variants: Managed vs. Standalone AppRouter
SAP provides two main variants of the AppRouter:
- Managed App Router: A SAP-hosted router (for example via SAP Fiori Launchpad or SAP Build Work Zone). It requires no runtime maintenance by the developer and comes preintegrated with SAP BTP services. This managed router is recommended for most scenarios because SAP handles scaling, updates and provides built-in service integration. For example, if you onboard an app to SAP Build Work Zone, that environment effectively acts as the managed AppRouter.
- Standalone App Router: A Node.js application using
@sap/approuter
that you include and deploy yourself (e.g. in an MTA withtype: approuter.nodejs
). This gives you full control and customization (custom middleware, advanced routing, multi-tenant support, etc.). Use a standalone router for specialized use cases (multi-tenant SaaS apps, nonstandard OAuth flows) or when you need to extend the router logic. By default, however, a managed router suffices for most SAP Cloud scenarios.
Configuration (xs-app.json, package.json, MTA)
Configuring the AppRouter is done via JSON files and environment variables:
Node Module (package.json)
Include @sap/approuter
and a start script. For example:
{
"name": "my-approuter",
"version": "1.0.0",
"dependencies": {
"@sap/approuter": "<APPROUTER_VERSION>"
},
"scripts": {
"start": "node node_modules/@sap/approuter/approuter.js"
}
}
Check latest version of the NPM pagage in https://www.npmjs.com/package/@sap/approuter
This ensures the AppRouter library is available and launches it on npm start
.
Routing File (xs-app.json)
Defines the router’s behavior. Key properties are:
-
welcomeFile
: The default file (e.g."/index.html"
). -
authenticationMethod
: Usually"route"
(to enable per-route auth) or"none"
(if no auth is needed). -
routes
: An array of route objects. Each route maps an inbound path (source
regex) to a target or destination. For example:{ "welcomeFile": "/index.html", "authenticationMethod": "route", "routes": [ // Route to a given destinaiton { "source": "^/api/(.*)$", "destination": "srv-api", "authenticationType": "xsuaa", "csrfProtection": true }, // Route to a local folder in the server instance { "source": "^/local/(.*)$", "localDir": "webapp", "authenticationType": "none" }, // Route to the HTML Application Repository service { "source": "^(.*)$", "target": "$1", "service": "html5-apps-repo-rt", "authenticationType": "none" } ] }
In this example, requests to
/api/*
are forwarded to a Cloud Foundry destination namedsrv-api
(with XSUAA auth and CSRF protection). The request to/local/*
are forwarded to awebapp
folder inside the AppRouter server instance with no authentication required. All other paths are served from the SAP HTML5 App Repository (html5-apps-repo-rt
) with no additional authentication. Note how setting"authenticationType": "xsuaa"
on a route enforces login via the XSUAA service.Routes order matter
It is very important to remark that the order of the routers matter in its resolution. Router patterns will be evaluated in the order of their definition, so if the first pattern match, none of the following ones will be evaluated.
In other words, in the following configuration, the route for
^/myapp/api/(.*)$
will never be resolved, because the route for^/myapp/(.*)$
will be always resolved first:// DO NOT DO THIS { "welcomeFile": "/index.html", "authenticationMethod": "route", "routes": [ // This route will ALWAYS resolve all /myapp/ requests, // independently of the routes defined below { "source": "^/myapp/(.*)$", "target": "$1", "service": "html5-apps-repo-rt", "authenticationType": "none" }, // This route will NEVER be resolved { "source": "^/myapp/api/(.*)$", "destination": "srv-api", "authenticationType": "xsuaa", "csrfProtection": true }, ... ] }
The "target" property
The
"target"
property in anxs-app.json
route tells the Application Router how to rewrite the request path before forwarding it to the backend—effectively stripping or modifying the URL prefix defined in"source"
. For example, with:{ "source": "^/service/(.*)$", "target": "$1", "destination": "backend", "authenticationType": "xsuaa" }, { "source": "^/api/(.*)$", "target": "/odata/v4/$1", "destination": "backend", "authenticationType": "xsuaa" }
an incoming request like
/service/business-partner
is rewritten to/business-partner
when it is proxied to thebackend
destination. Here,$1
corresponds to the(.*)
capture group in thesource
, providing a clean URL structure for the backend service. On the other route, all request like/api/Products
will be resolved as/odata/v4/Products
when forwarding to thebackend
destination.Without
"target"
, the original path would be forwarded as-is. Conversely, if you want to preserve the URL structure, you can explicitly set"target": "/service/$1"
to keep the/service
prefix. This mechanism is essential for decoupling frontend routing structures from backend endpoint designs while maintaining flexibility and clarity in your Cloud Foundry applications.
Destinations (env var)
Use Cloud Foundry destinations for backend URLs. In your manifest.yml
or default-env.json
, set a destinations
JSON. For example:
# manifest.yaml snippet
env:
destinations: >
[
{
"name": "srv-api",
"url": "https://api-backend.cfapps.myregion.example.com",
"forwardAuthToken": true
}
]
// default-env.json file
{
"PORT": "8080",
"destinations": [
{
"name": "srv-api",
"url": "https://api-backend.cfapps.your-region.hana.ondemand.com",
"forwardAuthToken": true
}
],
"VCAP_SERVICES": {
...
}
}
This tells the AppRouter how to reach the srv-api
service. forwardAuthToken: true
makes the router pass the logged-in user’s JWT to the backend.
Destination can be consumed also from the SAP BTP account directly. For that it is needed to add the destination service binding properties in the environment varaibles. Do this including the VCAP_SERVICES object in the default-env.json
file.
// default-env.json file
{
"PORT": "8080",
"destinations": [
...
],
"VCAP_SERVICES": {
"destination": [
{
"name": "my-destination-service",
"credentials": {
"clientid": "<DEST-client-id>",
"clientsecret": "<DEST-client-secret>",
"url": "https://destination.cfapps.your-region.hana.ondemand.com",
"token_url": "https://<subdomain>.authentication.eu10.hana.ondemand.com/oauth/token"
},
"plan": "lite"
}
]
}
}
IMPORTANT! Note that all hardcoded destinations set in the
destinations: {}
object will overwrite any destination with the same name defined in the bound BTP destination service instance.
MTA Configuration
In mta.yaml
, declare the AppRouter module and bind required resources:
- name: my-approuter
type: approuter.nodejs
path: approuter
requires:
- name: html5-apps-repo-rt
- name: my-xsuaa
Also add a resource for XSUAA:
- name: my-xsuaa
type: org.cloudfoundry.managed-service
service: xsuaa
service-plan: application
parameters:
path: ./xs-security.json
This tells Cloud Foundry to create an XSUAA instance (plan application) using the xs-security.json
descriptor.
Authentication and XSUAA
The AppRouter uses the XSUAA (SAP’s UAA service) for OAuth2/OIDC authentication. Key points:
-
XSUAA Service: This is the identity provider on SAP BTP. You must create an XSUAA instance (with your
xs-security.json
) and bind it to the AppRouter. Thexs-security.json
file defines your app’s OAuth client, scopes, and roles. For example:{ "xsappname": "my-approuter", "tenant-mode": "dedicated", "scopes": [ { "name": "uaa.user", "description": "Standard user scope" } ] }
Here,
"xsappname": "my-approuter"
becomes the OAuth client name (referred to by the AppRouter). -
Login Flow: When a route has
"authenticationType": "xsuaa"
, the AppRouter redirects unauthenticated users to XSUAA’s login page. After login, XSUAA issues a JWT. The AppRouter stores this token in the session and forwards it to backend services (based on routes or destinations). -
Token Propagation: By binding XSUAA and using
forwardAuthToken
, the AppRouter transparently handles user tokens. Backend services (e.g. CAP or OData servers) receive the JWT in the Authorization header and can validate scopes/roles without additional login prompts. The Cloud SDK recommends using the AppRouter as the proxy for auth so that user/session management is centralized. -
No Extra Code Needed: The AppRouter library handles the OAuth handshake. You usually don’t write custom auth code – just configure
xs-app.json
and providexs-security.json
for XSUAA. As SAP’s documentation notes, “you don't have to write any JavaScript code. Only some configurations have to be provided” in the router’s web folder.
In summary: The SAP Application Router unifies routing and security. Configure it via xs-app.json
and an XSUAA service. Use managed routing when possible, or a standalone AppRouter (@sap/approuter
) when you need full control. Ensure all routes that need login use authenticationType: "xsuaa"
, and bind an XSUAA instance so that user authentication and JWT management work seamlessly across your SAP BTP application.
References
- SAP Help: Application Router Overview
- SAP Help: Set Up Application Router
- SAP Help: HTML5 Applications on SAP BTP
- SAP Samples on GitHub: approuter
- SAP Help: Authorization and Trust Management Service (XSUAA)
- SAP Help: Destination Service
- SAP Help: Using the Application Router with XSUAA
- SAP Community Blog: SAP AppRouter Basics
- SAP Developers Tutorial: Develop a Multi-Target Application (MTA)