Skip to content

Commit 62506de

Browse files
davidkna-sapKavithaSivacloud-sdk-js
authored
docs: [JS] add IAS App-to-App (#2335)
* docs: [JS] add IAS * fix linter issues * add mermaid diagram * document caching behaviour * fmt * remove apptid cache comment * document the identity transformer * remove docs for list resources * update docs * update docs to reflect recent changes * update docs * remove experimental marker * Apply suggestions from code review Co-authored-by: KavithaSiva <kavitha.sivakumar@sap.com> * address review comments * Apply suggestions from code review Co-authored-by: KavithaSiva <kavitha.sivakumar@sap.com> * Update docs-js/features/connectivity/ias.mdx Co-authored-by: KavithaSiva <kavitha.sivakumar@sap.com> * fix: Changes from lint * chore: document JWT-Based Tenant Extraction during technical user authentication --------- Co-authored-by: KavithaSiva <kavitha.sivakumar@sap.com> Co-authored-by: cloud-sdk-js <cloud-sdk-js@github.com>
1 parent d6d34f1 commit 62506de

9 files changed

Lines changed: 1561 additions & 108 deletions

File tree

docs-js/features/connectivity/destination-cache-isolation.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ The default cache isolation strategy depends on the provided JWT:
7373
The value for the tenant is the provider account tenant.
7474
- JWT without `user_id`: Isolation is set to `tenant`.
7575
The value for the tenant is the `zid` property of the JWT.
76-
- JWT with `user_id`: Isolation is set to `tenant-user`.
77-
The and values are taken from `zid` and `user_id`.
76+
- JWT with `user_uuid` or `user_id`: Isolation is set to `tenant-user`.
77+
The tenant and user values are taken from `zid` and `user_uuid` (preferred) or `user_id`.
7878

7979
The first two cases (no JWT and JWT wihout `user_id`) are typical for user-independent authentication types, like `BasicAuthentication`, `ClientCertificateAuthentication` or `OAuth2ClientCredentials`.
8080
This is a safe choice which prevents privilege escalation due to caching.

docs-js/features/connectivity/destination.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ The SAP Cloud SDK provides a default implementation for the transformation of se
191191
- `service-manager`
192192
- `xsuaa`
193193
- `aicore`
194+
- `identity`
194195

195196
The default implementation also retrieves a service token, if needed.
196197

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
---
2+
id: identity-authentication-service
3+
title: Identity Authentication Service
4+
hide_title: false
5+
hide_table_of_contents: false
6+
sidebar_label: Identity Authentication Service
7+
description: This article describes how to use the Identity Authentication Service (IAS) with the SAP Cloud SDK.
8+
keywords:
9+
- sap
10+
- cloud
11+
- sdk
12+
- ias
13+
- identity authentication service
14+
- authentication
15+
- app2app
16+
- app-to-app
17+
- oauth2
18+
- btp
19+
- JavaScript
20+
- TypeScript
21+
---
22+
23+
:::warning
24+
25+
Only IAS App2App authentication is supported by the SAP Cloud SDK.
26+
Other scenarios such as App2Service are not fully supported yet.
27+
28+
:::
29+
30+
The SAP Cloud SDK supports the Identity Authentication Service (IAS) for App2App authentication scenarios.
31+
In this scenario, a consumer application requests tokens scoped to specific provider applications through pre-configured dependencies in IAS.
32+
33+
## App2App Authentication
34+
35+
App2App authentication allows secure service-to-service communication where tokens are scoped to specific provider applications.
36+
The consumer and provider applications must have a pre-configured dependency relationship in IAS.
37+
38+
At runtime, the consumer requests a token using the [`resource` parameter](#app2app-resources), which references the provider dependency.
39+
The IAS broker validates the relationship and issues a scoped token that only works for the specified provider.
40+
41+
### Configuration
42+
43+
:::note
44+
45+
The destination includes `mtlsKeyPair` with x509 credentials from the IAS service binding, if present.
46+
The SAP Cloud SDK uses these credentials for mTLS communication with the provider system.
47+
48+
The SAP Cloud SDK supports IAS service bindings with the following credential types:
49+
50+
- **`X509_GENERATED`**: automatically generated X.509 certificates.
51+
- **`SECRET`**: client secret credentials.
52+
53+
:::
54+
55+
Provider applications register a "provides" configuration on the IAS broker service, defining which APIs are exposed.
56+
Consumer applications create a service binding to IAS with dependencies on the required provider resources.
57+
58+
The dependency name configured in IAS is used as `resource.name` in the SAP Cloud SDK.
59+
60+
```mermaid
61+
sequenceDiagram
62+
participant Consumer as Consumer App
63+
participant SDK as SAP Cloud SDK
64+
participant IAS as IAS Broker
65+
participant Provider as Provider App
66+
67+
Note over Consumer,Provider: Configuration Phase (Setup)
68+
Provider->>IAS: Register "provides" configuration
69+
Consumer->>IAS: Configure dependency on provider
70+
71+
Note over Consumer,Provider: Runtime Phase (Token Exchange)
72+
Consumer->>SDK: Request token with resource parameter
73+
SDK->>IAS: Token request (client credentials + resource)
74+
IAS->>IAS: Validate dependency relationship
75+
IAS->>SDK: Issue scoped token
76+
SDK->>Consumer: Return token
77+
Consumer->>Provider: API call with scoped token
78+
Provider->>Provider: Validate token
79+
Provider->>Consumer: API response
80+
```
81+
82+
### Creating Destinations
83+
84+
Use [`getDestinationFromServiceBinding()`](pathname:///api/v4/functions/sap-cloud-sdk_connectivity.getDestinationFromServiceBinding.html) to connect to a system that is registered as an application within IAS.
85+
The parameter `iasOptions` contains:
86+
87+
- `targetUrl`: The URL of the system where the target application resides.
88+
- `resource`: The dependency identified by its name or identifier configured in IAS (see [App2App Resources](#app2app-resources)) section.
89+
90+
#### Technical User Authentication
91+
92+
For service-to-service communication with client credentials:
93+
94+
```typescript
95+
import { getDestinationFromServiceBinding } from '@sap-cloud-sdk/connectivity';
96+
97+
const destination = await getDestinationFromServiceBinding({
98+
destinationName: 'my-identity-service',
99+
iasOptions: {
100+
targetUrl: 'https://backend-provider.example.com',
101+
resource: { name: 'backend-api' }
102+
}
103+
});
104+
```
105+
106+
For multi-tenant scenarios, see the [Multi-Tenant Support](#multi-tenant-support) section.
107+
108+
Technical user token requests will be cached by default.
109+
To disable caching, set the `useCache` option to `false` in the destination request:
110+
111+
```typescript
112+
const destination = await getDestinationFromServiceBinding({
113+
destinationName: 'my-identity-service',
114+
useCache: false,
115+
iasOptions: {
116+
targetUrl: 'https://backend-provider.example.com',
117+
resource: { name: 'backend-api' }
118+
}
119+
});
120+
```
121+
122+
#### Business User Authentication
123+
124+
:::warning
125+
126+
When using business user authentication, token requests are not cached.
127+
128+
:::
129+
:::info
130+
131+
Setting `authenticationType` to `OAuth2JWTBearer` is required to trigger Business User authentication.
132+
133+
:::
134+
135+
For user context propagation, provide the JWT and set the authentication type.
136+
When you provide a JWT to the function, it automatically uses it as the assertion for token exchange.
137+
This will happen when no explicit `assertion` is provided in `iasOptions`:
138+
139+
```typescript
140+
const destination = await getDestinationFromServiceBinding({
141+
destinationName: 'my-identity-service',
142+
jwt: userToken,
143+
iasOptions: {
144+
authenticationType: 'OAuth2JWTBearer',
145+
targetUrl: 'https://backend-provider.example.com',
146+
resource: { name: 'backend-api' }
147+
// assertion is automatically set to userToken
148+
}
149+
});
150+
```
151+
152+
Multi-tenant scenarios are supported as well, refer to the [JWT-Based Tenant Extraction](#jwt-based-tenant-extraction) section for more details.
153+
154+
### App2App Resources
155+
156+
The [`IasResource`](pathname:///api/v4/types/sap-cloud-sdk_connectivity.IasResource.html) type identifies provider dependencies configured in IAS.
157+
It can be specified by dependency name or provider client identifier:
158+
159+
```typescript
160+
type IasResource =
161+
| {
162+
name: string;
163+
}
164+
| {
165+
providerClientId: string;
166+
providerTenantId?: string;
167+
};
168+
```
169+
170+
The `name` property refers to the dependency name configured in IAS and is the recommended way to identify resources.
171+
Alternatively, the `providerClientId` property can be used to specify the provider application's client identifier.
172+
Providing `providerClientId` grants access to all dependencies associated with that provider.
173+
174+
### Multi-Tenant Support
175+
176+
In multi-tenant scenarios, you can control the tenant context using the `requestAs` parameter or explicitly provide the tenant identifier.
177+
178+
#### Current Tenant and Provider Tenant options
179+
180+
:::warning
181+
182+
The `requestAs` parameter only affects technical user authentication (client credentials flow).
183+
184+
:::
185+
186+
The `requestAs` parameter determines which tenant (`app_tid`) context is used for the token request:
187+
188+
- **`'current-tenant'`** (default): Uses the tenant from the provided JWT (if any), otherwise falls back to the service binding credentials' `app_tid`
189+
- **`'provider-tenant'`**: Always uses the tenant from the service binding credentials
190+
191+
```typescript
192+
// Request as current tenant (uses JWT's app_tid)
193+
const jwt = '<user-jwt>'; // Placeholder for user JWT
194+
const destination = await getDestinationFromServiceBinding({
195+
destinationName: 'my-identity-service',
196+
jwt, // JWT's app_tid will be used
197+
iasOptions: {
198+
targetUrl: 'https://backend-provider.example.com',
199+
resource: { name: 'backend-api' },
200+
requestAs: 'current-tenant' // default
201+
}
202+
});
203+
```
204+
205+
```typescript
206+
// Request as provider tenant (uses service binding's app_tid)
207+
const destination = await getDestinationFromServiceBinding({
208+
destinationName: 'my-identity-service',
209+
iasOptions: {
210+
targetUrl: 'https://backend-provider.example.com',
211+
resource: { name: 'backend-api' },
212+
requestAs: 'provider-tenant'
213+
}
214+
});
215+
```
216+
217+
#### Explicit Tenant Identifier
218+
219+
For client credentials flows in multi-tenant scenarios, you can explicitly specify the consumer tenant identifier using `appTid`:
220+
221+
```typescript
222+
const destination = await getDestinationFromServiceBinding({
223+
destinationName: 'my-identity-service',
224+
iasOptions: {
225+
targetUrl: 'https://backend-provider.example.com',
226+
resource: { name: 'backend-api' },
227+
appTid: 'subscriber-tenant-id'
228+
}
229+
});
230+
```
231+
232+
#### JWT-Based Tenant Extraction
233+
234+
When a JWT is supplied in the `options`, the SAP Cloud SDK automatically extracts the tenant information from the JWT assertion and routes token requests to the correct IAS tenant.
235+
JWT-Based tenant extraction is enabled for technical user authentication (`OAuth2ClientCredentials`) as the current tenant (default) and business user authentication (`OAuth2JWTBearer`):
236+
237+
```typescript
238+
const destination = await getDestinationFromServiceBinding({
239+
destinationName: 'my-identity-service',
240+
jwt: subscriberUserJwt,
241+
iasOptions: {
242+
authenticationType: 'OAuth2JWTBearer',
243+
targetUrl: 'https://backend-provider.example.com',
244+
resource: { name: 'backend-api' }
245+
}
246+
});
247+
// Token request is automatically routed to the subscriber's IAS tenant
248+
```

docs-js/guides/how-to-retrieve-jwt.mdx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@ Therefore, JWTs are used to exchange authorization and authentication informatio
2828

2929
## JWT on SAP BTP
3030

31-
The retrieval of a JWT is done by the approuter together with the XSUAA.
31+
The retrieval of a JWT is done by the approuter together with XSUAA or IAS.
3232
[This guide](./how-to-use-the-approuter.mdx) explains these concepts.
3333
Find a complete setup in the sample applications for [Cloud Foundry](https://github.com/SAP-samples/cloud-sdk-js/tree/main/samples/cf-sample-application) and [k8s](https://github.com/SAP-samples/cloud-sdk-js/tree/main/samples/k8s-sample-application).
3434
The flow is as follows:
3535

3636
- user requests a resource and is not yet authenticated
3737
- approuter redirects the request to the identity provider (IdP)
38-
- XSUAA issues a JWT - see [here](#obtain-jwt-programmatically) for details
38+
- XSUAA or IAS issues a JWT - see [here](#obtain-jwt-programmatically) for details
3939
- approuter adds the JWT to the request headers and redirects the request to the initially requested resource
4040

41-
A JWT issued this way contains a `JKU` header property.
41+
A JWT issued by XSUAA contains a `JKU` header property.
4242
This property points to the URL where you can obtain the certificate to verify the JWT.
4343
The URL must be from the XSUAA domain so that it is trusted and the JWT validation does not fail.
4444

@@ -48,6 +48,10 @@ The URL must be from the XSUAA domain so that it is trusted and the JWT validati
4848
Since `v4.1.0` SAP Cloud SDK no longer verifies the JWT issued by XSUAA.
4949
:::
5050

51+
:::info IAS App-to-App Authentication
52+
For app-to-app authentication scenarios using the Identity Authentication Service (IAS), see the [Identity Authentication Service documentation](../features/connectivity/ias.mdx).
53+
:::
54+
5155
Sometimes you want to use a JWT which is not issued by the XSUAA and approuter.
5256
Such tokens do not contain a `JKU` at all or a value with a different domain.
5357
The destination service validates the token in this case.

docusaurus.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ module.exports = {
2626
organizationName: 'SAP',
2727
projectName: 'cloud-sdk',
2828
trailingSlash: false,
29+
markdown: {
30+
mermaid: true
31+
},
32+
themes: ['@docusaurus/theme-mermaid'],
2933
themeConfig: {
3034
colorMode: {
3135
respectPrefersColorScheme: true,

0 commit comments

Comments
 (0)