@sap/approuter
v20.8.8
Published
Node.js based application router
Readme
@sap/approuter
- Overview
- Deploying a business application with microservices
- Working directory
- Configurations
- Destinations
- UAA configuration
- Additional headers configuration
- Additional Cookie Attributes
- Plugins configuration
- Session timeout configuration
- X-Frame-Options configuration
- Cross-Origin Resource Sharing configuration
- Direct Routing URI Patterns configuration
- NodeJS Minimal Logging Level configuration
- Dynamic Identity Provider configuration
- Routes
- Replacements
- xs-app.json configuration file
- welcomeFile property
- authenticationMethod property
- routes property
- login property
- logout property
- destinations property
- services property
- responseHeaders property
- compression property
- pluginMetadataEndpoint property
- whitelistService property
- websockets property
- errorPage property
- cors property
- Complete example of a xs-app.json configuration file
- Headers
- CSRF Protection
- Support of SAP Statistics
- Connectivity
- SaaS Application Registration in SAP BTP
- Authentication with Identity Service (IAS)
- Mutual TLS Authentication (mTLS) and Certificates Handling
- Integration with HTML5 Application Repository
- Integration with Business Services
- Web Sockets
- Session Handling
- External Session Management
- Service to Application Router
- Central Logout
- User API Service
- Allowlist Service
- Scaling
- Sizing Guide for Application Router
- Configure server-side HTTPS
- Audit-Log Service
- Troubleshooting
- Getting Support
- Extending Application Router
- Best practices
Overview
When a business application consists of several different apps (microservices), the application router is used to provide a single entry point to that business application. It has the responsibility to:
- Dispatch requests to backend microservices (reverse proxy)
- Authenticate users
- Serve static content

Let's think of the different apps (microservices) as destinations to which the incoming request will be forwarded. The rules that determine which request should be forwarded to which destination are called routes. For every destination there can be more than one route. You may read more on the concept of routes later in this document. If the backend microservices require authentication, the application router can be configured to authenticate the users and propagate the user information. Again by using routes, the application router can serve static content.
The application router is designed to work in XS Advanced - Cloud Foundry and XS OnPremise Runtime.
A calling component accesses a target service by means of the application router only if there is no JWT token available, for example, if a user invokes the application from a Web browser. If a JWT token is already available, for example, because the user has already been authenticated, or the calling component uses a JWT token for its own OAuth client, the calling component calls the target service directly; it does not need to use the application router.
Note that the application router does not hide the backend microservices in any way. They are still directly accessible bypassing the application router. So the backend microservices must protect all their endpoints by validating the JWT token and implementing proper scope checks. Network isolation is not provided currently by the platform.
Deploying a business application with microservices
For example we can have a business application that has the following structure:
The manifest.yml file is used to deploy the business application on Cloud Foundry and the manifest-op.yml - on the XS OnPremise Runtime. These files should describe all the microservices for that business application.
Folders are used to isolate the different microservices. Let's assume that the application router is the microservice in the web folder (every business application has its own application router). Here is how we can include the application router:
- Manually create the node_modules folder in the web folder.
- Copy and paste the folder that contains the self-contained application router into node_modules. In this example the name of that folder is @sap/approuter, see the start script in the package.json below.
- Check the version of the application router you just copied.
- Create a package.json file in web with content similar to the following and replace the version's value with the version of your application router:
{
"name": "hello-world-approuter",
"dependencies": {
"@sap/approuter": "2.6.1"
},
"scripts": {
"start": "node node_modules/@sap/approuter/approuter.js"
}
}In order to use the application router you don't have to write any JavaScript code. Only some configurations have to be provided in the web folder. Here is a complete example:
The web folder contains the package.json, node_modules, some configuration files used by the application router, and static resources to be served. You can read more about the configurations later in this document.
By default, the application router runs on port 5000 (if started locally) or it takes the port from the PORT environment variable.
Working directory
The working directory contains configuration files that the application router needs and static resources that can be served at runtime. In the previous example, the web folder is the working directory. By default the current directory is the working directory. It is possible to configure it during start up of the application router with the following command line argument:
node approuter.js -w <working-dir>Application router will abort if the working directory does not contain xs-app.json file.
Configurations
The application router makes use of the following configurations:
Main configuration - this is the xs-app.json file. This file is mandatory and contains the main configurations of the application router.
UAA configuration - the application router reads this configuration either from the
VCAP_SERVICESenvironment variable (when deployed on Cloud Foundry or XS Advanced OnPremise Runtime) or from the default-services.json file (when running locally). Refer to the documentation of the@sap/xsenvpackage for more details.Configurations from the environment - these configurations are either read from the application router's environment (when deployed on Cloud Foundry or XS Advanced OnPremise Runtime) or from the default-env.json file (when running locally). Refer to the documentation of the
@sap/xsenvpackage for more details.
Note that when running application router locally it is required to set theNODE_ENVenvironment variable todevelopmentexplicitly in order to load the default-env.json file. The environment variables that the application router takes into account are:
| Configuration | Environment variable | Description |
|-------------------------------------------------------------------------------|-------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| UAA service name | UAA_SERVICE_NAME | Contains the name of the UAA service to be used. |
| Destinations | destinations | Provides information about the available destinations. |
| Additional headers | httpHeaders | Provides headers that the application router will return to the client in its responses. |
| Additional cookie attributes | COOKIES | The application router triggers the generation of the following third-party cookies and sends them to the client: • locationAfterLogin • fragmentAfterLogin • signature • JSESSIONID To control the behavior and usage of the third-party cookies, you can configure the attributes SameSite and Partitioned.For more information about third-party cookies, please see KBA 3409306. |
| Plugins | plugins | A plugin is just like a route except that you can't configure some inner properties. |
| Session timeout | SESSION_TIMEOUT | Positive integer representing the session timeout in minutes. The default timeout is 15 minutes. |
| X-Frame-Options | SEND_XFRAMEOPTIONS, httpHeaders | Configuration for the X-Frame-Options header value. |
| Allowlist service | CJ_PROTECT_WHITELIST | Configuration for the allowlist that is preventing clickjack attacks. |
| Web Sockets origins allowlist | WS_ALLOWED_ORIGINS | An allowlist configuration that is used for verifying the Origin header of the initial upgrade request when establishing a web socket connection. |
| JWT Token refresh | JWT_REFRESH | The time in minutes before a JWT token expires and the application router should trigger a token refresh routine. |
| Incoming connection timeout | INCOMING_CONNECTION_TIMEOUT | Maximum time in milliseconds for a client connection. After that time the connection is closed. If set to 0, the timeout is disabled. Default: 120000 (2 min) |
| Incoming request timeout | INCOMING_REQUEST_TIMEOUT | Maximum time in milliseconds for an incoming request. After that time the request is rejected with 408 status. If set to 0, the timeout is disabled. Default: 300000 (5 min) |
| Tenant host pattern | TENANT_HOST_PATTERN | String containing a regular expression with a capturing group. The request host is matched against this regular expression. The value of the first capturing group is used as tenant id. |
| Destination host pattern | DESTINATION_HOST_PATTERN | String containing a regular expression with a capturing group. The request host is matched against this regular expression. The value of the capturing group is used as destination name. |
| Compression | COMPRESSION | Configuration regarding compressing resources before responding to the client. |
| Secure flag of session cookie | SECURE_SESSION_COOKIE | Can be set to true or false. By default, the Secure flag of the session cookie is set depending on the environment the application router runs in. For example, when application router is behind a router (Cloud Foundry's router or SAP Web Dispatcher) that is configured to serve HTTPS traffic, then this flag will be present. During local development the flag is not set. This environment variable can be used to enforce setting or omitting the Secure flag. Note: If the Secure flag is enforced, the application router will reject requests sent over unencrypted connection (http). |
| Trusted CA certificates | XS_CACERT_PATH | List of files paths with trusted CA certificates used for outbound https connections (UAA, destinations, etc.). File paths are separated by path.delimiter. If this is omitted, several well known "root" CAs (like VeriSign) will be used. This variable is set automatically by XSA On-premise runtime. |
| Reject untrusted certificates | NODE_TLS_REJECT_UNAUTHORIZED | By default an outbound https connection is terminated if the remote end does not provide a trusted certificate. This check can be disabled by setting NODE_TLS_REJECT_UNAUTHORIZED to 0. This is a built-in feature of Node.js. Note: Do not use this in production as it compromises security! |
| External reverse proxy flag | EXTERNAL_REVERSE_PROXY | Boolean value that indicates the use of application router behind an external reverse proxy (outside of Cloud Foundry domain) |
| Skip client credentials tokens load on start | SKIP_CLIENT_CREDENTIALS_TOKENS_LOAD | Boolean value that indicates that no client credentials tokens should be created during the application router start phase |
| Cross-Origin Resource Sharing | CORS | Configuration regarding CORS enablement. |
| Preserve URL fragment | PRESERVE_FRAGMENT | When set to true or not set, fragment part of the URL provided during first request of not logged-in user to protected route will be preserved, and after login flow user is redirected to original URL including fragment part. However, this may break programmatic access to Approuter (e.g. e2e tests), since it introduces change in login flow, which is incompatible with Approuter version 4.0.1 and earlier. Setting value to false makes login flow backward compatible, however will not take fragment part of the URL into account. |
| Direct Routing URI Patterns | DIRECT_ROUTING_URI_PATTERNS | Configuration for direct routing URI patterns. |
| NodeJS Minimal Logging Level | CF_NODEJS_LOGGING_LEVEL | Configuration for NodeJS minimal logging level. |
| Dynamic Identity Provider | DYNAMIC_IDENTITY_PROVIDER | Configuration for dynamic identity provider. |
| Backend Cookies Secret | BACKEND_COOKIES_SECRET | Secret that is used to encrypt backend session cookies in service to Application Router flow. Should be set in case multiple instances of Application Router are used. By default a random sequence of characters is used. |
| Service to Application Router | SERVICE_2_APPROUTER | If true, when the SAP Passport header is received from the application router, it will be transferred without modification to the backend application. |
| Client certificate header name | CLIENT_CERTIFICATE_HEADER_NAME | When set application router will use this header name to get the client certificate from the request header in subscription callback. If not provided the default header name x-forwarded-client-cert is used. |
| Server Keep Alive | SERVER_KEEP_ALIVE | server keep alive timeout (positive integer in milliseconds). |
| Minimum Token Validity | MINIMUM_TOKEN_VALIDITY | positive integer in seconds. When set, approuter will check that the token returned from the authorization service has an expiration time higher than the minimum token validity value. |
| State Parameter Secret | STATE_PARAMETER_SECRET | enables the use of state parameters to prevent CSRF attacks. If this environment variable is set, the application router creates a state parameter for each initial request. Note that the state parameter value is returned as a session cookie, which enables session stickiness to the same application router instance. After the login callback is executed, this session cookie is replaced by another session cookie. By validating that the authentication server returns the same state parameter in its response, the application router can verify that the response did not originate from a third party. In Cloud Foundry, session stickiness is activated automatically. In Kyma, you must set up the session stickiness manually by using a destination rule (see HTTPCookie) or another method. The application router stores the state parameter for 60 seconds by default. If the login process is not completed within this time, the request fails with a 401 error. To adjust this time limit, you can use the STATE_CACHE environment variable. |
| HTTP2 Support | HTTP2_SUPPORT | Enables the application router to start as an HTTP/2 server. Note: To configure HTTP/2 support, you must use Cloud Foundry routes with an HTTP/2 destination protocol. See Configuring HTTP/2 Support in the Cloud Foundry Documentation. As connection-specific header fields aren't supported by the HTTP/2 protocol, see rfc9113, the application router removes such headers automatically when they are returned from a backend to prevent a failure of the HTTP/2 response. |
| Store CSRF token in external session | SVC2AR_STORE_CSRF_IN_EXTERNAL_SESSION | If true and have enabled external session management, the application router can generate and validate CSRF tokens in service-to-application-router flows by storing the token in an external session. |
| Cache service credentials | CACHE_SERVICE_CREDENTIALS | If true, services credentials are cached in the application router memory |
| Enable x-forwarded-host header validation | ENABLE_X_FORWARDED_HOST_VALIDATION | If true, x-forwarded-host validation will be performed, allowing letters, digits, hypens (-), underscores (_) and dots (.). As well as it validates hostname length. |
| Add the content security policy headers to the response | ENABLE_FRAME_ANCESTORS_CSP_HEADERS | If true, Approuter will include the content security policy (CSP) header using subaccount trusted domains with frame-ancestors policy. |
| Time cache value for frame ancestors CSP header | FRAME_ANCESTORS_CSP_HEADER_CACHE_TIME | Time in seconds for the frame ancestors CSP header to be cached. The default value is 300 seconds. |
| Store backend session cookies in external session store | STORE_SESSION_COOKIES_IN_EXTERNAL_SESSION_STORE | If true, the application router will store backend session cookies in an external session store in the service-to-application-router flow. In this case the "ARBE" cookie will not be returned to the calling service. |
| Own SAP Cloud Service | OWN_SAP_CLOUD_SERVICE | An array that contains the business solutions ("SAP cloud services") that your HTML5 applications are associated with as values. This configuration enables the standalone application router to use the same standardized format for runtime URLs ("/<sap.cloud.service>.-/") that is also used by the managed application router. If a runtime URL contains one of the defined values in the <sap.cloud.service> section, the application router will recognize the value during the processing of a request. |
| Cookie backward compatibilty | COOKIE_BACKWARD_COMPATIBILITY | If 'true', cookie serialization will preserve previous cookie library version serialization algorithm. |
| Platform cookie name | PLATFORM_COOKIE_NAME | Name the cookie that is used for session stickiness. In Cloud Foundry, the cookie name is hardcoded as VCAP_ID. Cloud Foundry automatically adds this cookie, and you cannot change it. In Kyma, you define the cookie name when you configure the load balancer settings for the destination rule (see HTTPCookie). Note: It's not recommended to use the JSESSIONID cookie in Kyma because it may cause errors in the application router.
