@@ -462,7 +461,7 @@ Moreover, deserialization errors terminate the request and are tracked in the ap
In general, to achieve perfect injection resistance, applications should have input validation, output validation, and a proper Content-Security-Policy in place.
- CAP provides built-in support for **input validation**.
-Developers can use the [`@assert`](../providing-services#input-validation) annotation to define field-specific input checks.
+Developers can use the [`@assert`](../services/constraints) annotation to define field-specific input checks.
::: warning
Applications need to validate or sanitize all input variables according to the business context.
@@ -523,7 +522,7 @@ If you want to apply an application-specific sizing, consult the corresponding f
See section [Maximum Request Body Size](../../node.js/cds-server#maximum-request-body-size) to find out how to restrict incoming requests to a CAP Node.js application depending on the body size.
:::
-Moreover, CAP adapters automatically introduce query results pagination in order to limit memory peaks (customize with [`@cds.query.limit`](../providing-services#annotation-cds-query-limit)).
+Moreover, CAP adapters automatically introduce query results pagination in order to limit memory peaks (customize with [`@cds.query.limit`](../services/served-ootb#annotation-cds-query-limit)).
The total number of request of OData batches can be limited by application configuration.
@@ -541,7 +540,7 @@ To prevent clients from _requesting too much data_, you can define restrictions
- Or you can set an **application-wide limit** with
cds.query.restrictions.expand.maxLevels = \ that applies to all entities. Value `-1` indicates absence of limit.
:::warning
-These restrictions are enforced on 'READ' events on [Application services](/java/cqn-services/#application-services).
+These restrictions are enforced on 'READ' events on [Application services](../../java/cqn-services/#application-services).
:::
Good candidates for expand restrictions are associations to the same type (for example, when your entity represents a tree or a hierarchy
1), backlink associations of compositions, or many-to-many associations.
@@ -633,13 +632,13 @@ This can be achieved automatically by consuming [Application Autoscaler](https:/
There are additional attack vectors to consider. For instance, naive URL handling in the server endpoints frequently introduces security gaps.
-Luckily, CAP applications don't have to implement HTTP/URL processing on their own as CAP offers sophisticated [protocol adapters](../../about/features#consuming-services) such as OData V2/V4 that have the necessary security validations in place.
+Luckily, CAP applications don't have to implement HTTP/URL processing on their own as CAP offers sophisticated [protocol adapters](../../get-started/feature-matrix#consuming-services) such as OData V2/V4 that have the necessary security validations in place.
The adapters also transform the HTTP requests into a corresponding CQN statement.
Access control is performed on basis of CQN level according to the CDS model and hence HTTP Verb Tampering attacks are avoided. Also HTTP method override, using `X-Http-Method-Override` or `X-Http-Method` header, is not accepted by the runtime.
The OData protocol allows to encode field values in query parameters of the request URL or in the response headers. This is, for example, used to specify:
-- [Pagination (implicit sort order)](../providing-services#pagination-sorting)
-- [Searching Data](../providing-services#searching-data)
+- [Pagination (implicit sort order)](../services/served-ootb#pagination-sorting)
+- [Searching Data](../services/served-ootb#searching-data)
- Filtering
::: warning
@@ -655,7 +654,7 @@ In addition, CAP runs on a virtual machine with a managed heap that protects fro
CAP also brings some tools to effectively reduce the attack vector of race condition vulnerabilities.
These might be exposed when the state of resources can be manipulated concurrently and a consumer faces an unexpected state.
-CAP provides basic means of [concurrency control](../providing-services#concurrency-control) on different layers, for example [ETags](../providing-services#etag) and [pessimistic locks](../providing-services#select-for-update). Moreover, Messages received from the [message queue](../messaging/) are always in order.
+CAP provides basic means of [concurrency control](../services/served-ootb#concurrency-control) on different layers, for example [ETags](../services/served-ootb#etag) and [pessimistic locks](../services/served-ootb#select-for-update). Moreover, Messages received from the [message queue](../events/index.md) are always in order.
::: tip
Applications have to ensure a consistent data processing taking concurrency into account.
@@ -684,7 +683,7 @@ Developers have to explicitly configure public endpoints if necessary.
- Application logging has `INFO` level to avoid potential information disclosures.
-- CAP also has first-class citizen support for [Fiori UI](../../advanced/fiori) framework that brings a lot secure by default features in the UI client.
+- CAP also has first-class citizen support for [Fiori UI](../uis/fiori) framework that brings a lot secure by default features in the UI client.
Of course, several security aspects need application-specific configuration.
For instance, this is true for [authorizations](#secure-authorization) or application [sizing](#dos-attacks).
diff --git a/guides/data-privacy/annotations.md b/guides/security/dpp-annotations.md
similarity index 89%
rename from guides/data-privacy/annotations.md
rename to guides/security/dpp-annotations.md
index 6549842caa..6a329ee15c 100644
--- a/guides/data-privacy/annotations.md
+++ b/guides/security/dpp-annotations.md
@@ -1,4 +1,6 @@
---
+synopsis: >
+ In order to automate audit logging, personal data management, and data retention management as much as possible, the first and frequently only task to do as an application developer is to identify entities and elements (potentially) holding personal data using `@PersonalData` annotations.
status: released
---
@@ -22,13 +24,13 @@ In order to automate audit logging, personal data management, and data retention
In the remainder of this guide, we use the [Incidents Management reference sample app](https://github.com/cap-js/incidents-app) as the base to add data privacy and audit logging to.
-{style="zoom:111%;"}
+{style="zoom:111%;"}
So, let's annotate the data model to identify personal data.
In essence, in all our entities we search for elements which carry personal data, such as person names, birth dates, etc., and tag them accordingly.
All found entities are classified as either *Data Subjects*, *Subject Details* or *Related Data Objects*.
-Following the [best practice of separation of concerns](../domain-modeling#separation-of-concerns), we annotate our domain model in a separate file *srv/data-privacy.cds*, which we add to our project and fill it with the following content:
+Following the [best practice of separation of concerns](../domain/index#separation-of-concerns), we annotate our domain model in a separate file *srv/data-privacy.cds*, which we add to our project and fill it with the following content:
> For the time beeing also replace the data in _data/sap.capire.incidents-Customers.csv_.
@@ -94,7 +96,7 @@ Learn more about these annotations in the [@PersonalData OData vocabulary](https
The entity-level annotation `@PersonalData.EntitySemantics` signifies relevant entities as *Data Subject*, *Data Subject Details*, or *Other* in data privacy terms, as depicted in the following graphic.
-{style="zoom:111%;"}
+{style="zoom:111%;"}
The following table provides some further details.
@@ -144,7 +146,7 @@ Use this annotation to identify data subject's unique key, or a reference to it.
- Each `@PersonalData` entity needs to identify a `DataSubjectID` element.
- For entities with `DataSubject` semantics, this is typically the primary key.
- For entities with `DataSubjectDetails` or `Other` semantics, this is usually an association to the data subject.
-- Fields marked as `DataSubjectID` should use [`not null`](../databases#not-null) to guarantee a value is present at all times.
+- Fields marked as `DataSubjectID` should use [`not null`](../databases/cdl-to-ddl#not-null-constraints) to guarantee a value is present at all times.
Hence, we annotate our model as follows:
@@ -197,6 +199,6 @@ annotate my.Customers with {
Having annotated your data model with `@PersonalData` annotations, you can now go on to the respective tasks that leverage these annotations to automate as much as possible:
-- [*Automated Audit Logging*](audit-logging)
-- [*Personal Data Management*](pdm)
-- [*Data Retention Management*](drm)
+- [*Automated Audit Logging*](dpp-audit-logging)
+- [*Personal Data Management*](dpp-pdm)
+- [*Data Retention Management*](dpp-drm)
diff --git a/guides/data-privacy/audit-logging.md b/guides/security/dpp-audit-logging.md
similarity index 93%
rename from guides/data-privacy/audit-logging.md
rename to guides/security/dpp-audit-logging.md
index 96ede8face..6e4e05a353 100644
--- a/guides/data-privacy/audit-logging.md
+++ b/guides/security/dpp-audit-logging.md
@@ -1,4 +1,6 @@
---
+synopsis: >
+ The Audit Logging plugin provides out-of-the box support for automatic audit logging of data privacy-related events, in particular changes to personal data and reads of sensitive data.
status: released
---
@@ -12,7 +14,7 @@ The [`@cap-js/audit-logging`](https://www.npmjs.com/package/@cap-js/audit-loggi
:::warning
-_The following is mainly written from a Node.js perspective. For Java's perspective, please see [Java - Audit Logging](../../java/auditlog)._
+_The following is mainly written from a Node.js perspective. For Java's perspective, please see [Java - Audit Logging](../../java/auditlog.md)._
:::
@@ -24,7 +26,7 @@ _The following is mainly written from a Node.js perspective. For Java's perspect
## Annotate Personal Data
-First identify entities and elements (potentially) holding personal data using `@PersonalData` annotations, as explained in detail in the [*Annotating Personal Data* chapter](annotations) of these guides.
+First identify entities and elements (potentially) holding personal data using `@PersonalData` annotations, as explained in detail in the [*Annotating Personal Data* chapter](dpp-annotations) of these guides.
> We keep using the [Incidents Management reference sample app](https://github.com/cap-js/incidents-app).
@@ -153,7 +155,7 @@ A more comprehensive guide, incl. tutorials, is currently under development.
-For deployment in general, please follow the [deployment guide](../deployment/). Check the rest of this guide before actually triggering the deployment (that is, executing `cf deploy`).
+For deployment in general, please follow the [deployment guide](../deploy/index.md). Check the rest of this guide before actually triggering the deployment (that is, executing `cf deploy`).
Here is what you need to do additionally, to integrate with SAP Audit Log Service:
@@ -183,7 +185,7 @@ There are two options to access audit logs:
### Behind the Scenes...
-For all [defined services](../providing-services#service-definitions), the generic audit logging implementation does the following:
+For all [defined services](../services/providing-services), the generic audit logging implementation does the following:
- Intercept all write operations potentially involving personal data.
- Intercept all read operations potentially involving sensitive data.
@@ -211,7 +213,7 @@ await audit.log('Foo', { bar: 'baz' })
```
::: tip Audit Logging as Just Another CAP Service
-The Audit Log Service API is implemented as a CAP service, with the service API defined in CDS as shown in the next section. In effect, the common patterns of [*CAP Service Consumption*](../using-services) apply, as well as all the usual benefits like *mocking*, *late-cut µ services*, *resilience* and *extensibility*.
+The Audit Log Service API is implemented as a CAP service, with the service API defined in CDS as shown in the next section. In effect, the common patterns of [*CAP Service Consumption*](../services/consuming-services) apply, as well as all the usual benefits like *mocking*, *late-cut µ services*, *resilience* and *extensibility*.
:::
@@ -443,7 +445,7 @@ await audit.log ('SecurityEvent', {
-## Custom Implementation { #custom-implementation }
+## Custom Implementation
In addition, everybody could provide new implementations in the same way as we implement the mock variant:
@@ -477,11 +479,11 @@ As always, custom implementations need to be configured in `cds.requires.<>.impl
-## Transactional Outbox { #transactional-outbox }
+## Transactional Outbox
By default, all log messages are sent through a transactional outbox. This means, when sent, log messages are first stored in a local outbox table, which acts like a queue for outbound messages. Only when requests are fully and successfully processed, these messages are forwarded to the audit log service.
-
+
This provides an ultimate level of resiliency, plus additional benefits:
@@ -491,4 +493,4 @@ This provides an ultimate level of resiliency, plus additional benefits:
- **False log messages are avoided** — messages are forwarded to the audit log service on successfully committed requests; and skipped in case of rollbacks.
-This transparently applies to all implementations, even [custom implementations](#custom-implementation). You can opt out of this default by configuring
cds.audit-log.[development].outbox = false.
+This transparently applies to all implementations, even [custom implementations](#custom-implementation). You can opt out of this default by configuring
cds.audit-log.\[development\].outbox = false.
diff --git a/guides/data-privacy/drm.md b/guides/security/dpp-drm.md
similarity index 90%
rename from guides/data-privacy/drm.md
rename to guides/security/dpp-drm.md
index 007e5ea908..06e4b19779 100644
--- a/guides/data-privacy/drm.md
+++ b/guides/security/dpp-drm.md
@@ -1,4 +1,6 @@
---
+synopsis: >
+ The Data Retention Management (DRM) guide is under construction. It will cover concepts and implementation details for managing the retention and deletion of personal data in compliance with data privacy regulations.
# status: released
---
diff --git a/guides/data-privacy/pdm.md b/guides/security/dpp-pdm.md
similarity index 94%
rename from guides/data-privacy/pdm.md
rename to guides/security/dpp-pdm.md
index 7a2456c137..bd84c95a59 100644
--- a/guides/data-privacy/pdm.md
+++ b/guides/security/dpp-pdm.md
@@ -1,12 +1,6 @@
---
-label: Personal Data Management
-shorty: PDM
synopsis: >
- Use the SAP Personal Data Manager (PDM) with a CAP application.
-breadcrumbs:
- - Cookbook
- - Data Privacy
- - PDM
+ The Personal Data Management (PDM) guide explains how to integrate your CAP application with the SAP Personal Data Manager service to respond to data subject requests about their personal data stored in your application.
status: released
---
@@ -26,7 +20,7 @@ SAP BTP provides the [*SAP Personal Data Manager (PDM)*](https://help.sap.com/do
## Annotate Personal Data
-First identify entities and elements (potentially) holding personal data using `@PersonalData` annotations, as explained in detail in the [*Annotating Personal Data* chapter](annotations) of these guides.
+First identify entities and elements (potentially) holding personal data using `@PersonalData` annotations, as explained in detail in the [*Annotating Personal Data* chapter](dpp-annotations) of these guides.
> We keep using the [Incidents Management reference sample app](https://github.com/cap-js/incidents-app).
@@ -39,7 +33,7 @@ Following the CAP principles, we recommend adding a new dedicated CAP service th
### CAP Service Model for SAP Personal Data Manager
-Following the [best practice of separation of concerns](../domain-modeling#separation-of-concerns), we create a dedicated service for the integration with SAP Personal Data Manager:
+Following the [best practice of separation of concerns](../domain/index#separation-of-concerns), we create a dedicated service for the integration with SAP Personal Data Manager:
::: code-group
```cds [srv/pdm-service.cds]
@@ -92,7 +86,7 @@ service PDMService @(path: '/pdm') {
:::
::: tip
-Make sure to have [indicated all relevant entities and elements in your domain model](annotations).
+Make sure to have [indicated all relevant entities and elements in your domain model](dpp-annotations).
:::
@@ -177,7 +171,7 @@ npm install @sap/xssec
The Personal Data Manager can't connect to your application running locally. Therefore, you first need to deploy your application. In our sample, we added two manifest files using `cds add cf-manifest` and SAP HANA configuration using `cds add hana`.
-The general deployment is described in detail in [Deploy Using Manifest Files](../deployment/to-cf).
+The general deployment is described in detail in [Deploy Using Manifest Files](../deploy/to-cf).
Make a production build:
@@ -197,7 +191,7 @@ cf create-service-push
[Subscribe to the service](https://help.sap.com/docs/PERSONAL_DATA_MANAGER/620a3ea6aaf64610accdd05cca9e3de2/ef10215655a540b6ba1c02a96e118d66.html) from the _Service Marketplace_ in the SAP BTP cockpit.
-{width="300"}
+{width="300"}
Follow the wizard to create your subscription.
@@ -288,8 +282,8 @@ cf bind-service incidents-mgmt-srv incidents-mgmt-pdm -c ./pdm-binding-config.js
Open the SAP Personal Data Manager application from the _Instances and Subscriptions_ page in the SAP BTP cockpit.
-{width="500"}
+{width="500"}
In the personal data manager application you can search for data subjects with _First Name_, _Last Name_, and _Date of Birth_, or alternatively with their _ID_.
-{width="500"}
\ No newline at end of file
+{width="500"}
\ No newline at end of file
diff --git a/guides/security/index.md b/guides/security/index.md
index 5091a893ca..287dd2dfe5 100644
--- a/guides/security/index.md
+++ b/guides/security/index.md
@@ -1,24 +1,26 @@
---
-section: Security
-status: released
synopsis: >
This guide teaches how to how to develop, deploy and operate CAP applications in a secure way.
uacp: Used as link target from Help Portal at https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/9186ed9ab00842e1a31309ff1be38792.html
---
-# CAP Security Guide
+# CAP Security and Data Privacy
-This guide addresses
+Security, data protection and data privacy are critical aspects of modern application development,
+with significant legal and ethical implications. \
+The guides in this section are for developers, operators, administrators, and security professionals
+who need to understand how to develop, deploy and operate secure and compliant CAP applications.
+{.abstract}
-- Developers and operators
-- User administrators
-- Security experts
+#### Data Protection vs. Data Privacy:
-of CAP applications who need to understand how to develop, deploy and operate CAP applications in a secure way.
+| Feature | Data Privacy | Data Protection |
+|:-----------|:-----------------------------------------------|:-----------------------------------------------------------|
+| **Focus** | **_Who_** has access and **_how_** it is used. | Protect against unauthorized access. |
+| **Nature** | A legal concept / human rights. | A suite of security measures. |
+| **Goals** | Ensures user consent and lawful data handling. | Ensures data availability, integrity, and confidentiality. |
-
+
-
+
diff --git a/guides/security/overview.md b/guides/security/overview.md
index 249401071a..3b60ec9a08 100644
--- a/guides/security/overview.md
+++ b/guides/security/overview.md
@@ -1,178 +1,142 @@
---
synopsis: >
- This section provides an overview about the security architecture of CAP applications on different platforms.
+ This section provides an overview of the security concepts and architecture of CAP applications on different platforms.
status: released
uacp: Used as link target from SAP Help Portal at https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/9186ed9ab00842e1a31309ff1be38792.html
---
-# Platform Security
+# Overview of Security Concepts and Architecture
{{ $frontmatter.synopsis }}
[[toc]]
-## Platform Compliance { #platform-compliance }
+## Key Concepts { #key-concepts }
-CAP applications run in a certain environment, that is, in the context of some platform framework that has specific characteristics.
-The underlying framework has a major impact on the security of the application,
-regardless of whether it runs a [cloud](#cloud) environment or [local](#local) environment.
-Moreover, CAP applications are tightly integrated with [platform services](#btp-services), in particular with identity and persistence service.
+CAP's security architecture is built on several fundamental principles that enable flexible, secure, and maintainable applications.
+These concepts work together to provide comprehensive security while maintaining developer productivity and operational efficiency.
-::: warning End-to-end security necessarily requires compliance with all security policies of all involved components.
-CAP application security requires consistent security configuration of the underlying platform and all consumed services. Consult the relevant security documentation accordingly.
-:::
+### Pluggable Building Blocks { #key-concept-pluggable }
-### CAP in Cloud Environment { #cloud }
+CAP divides the different security-related tasks into separate and independent building blocks, each with a standard CAP implementation suitable for most scenarios.
-Currently, CAP supports to run on two cloud runtimes of [SAP Business Technology Platform](https://help.sap.com/docs/btp):
+{width="700px" }
-- [SAP BTP, Cloud Foundry Runtime](https://help.sap.com/docs/btp/sap-business-technology-platform/cloud-foundry-environment)
-- [SAP BTP, Kyma Runtime](https://help.sap.com/docs/btp/sap-business-technology-platform/kyma-environment)
+The building blocks are:
-Application providers are responsible to ensure a **secure platform environment**.
-In particular, this includes *configuring* [platform services](#btp-services) the application consumes.
-For instance, the provider (user) administrator needs to configure the [identity service](#identity-service) to separate platform users from business users that come from different identity providers.
-Likewise login policies (for example, multifactor authentication or single-sign-on) need to be aligned with company-specific requirements.
+- [Authentication](./authentication )
+- [CAP Users](./cap-users)
+- [CAP Authorization](./authorization)
+- [Outbound Authentication](./remote-authentication)
-Note, that achieving production-ready security requires to meet all relevant aspects of the **development process** as well.
-For instance, source code repositories need to be protected and may not contain any secrets or personal data.
-Likewise, the **deployment process** needs to be secured. That includes not only setting up CI/CD pipelines running on technical platform users, but also defining integration tests to ensure properly secured application endpoints.
+**By separating these concerns**, CAP ensures that each security function can be configured and customized independently without affecting other parts of the system, providing maximum flexibility.
-As part of **secure operations**, application providers need to establish a patch and vulnerability management, as well as a secure support process. For example, component versions need to be updated and credentials need to be rotated regularly.
+For example, authentication can be delegated to a [separate ingress component](./authentication#fully-auth), while authorization remains within the application service close to the data.
-::: warning
-The application provider is responsible to **develop, deploy, and operate the application in a secure platform environment**.
-CAP offers seamless integration into platform services and tools to help to meet these requirements.
-:::
+### Customizable { #key-concept-customizable }
-Find more about BTP platform security here:
+Due to the plugin-based architecture, **you can modify CAP's standard functions as required or, if necessary, completely replace them**.
+This flexibility is crucial for scenarios where the default methods do not fully meet your application's requirements.
+Moreover, this integration helps to easily incorporate non-CAP and even non-BTP services, thereby providing a flexible and interoperable environment.
-[SAP BTP Security](https://help.sap.com/docs/btp/sap-business-technology-platform/security-e129aa20c78c4a9fb379b9803b02e5f6){.learn-more}
-[SAP BTP Security Recommendations](https://help.sap.com/docs/btp/sap-btp-security-recommendations-c8a9bb59fe624f0981efa0eff2497d7d/sap-btp-security-recommendations){.learn-more}
-[SAP BTP Security (Community)](https://pages.community.sap.com/topics/btp-security){.learn-more}
+{width="600px" }
+For instance, you can define specific endpoints with a [custom authentication strategy](./authentication#custom-auth).
+Likewise, you can override the CAP representation of the request user to match additional, application-specific requirements.
-
+### Built on Best of Breed { #key-concept-platform-services }
-### CAP in Local Environment { #local }
+CAP does not deal with user login flows, password and credential management, user sessions, or any cryptographic logic - **and applications should definitely not do so!**
+Instead, **CAP seamlessly integrates with battle-tested [platform services](#btp-services)** that handle these critical security topics centrally.
+This approach not only simplifies the implementation but also enhances security by leveraging robust, well-tested mechanisms provided by the platform.
+Built on platform services, CAP allows developers to focus on core application functionality without worrying about the intricacies of security implementation.
-Security not only plays a crucial role in [cloud](#cloud) environments, but also during local development.
-Apparently the security requirements are different from cloud scenario as local endpoints are typically not exposed for remote clients.
-But there are still a few things to consider because exploited vulnerabilities could be the basis for attacks on productive cloud services:
+Most notably, authentication is covered by CAP-integration of [platform's identity services](./authentication#ias-auth).
+Likewise, TLS termination is offered by the [platform infrastructure](#platform-environment).
-- Make sure that locally started HTTP endpoints are bound to `localhost`.
-- In case you run your service in hybrid mode with bindings to cloud service instances,
-use [cds bind](../../advanced/hybrid-testing) instead of copying bindings manually to `default-env.json` file.
-`cds bind` avoids materialization of secrets to local disc, which is inherently dangerous.
-- Don't write sensitive data to application logs, also not via debug logging.
-- Don't test with real business data, for example, copied from a productive system.
+{width="600px" }
+### Decoupled from Business Logic { #key-concept-decoupled-coding }
-### SAP BTP Services for Security { #btp-services}
+As security functions are factorized into independent components, **application code is entirely decoupled** and hence is not subject to change for any security-related adaptations.
+This ensures that business logic remains independent of platform services, which are often subject to security-hardening initiatives.
+As a welcome side effect, this also allows testing application security in a **local test or development setup in a self-contained way**.
-SAP BTP provides a range of platform services that your CAP applications can utilize to meet production-grade security requirements. To ensure the security of your CAP applications, it's crucial to comply with the service level agreement (SLA) of these platform services. *As the provider of the application, you play a key role in meeting these requirements by correctly configuring and using these services.*
+For instance, CAP allows performing outbound service calls via [Remote Services while handling authentication completely under the hood](./remote-authentication#remote-services).
+This abstraction layer ensures that developers do not need to worry about the details of authentication.
-::: tip
-SAP BTP services and the underlying platform infrastructure hold various certifications and attestations, which can be found under the naming of SAP Cloud Platform in the [SAP Trust Center](https://www.sap.com/about/trust-center/certification-compliance/compliance-finder.html?search=SAP%20Business%20Technology%20Platform%20ISO).
+::: warning Low-level application code is prone to configuration changes
+Application code that doesn't build on the abstractions provided by CAP, but instead uses the interfaces of the underlying security services directly, is highly vulnerable to configuration changes or behavioral changes on this level.
+For example, the application cannot be switched from TLS to mTLS-based communication with the platform services without rewriting custom code, if it doesn't consistently use Remote Services.
:::
-The CAP framework offers flexible APIs that you can integrate with various services, including your custom services. If you replace platform services with your custom ones, it's important to ensure that the service level agreements (SLAs) CAP depends on are still met.
+### Secure by Default { #key-concept-secure-by-default }
-The most important services for security offered by the platform:
-
-[Webcast SAP BTP Cloud Identity and Security Services](https://assets.dm.ux.sap.com/webinars/sap-user-groups-k4u/pdfs/221117_sap_security_webcast_series_sap_btp_cloud_identity_and_security_services.pdf){.learn-more}
-
-#### [SAP Cloud Identity Services - Identity Authentication](https://help.sap.com/docs/IDENTITY_AUTHENTICATION) { #identity-service }
-
-The Identity Authentication service defines the user base for (CAP) applications and services, and allows to control access.
-Customers can integrate their 3rd party or on-premise identity provider (IdP) and harden security by defining multifactor authentication or by narrowing client IP ranges.
-This service helps to introduce a strict separation between platform users (provider) and business users (subscribers), a requirement of CAP. It supports various authentication methods, including SAML 2.0 and [OpenID Connect](https://openid.net/connect/), and allows for the configuration of single sign-on access.
+CAP security features are configured by default. If different behavior is required, you must explicitly reconfigure or add custom code accordingly.
+CAP's security autoconfiguration approach significantly reduces the risk of misconfiguration - **override only when absolutely necessary and when all effects are safely controlled**.
-[Learn more in the security guide.](https://help.sap.com/docs/IDENTITY_AUTHENTICATION?#discover_task-security){.learn-more}
-
-#### [SAP Authorization and Trust Management Service](https://help.sap.com/docs/CP_AUTHORIZ_TRUST_MNG)
+For instance, endpoints of deployed CAP applications are [automatically authenticated](./authentication#model-auth), providing a secure baseline.
+Making endpoints public requires manual configuration in either the CAP model or the middleware.
-The service lets customers manage user authorizations in technical roles at application level, which can be aggregated into business-level role collections for large-scale cloud scenarios.
-Obviously, developers must define application roles carefully as they form basic access rules to business data.
-
-#### [SAP Malware Scanning Service](https://help.sap.com/docs/MALWARE_SCANNING)
-
-This service can be used to scan transferred business documents for malware and viruses.
-Currently, there is no CAP integration. A scan needs to be triggered by the business application explicitly.
-
-[Learn more in the security guide.](https://help.sap.com/docs/btp?#operate_task-security){.learn-more}
-
-#### [SAP Credential Store](https://help.sap.com/docs/CREDENTIAL_STORE)
-
-Credentials managed by applications need to be stored in a secure way.
-This service provides a REST API for (CAP) applications to store and retrieve credentials at runtime.
-
-[Learn more in the security guide.](https://help.sap.com/docs/CREDENTIAL_STORE?#discover_task-security){.learn-more}
-
-#### [SAP BTP Connectivity](https://help.sap.com/docs/CP_CONNECTIVITY)
+::: warning Application projects are still responsible overall
+CAP cannot guarantee end-to-end [product security](./data-protection) across all application layers by default.
+The application is responsible for coordinated overall configuration.
+:::
-The connectivity service allows SAP BTP applications to securely access remote services that run on the Internet or on-premise.
-It provides a way to establish a secure communication channel between remote endpoints that are connected via an untrusted network infrastructure.
-[Learn more in the security guide.](https://help.sap.com/docs/CP_CONNECTIVITY/cca91383641e40ffbe03bdc78f00f681/cb50b6191615478aa11d2050dada467d.html){.learn-more}
-## Architecture and Platform Requirements
+## Security Architecture
-As [pointed out](#platform-compliance), CAP cloud applications run in a specific context that has a major impact on the security [architecture](#architecture-overview).
-CAP requires a dedicated [platform environment](#platform-environment) to integrate with, in order to ensure end-to-end security.
+CAP applications run in a specific context that has a major impact on the security [architecture](#architecture-overview).
+CAP requires a dedicated [platform environment](#platform-environment) to integrate with to ensure end-to-end security.
### Architecture Overview { #architecture-overview }
-The following diagram provides a high-level overview about the security-relevant aspects of a deployed CAP application in a cloud environment:
+The following diagram provides a high-level overview of the security-relevant components and interfaces of a deployed CAP application in a cloud environment:
-
{width="600px"}
-To serve a business request, different runtime components are involved: a request, issued by a UI or technical client ([public zone](#public-zone)), is forwarded by a gateway or ingress router to the CAP application. In case of a UI request, an [Application Router](https://help.sap.com/docs/btp/sap-business-technology-platform/application-router) instance acts as a proxy. The CAP application might make use of a CAP sidecar. All application components ([application zone](#application-zone)) might make use of platform services such as database or identity service ([platform zone](#platform-zone)).
+To serve a business request, different runtime components are involved: a request, issued by a UI or technical client ([public zone](#public-zone)), is forwarded by a gateway or ingress router to the CAP application. For a UI request, an [Application Router](https://help.sap.com/docs/btp/sap-business-technology-platform/application-router) instance acts as a proxy to manage the login flow and the browser session. The CAP application can have additional services such as a CAP sidecar. All application components ([application zone](#application-zone)) might make use of platform services such as database or identity service ([platform zone](#platform-zone)).
#### Public Zone { #public-zone }
From CAP's point of view, all components without specific security requirements belong to the public zone.
Therefore, you shouldn't rely on the behavior or structure of consumer components like browsers or technical clients for the security of server components.
The platform's gateway provides a single point of entry for any incoming call and defines the API visible to the public zone.
-As malicious users have free access to the public zone, these endpoints need to be protected carefully.
+Since malicious users have free access to the public zone, you must protect these endpoints carefully.
Ideally, you should limit the number of exposed endpoints to a minimum, perhaps through proper network configuration.
#### Platform Zone { #platform-zone }
The platform zone contains all platform components and services that are *configured and maintained* by the application provider.
CAP applications consume these low-level [platform services](#btp-services) to handle more complex business requests.
-For instance, persistence service to store business data and identity service to authenticate the business user play a fundamental role.
+For instance, the persistence service stores business data and the identity service authenticates the business user. Both play a fundamental role.
The platform zone also includes the gateway, which is the main entry point for external requests. Additionally, it may contain extra ingress routers.
#### Application Zone { #application-zone}
-The application zone comprises all microservices that represent a CAP application. They are tightly integrated and form a unit of trust. The application provider is responsible to *develop, deploy and operate* these services:
+The application zone comprises all microservices that represent a CAP application. They are tightly integrated and form a **unit of trust**. The application provider is responsible for *developing, deploying, and operating* these services:
-- The [Application Router](https://help.sap.com/docs/btp/sap-business-technology-platform/application-router) acts as as an optional reverse proxy wrapping the application service and providing business-independent functionality required for UIs.
+- The [Application Router](https://help.sap.com/docs/btp/sap-business-technology-platform/application-router) acts as an optional reverse proxy wrapping the application service and providing business-independent functionality required for UIs.
This includes serving UI content, providing a login flow as well as managing the session with the browser.
-It can be deployed as application (reusable module) or alternatively consumed as a [service](https://help.sap.com/docs/btp/sap-business-technology-platform/managed-application-router).
+You can deploy it as an application (reusable module) or alternatively consume it as a [service](https://help.sap.com/docs/btp/sap-business-technology-platform/managed-application-router).
- The CAP application service exposes the API to serve business requests. Usually, it makes use of lower-level platform services. As built on CAP, a significant number of security requirements is covered either out of the box or by adding minimal configuration.
- The optional CAP sidecar (reusable module) is used to outsource application-independent tasks such as providing multitenancy and extension support.
-Application providers, that is platform users, have privileged access to the application zone.
-In contrast, application subscribers, that is business users, are restricted to a minimal interface.
-
-::: warning
-❗ Application providers **may not share any secrets from the application zone** such as binding information with other components or persons.
-In a productive environment, it is recommended to deploy and operate the application on behalf of a technical user.
-:::
+Application providers (platform users) have privileged access to the application zone.
+In contrast, application subscribers (business users) are restricted to a minimal interface.
-::: tip
-Without limitation of generality, there may be multiple CAP services or sidecars according to common [microservice architecture pattern](https://microservices.io/patterns/microservices.html).
+::: warning Do not share secrets
+Application providers **must not share any secrets from the application zone** such as binding information with other components or persons.
+In a production environment, we recommend deploying and operating the application on behalf of a technical user.
:::
-### Required Platform Environment { #platform-environment }
+### Platform Requirements { #platform-environment }
There are several assumptions that a CAP application needs to make about the platform environment it is deployed to:
@@ -180,18 +144,129 @@ There are several assumptions that a CAP application needs to make about the pla
Hence, the **CAP application can offer a pure HTTP endpoint** without having to enforce TLS and to deal with certificates.
2. The server certificates presented by the external endpoints are signed by a trusted certificate authority.
-This **frees CAP applications from the need to manage trust certificates**. The underlying runtimes (Java or Node) can validate the server certificates by default.
+This **frees CAP applications from the need to manage trust certificates**. The underlying runtimes (Java or Node.js VMs) can validate the server certificates by default.
-3. **Secrets** that are required to protect the application or to consume other platform services **are injected by the platform** into the application in a secure way.
+3. **Secrets** that are required to protect the application or to consume other platform services **are injected by the platform** into the application microservices in a secure way.
-All supported [environments](overview#cloud) fulfill the given requirements. Additional requirements could be added in future.
+All supported [environments](#cloud) fulfill the given requirements. Additional requirements may be added in future.
-::: tip
-Custom domain certificates need to be signed by trusted certificate authority.
+::: tip Sign custom certificates
+Custom domain certificates must be signed by a trusted certificate authority.
:::
-::: warning
-❗ **In general, application endpoints are visible to public zone**. Hence, CAP can't rely on private endpoints.
-In particular, an application router does not prevent external access to the CAP application service.
-As a consequence, **all CAP endpoints must be protected in an appropriate manner**.
+::: warning Application endpoints are visible to the public zone
+Hence, CAP applications need to protect all exposed endpoints.
:::
+
+
+## Platform Compliance { #platform-compliance }
+
+CAP applications run in a certain environment, that is, in the context of some platform framework that has specific characteristics as explained [before](#platform-environment).
+The underlying framework has a major impact on the security of the application,
+regardless of whether it runs a [cloud environment](#cloud) or [local environment](#local).
+Moreover, CAP applications are tightly integrated with [platform services](#btp-services), in particular with identity and persistence service.
+
+::: warning End-to-end security necessarily requires compliance with all security policies of all involved components
+CAP application security requires consistent security configuration of the underlying platform and all consumed services. Consult the relevant security documentation accordingly.
+:::
+
+### CAP in Local Environment { #local }
+
+Security not only plays a crucial role in [cloud environments](#cloud), but also during local development.
+Apparently the security requirements are different from cloud scenario as local endpoints are typically not exposed for remote clients.
+But there are still a few things to consider because exploited vulnerabilities could be the basis for attacks on productive cloud services:
+
+#### DO:{.good}
+
+- Make sure that locally started HTTP endpoints are bound to `localhost`.
+- Use [cds bind](../../tools/cds-bind) to run your service in hybrid mode with bindings to cloud service instances. `cds bind` avoids materialization of secrets to local disc, which is inherently dangerous. The opposite is consequently a **Don't**.
+
+#### DON'T:{.bad}
+- Don't copy bindings manually to `default-env.json` file or otherwise on your local disc.
+- Don't write sensitive data to application logs, also not via debug logging.
+- Don't test with real business data, for example, copied from a productive system.
+
+
+### CAP in Cloud Environment { #cloud }
+
+Currently, CAP supports to run on two cloud runtimes of [SAP Business Technology Platform](https://help.sap.com/docs/btp):
+
+- [SAP BTP, Cloud Foundry Runtime](https://help.sap.com/docs/btp/sap-business-technology-platform/cloud-foundry-environment)
+- [SAP BTP, Kyma Runtime](https://help.sap.com/docs/btp/sap-business-technology-platform/kyma-environment)
+
+Application providers are responsible for ensuring a **secure platform environment**.
+In particular, this includes *configuring* [platform services](#btp-services) the application consumes.
+For instance, you as the provider (user) administrator need to configure the [identity service](#identity-service) to separate platform users from business users that come from different identity providers.
+Likewise, login policies (for example, multifactor authentication or single-sign-on) must be aligned with company-specific requirements.
+
+Note that achieving production-ready security requires meeting all relevant aspects of the **development process** as well.
+For instance, source code repositories must be protected and must not contain any secrets or personal data.
+Likewise, the **deployment process** must be secured. This includes not only setting up CI/CD pipelines running on technical platform users, but also defining integration tests to ensure properly secured application endpoints.
+
+As part of **secure operations**, application providers must establish patch and vulnerability management, as well as a secure support process. For example, component versions must be updated and credentials must be rotated regularly.
+
+::: warning Applications must use secure platform environments
+The application provider is responsible to **develop, deploy, and operate the application in a secure platform environment**.
+CAP offers seamless integration into platform services and tools to help to meet these requirements.
+:::
+
+Find more about BTP platform security here:
+
+[SAP BTP Security](https://help.sap.com/docs/btp/sap-business-technology-platform/security-e129aa20c78c4a9fb379b9803b02e5f6){.learn-more}
+[SAP BTP Security Recommendations](https://help.sap.com/docs/btp/sap-btp-security-recommendations-c8a9bb59fe624f0981efa0eff2497d7d/sap-btp-security-recommendations){.learn-more}
+[SAP BTP Security (Community)](https://pages.community.sap.com/topics/btp-security){.learn-more}
+
+
+
+
+
+
+### Security Platform Services { #btp-services }
+
+SAP BTP provides a range of platform services that your CAP applications can use to meet production-grade security requirements. To ensure the security of your CAP applications, comply with the service level agreement (SLA) of these platform services. *As the provider of the application, you play a key role in meeting these requirements by correctly configuring and using these services.*
+
+::: tip Compliance documents in SAP Trust Center
+SAP BTP services and the underlying platform infrastructure hold various certifications and attestations, which can be found under the naming of SAP Cloud Platform in the [SAP Trust Center](https://www.sap.com/about/trust-center/certification-compliance/compliance-finder.html?search=SAP%20Business%20Technology%20Platform%20ISO).
+:::
+[Webcast SAP BTP Cloud Identity and Security Services](https://assets.dm.ux.sap.com/webinars/sap-user-groups-k4u/pdfs/221117_sap_security_webcast_series_sap_btp_cloud_identity_and_security_services.pdf){.learn-more}
+
+
+The CAP framework offers flexible APIs that you can integrate with various services, including your custom services. If you replace platform services with your custom ones, ensure that the service level agreements (SLAs) CAP depends on are still met.
+
+The most important services for security offered by the platform:
+
+#### [SAP Cloud Identity Services - Identity Authentication](https://help.sap.com/docs/IDENTITY_AUTHENTICATION) { #identity-service }
+
+The Identity Authentication service defines the user base for (CAP) applications and services, and allows you to control access.
+You can integrate your third-party or on-premise identity provider (IdP) and harden security by defining multifactor authentication or by narrowing client IP ranges.
+This service helps introduce a strict separation between platform users (provider) and business users (subscribers), a requirement of CAP. It supports various authentication methods, including SAML 2.0 and [OpenID Connect](https://openid.net/connect/), and allows you to configure single sign-on access.
+
+[Learn more in the SAP Cloud Identity - Security Guide.](https://help.sap.com/docs/IDENTITY_AUTHENTICATION?#discover_task-security){.learn-more}
+
+#### [SAP Authorization and Trust Management Service](https://help.sap.com/docs/CP_AUTHORIZ_TRUST_MNG)
+
+The service allows customers to manage user authorizations in technical roles at the application level, which can be aggregated into business-level role collections for large-scale cloud scenarios.
+Developers must define application roles carefully as they form the basic access rules for business data.
+
+[Learn more in the SAP Authorization and Trust Management service guide.](https://help.sap.com/docs/btp/sap-business-technology-platform/btp-security){.learn-more}
+
+#### [SAP BTP Connectivity](https://help.sap.com/docs/CP_CONNECTIVITY)
+
+The connectivity service allows SAP BTP applications to securely access remote services that run on the Internet or on-premise.
+It provides a way to establish a secure communication channel between remote endpoints that are connected via an untrusted network infrastructure.
+
+[Learn more in the SAP BTP Connectivity guide.](https://help.sap.com/docs/CP_CONNECTIVITY/cca91383641e40ffbe03bdc78f00f681/cb50b6191615478aa11d2050dada467d.html){.learn-more}
+
+#### [SAP Malware Scanning Service](https://help.sap.com/docs/MALWARE_SCANNING)
+
+This service scans transferred business documents for malware and viruses.
+Currently, there is no CAP integration. A scan must be triggered explicitly by the business application.
+
+[Learn more in the SAP Malware Scanning service guide.](https://help.sap.com/docs/btp?#operate_task-security){.learn-more}
+
+#### [SAP Credential Store](https://help.sap.com/docs/CREDENTIAL_STORE)
+
+Credentials managed by applications must be stored securely.
+This service provides a REST API for (CAP) applications to store and retrieve credentials at runtime.
+
+[Learn more in the SAP Credential Store guide.](https://help.sap.com/docs/CREDENTIAL_STORE?#discover_task-security){.learn-more}
diff --git a/guides/security/remote-authentication.md b/guides/security/remote-authentication.md
new file mode 100644
index 0000000000..de04d59beb
--- /dev/null
+++ b/guides/security/remote-authentication.md
@@ -0,0 +1,447 @@
+---
+# layout: cookbook
+label: Outbound Authentication
+synopsis: >
+ This guide explains how to authenticate remote services.
+status: released
+---
+
+
+
+
+
+# Outbound Authentication { #remote-authentication }
+
+
+
+This guide explains how to authenticate remote services.
+
+[[toc]]
+
+## Remote Service Abstraction { #remote-services }
+
+According to the key concept of [pluggable building blocks](./overview#key-concept-pluggable), the architecture of CAP's [Remote Services](../services/consuming-services#consuming-services) decouples protocol level (that is, exchanged content) from connection level (that is, established connection channel).
+While the business context of the application impacts the protocol, the connectivity of the service endpoints is independent of it and mainly depends on platform-level capabilities.
+The latter is frequently subject to change and therefore should not introduce application dependencies.
+
+{width="400px" }
+
+At the connectivity layer, the following basic tasks can be addressed generically:
+- Authentication (_how to set up a trusted channel_)
+- Destination (_how to find the target service_)
+- User propagation (_how to transport user information_)
+
+CAP's connectivity component handles authentication (IAS, XSUAA, X.509, ZTID, ...), destination (local destination, BTP Destination, BTP Service Binding), and user propagation (technical provider, technical subscriber, named user) transparently through configuration.
+All three service scenarios can be addressed through configuration variants of the same remote service concept, as shown in the following sections.
+
+CAP supports out-of-the-box consumption of various types of [remote services]( #remote-services):
+
+* [Co-located services](#co-located-services) as part of the same deployment and bound to the same identity instance (that is, belong to the same trusted [application zone](./overview#application-zone)).
+* [External services](#app-to-app) that can be running on non-BTP platforms.
+* [BTP reuse services](#ias-reuse) consumed via service binding.
+
+
+## Co-located Services {#co-located-services}
+
+Co-located services do not run in the same microservice, but are typically part of the same deployment unit and hence reside within the same trust boundary of the [application zone](./overview#application-zone).
+Logically, such co-located services contribute to the application equally and could run as integrated services in the same microservice, but for technical reasons (for example, different runtime or scaling requirements) they are separated physically, often as a result of a [late-cut microservice approach](../deploy/microservices#late-cut-microservices).
+
+Technically, **they share the same identity instance, which allows direct token forwarding**:
+
+{width="450px" }
+
+[Learn more about how to configure co-located services in CAP Java](/java/cqn-services/remote-services#binding-to-a-service-with-shared-identity) {.learn-more}
+
+You can test CAP's built-in support for co-located services in practice by modifying the [`xflights-java`](https://github.com/capire/xflights-java/tree/main) and [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) sample applications.
+`xflights-java` acts as a master data provider exposing basic flight data in service [`sap.capire.flights.data`](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24) via different protocols.
+On the client side, `xtravels-java` imports this service as a CAP remote service and fetches data in a [custom handler for data federation](https://github.com/capire/xtravels-java/blob/53a5fa33caf4c9068f2e66fab25bda26f3f450ca/srv/src/main/java/sap/capire/xtravels/handler/FederationHandler.java#L63).
+
+::: tip
+CAP offers a simplified co-located service setup by leveraging remote services that require:
+- Shared identity instance
+- URL for the destination
+- Principal propagation mode (optional)
+:::
+
+
+To combine both applications in a co-located setup, follow these steps:
+
+#### 1. Prepare the CF environment { #prepare }
+
+Make sure that you've prepared a [local environment for CF deployments](../deploy/to-cf#prerequisites) and in addition:
+- A Cloud Foundry (CF) space in a subaccount.
+- [HANA Cloud instance](https://help.sap.com/docs/hana-cloud/sap-hana-cloud-administration-guide/create-sap-hana-database-instance-using-sap-hana-cloud-central) mapped to the CF space.
+- [IAS tenant](./authentication#ias-ready) mapped to the subaccount.
+
+
+#### 2. Prepare and deploy the consumer application { #co-located-consumer }
+
+As client, `xtravels-srv` first needs a valid configuration for the remote service `sap.capire.flights.data`:
+
+::: code-group
+
+```yaml [/srv/src/main/resources/application.yaml]
+---
+spring:
+ config.activate.on-profile: cloud
+cds:
+ remote.services:
+ xflights:
+ type: hcql
+ model: sap.capire.flights.data
+ binding:
+ name: xtravels-ias
+ options:
+ url: https://
/hcql
+ onBehalfOf: systemUserProvider
+```
+:::
+
+The `type` property activates the protocol for exchanging business data and must be offered by the provider [CDS service](https://github.com/capire/xflights-java/blob/6fc7c665c63bb6d73e28c11b391b1ba965b8772c/srv/data-service.cds#L24).
+The `model` property needs to match the fully qualified name of the CDS service from the imported model.
+You can find CDS service definition of `sap.capire.flights.data` in file `target/cds/capire/xflight-data/service.cds` resolved during CDS build step.
+The `binding.name` needs to point to the shared identity instance and `options.url` provides the required location of the remote service endpoint.
+Finally, `onBehalfOf: systemUserProvider` specifies that the remote call is invoked on behalf of the technical provider tenant.
+
+
+Now you are ready to deploy the application with
+
+```sh
+cd ./xtravels_java
+cds up
+```
+
+❗Note that CF application `xtravels-srv` will not start successfully as long as `xflights` is not deployed yet (step 3).
+
+::: tip
+For production deployment, it is recommended to combine both services with the shared identity instance in a [single MTA descriptor](../deploy/microservices#all-in-one-deployment).
+:::
+
+
+#### 3. Prepare and deploy the provider application { #co-located-provider }
+
+As server, `xflights-srv` needs to restrict service `sap.capire.flights.data` to the technical client calling from of the same application.
+This can be done by adding pseudo-role [`internal-user`](./cap-users#pseudo-roles) to the service:
+
+::: code-group
+```cds [/srv/authorization.cds]
+using { sap.capire.flights.data as data } from './data-service';
+
+annotate data with @(requires: 'internal-user');
+```
+:::
+
+::: tip
+For different [user propagation](./cap-users#remote-services) modes the remote service can be configured appropriately.
+The provider service authorization needs to align with the configured user propagation.
+:::
+
+Additionally, to establish the co-located setup, the microservice needs to share the same identity instance:
+
+::: code-group
+
+```yaml [/srv/srv/main/resources/application.yaml]
+resources:
+ - name: xflights-ias
+ type: org.cloudfoundry.managed-service # [!code --]
+ type: org.cloudfoundry.existing-service # [!code ++]
+ parameters:
+ service: identity # [!code --]
+ service-name: xflights-ias # [!code --]
+ service-name: xtravels-ias # [!code ++]
+ service-plan: application # [!code --]
+ config: # [!code --]
+ display-name: xflights # [!code --]
+```
+
+:::
+
+Finally, deploy and start the application with
+
+```sh
+cd ./xflights_java
+cds up
+```
+
+#### 4. Verify the deployment { #verify }
+
+First, you can check the overall deployment status at the CF CLI level. Specifically, the application services must be started successfully and the shared identity instance must be verified.
+
+::: details Verify: `cf apps` should show the following lines:
+
+::: code-group
+```sh
+name requested state processes routes
+xflights-db-deployer stopped web:0/1
+xflights-srv started web:1/1 ...
+xtravels started web:1/1 ...
+xtravels-ams-policies-deployer stopped web:0/1
+xtravels-db-deployer stopped web:0/1
+xtravels-srv started web:1/1 ...
+```
+:::
+
+::: details Verify: `cf services` should show the following lines:
+
+::: code-group
+```sh
+xflights-ias identity application
+xtravels-ias identity application xtravels, xtravels-srv, xflights-srv, ...
+```
+:::
+
+You can test the valid setup of the xtravels application by accessing the UI and logging in with an authorized test user of the IAS tenant.
+To do so, assign a proper AMS policy (for example, `admin`) to the test user as described [earlier](./cap-users#ams-deployment).
+
+
+::: tip
+The very same setup could be deployed for XSUAA-based services.
+:::
+
+
+## External Services
+
+In contrast to [co-located services](#co-located-services), external services do not have strong dependencies as they have a fully decoupled lifecycle and are provided by different owners.
+As a consequence, external services can run cross-regionally; even non-BTP systems might be involved.
+A prerequisite for external service calls is a trust federation between the consumer and the provider system.
+
+A seamless integration experience for external service communication is provided by [IAS App-2-App](#app-to-app) flows, which are offered by CAP via remote services.
+Alternatively, remote services can be configured on top of [BTP HTTP Destinations](../services/consuming-services#using-destinations) that offer [various authentication strategies](https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/http-destinations) such as SAML 2.0 as required by many S/4 system endpoints.
+
+
+### IAS App-2-App { #app-to-app }
+
+As a first-class citizen, [IAS](./authentication#ias-auth) is positioned to simplify cross-regional requests with user propagation.
+Prerequisites are identity instances on both consumer and provider sides, plus a registered IAS dependency in the consumer instance.
+
+{width="500px" }
+
+CAP supports communication between arbitrary IAS endpoints and remains transparent for applications as it builds on the same architectural pattern of [remote services](#remote-services).
+Technically, the connectivity component uses [IAS App-2-App flows](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/consume-apis-from-other-applications) in this scenario that requires a token exchange from a consumer token into a token for the provider.
+The latter is issued by IAS only if the consumer is configured with a valid IAS dependency pointing to the provider accordingly.
+
+:::tip
+CAP offers a simplified App-2-App setup by leveraging remote services that require:
+- Identity instances for provider and consumer
+- Configured IAS dependency from consumer to provider
+- Destination with URL pointing to the provider
+- Principal propagation mode (optional)
+:::
+
+[Learn more about how to consume external application APIs with IAS](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/consume-apis-from-other-applications) {.learn-more}
+
+
+
+#### 1. Prepare and deploy the provider application
+
+Assuming the same local CF environment setup as [here](#prepare), clone [`xflights-java`](https://github.com/capire/xflights-java/tree/main) or, if already cloned and modified locally, reset to the remote branch.
+
+Similar to the [co-located](#co-located-provider) variant, `xflights` needs to expose service `sap.capire.flights.data` to technical clients.
+The difference is that the consumers are not known a priori and are not part of the same application deployment.
+
+To expose service APIs for consumption, you can enhance the identity instance of the provider by defining API identifiers that are listed in property `provided-apis`:
+
+::: code-group
+```yaml [mta.yaml]
+resources:
+ - name: xflights-ias
+ type: org.cloudfoundry.managed-service
+ parameters:
+ [...]
+ config:
+ display-name: xflights
+ provided-apis: [{ # [!code ++:5]
+ name: DataConsumer,
+ description: Grants technical access to data service API
+ }]
+```
+:::
+
+The entry with name `DataConsumer` represents the consumption of service `sap.capire.flights.data` and is exposed as IAS API.
+The description helps administrators to configure the consumer application with the proper provider API if done on UI level.
+
+[Detailed description about identity instance parameters for `provided-apis`](https://github.wdf.sap.corp/pages/CPSecurity/sci-dev-guide/docs/BTP/identity-broker#service-instance-parameters){.learn-more}
+
+How can proper authorization be configured for _technical clients without user propagation_?
+OAuth tokens presented by valid consumer requests from an App-2-App flow will have API claim `DataConsumer`, which is automatically mapped to a CAP role by the runtime.
+Therefore, you can protect the corresponding CDS service by CAP role `DataConsumer` to authorize requests thoroughly:
+
+::: code-group
+```cds [/srv/authorization.cds]
+using { sap.capire.flights.data as data } from './data-service';
+
+annotate data with @(requires: 'DataConsumer');
+```
+:::
+
+Finally, deploy and start the application with
+
+```sh
+cd ./xflights_java
+cds up
+```
+
+
+::: tip API as CAP role
+The API identifiers exposed by the IAS instance in list `provided-apis` are granted as CAP roles after successful authentication and can be used in @requires annotations.
+:::
+
+::: warning Use different roles for technical and business users
+Use different CAP roles for technical clients without user propagation and for named business users.
+
+Instead of using the same role, expose dedicated CDS services to technical clients that are not accessible to business users and vice versa.
+:::
+
+#### 2. Prepare and deploy the consumer application { #consumer }
+
+Like with xflights, clone [`xtravels-java`](https://github.com/capire/xtravels-java/tree/main) or, if already cloned and modified locally, reset to remote branch.
+
+First, you need to add a BTP destination that points to the provider service endpoint to be called (`URL`) and that contains the information about the IAS dependency to be called (`cloudsdk.ias-dependency-name`).
+The name for the IAS dependency is flexible but **needs to match the chosen name in the next step** when [connecting consumer and provider in IAS](#connect).
+The connectivity component requires the destination to prepare the HTTP call accordingly. Also note that the authentication type of the destination is `NoAuthentication`, as the destination itself does not contribute to the authentication process.
+
+
+::: code-group
+
+```yaml [mta.yaml (destination instance)]
+ - name: xtravels-destination
+ type: org.cloudfoundry.managed-service
+ parameters:
+ service: destination
+ service-plan: lite
+ config:
+ init_data:
+ instance:
+ existing_destinations_policy: update
+ destinations:
+ - Name: xtravels-data-consumer
+ Type: HTTP
+ URL: https:///hcql
+ cloudsdk.ias-dependency-name: "DataConsumer"
+ Authentication: NoAuthentication
+ ProxyType: Internet
+ Description: "Data consumer destination for xtravels"
+```
+
+```yaml [mta.yaml (destination binding)]
+modules:
+ - name: xtravels-srv
+ type: java
+ [...]
+ requires:
+ - name: xtravels-destination # [!code ++]
+```
+
+:::
+
+:::tip
+Alternatively, the destination can also be created manually in the [BTP destination editor](https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/access-destinations-editor).
+:::
+
+
+Given the destination, the remote service can be configured in a very similar way as with [co-located services](#co-located-consumer).
+Currently, an additional Cloud SDK dependency `scp-cf` is required to support communication with the BTP destination service:
+
+::: code-group
+
+```yaml [/srv/srv/main/resources/application.yaml]
+spring:
+ config.activate.on-profile: cloud
+cds:
+ remote.services:
+ xflights:
+ type: hcql
+ model: sap.capire.flights.data
+ destination:
+ name: xtravels-data-consumer
+ onBehalfOf: systemUserProvider
+```
+
+```xml [/srv/pom.xml]
+
+ com.sap.cloud.sdk.cloudplatform
+ scp-cf
+ runtime
+
+```
+
+:::
+
+[Learn more about simplified Remote Service configuration with destinations](/java/cqn-services/remote-services#destination-based-scenarios) {.learn-more}
+
+Finally, deploy and start the application with
+
+```sh
+cd ./xtravels_java
+cds up
+```
+
+`xtravels-srv` is not expected to start successfully; instead, you should see error log messages like this:
+```yaml
+Remote HCQL service responded with HTTP status code '401', ...
+```
+
+Technically, the remote service implementation will delegate the HTTP connection setup to the connectivity component that can recognize by the type of destination that it needs to initiate an App-2-App flow.
+It then takes the token from the request and triggers an IAS token exchange for the target [IAS dependency](#connect) according to the user propagation strategy (technical communication here).
+As the IAS dependency is not created yet, IAS rejects the token exchange request and the call to the provider fails with `401` (not authenticated).
+
+Note that property `oauth2-configuration.token-policy.access-token-format: jwt` is set in the identity instance to ensure the exchanged token has JWT format.
+
+#### 3. Connect consumer with provider { #connect }
+
+Now let's create the missing IAS dependency to establish trust for the API service call targeting provided API with id `DataConsumer`.
+
+Open the Administrative Console for the IAS tenant (see prerequisites [here](./authentication#ias-admin)):
+
+1. Select **Applications & Resources** > **Applications**. Choose the IAS application of the `xtravels` consumer from the list.
+2. In **Application APIs** select **Dependencies** and click on **Add**.
+3. Type `DataConsumer` as dependency name (needs to match property value `cloudsdk.ias-dependency-name`) and pick provided API `DataConsumer` from the provider IAS application `xflights`.
+4. Confirm with **Save**
+
+::: details Create IAS dependency in Administrative Console
+
+ {width="500px" }
+
+ {width="500px" }
+
+:::
+
+
+
+
+Now restart the consumer application with
+
+```sh
+cf restart xtravels-srv
+```
+
+to trigger a successful startup with valid flight data retrieved from the provider.
+
+You can now test the valid setup of the xtravels application by accessing the UI and logging in with an authorized test user of the IAS tenant.
+To do so, assign a proper AMS policy (e.g., `admin`) to the test user as described [earlier](./cap-users#ams-deployment).
+
+
+
+
+
+## Pitfalls
+
+- **Don't write custom integration logic** for consumed services.
+Leverage CAP's remote service architecture instead to ensure a seamless integration experience.
+
+- **Don't implement connectivity layer code** (for example, to fetch or exchange tokens).
+Instead, rely on the shared connectivity component, which ensures centralized and generic processing of outbound requests.
+
+- **Don't treat co-located services as external services**.
+This introduces unnecessary communication overhead and increases total cost of ownership.
+
+
diff --git a/guides/services/_menu.md b/guides/services/_menu.md
new file mode 100644
index 0000000000..17e2b37d26
--- /dev/null
+++ b/guides/services/_menu.md
@@ -0,0 +1,7 @@
+# [Define Provided Services](providing-services)
+# [Served Out-of-the-Box](served-ootb)
+# [Status Flows](status-flows)
+# [Constraints](constraints)
+# [Event Handlers](custom-code)
+# [Actions & Functions](custom-actions)
+# [Serving Media Data](media-data)
diff --git a/guides/services/assets/fiori-errors.png b/guides/services/assets/fiori-errors.png
new file mode 100644
index 0000000000..3e104ae7d9
Binary files /dev/null and b/guides/services/assets/fiori-errors.png differ
diff --git a/guides/assets/using-services/risk-mgmt.drawio.svg b/guides/services/assets/risk-mgmt.drawio.svg
similarity index 100%
rename from guides/assets/using-services/risk-mgmt.drawio.svg
rename to guides/services/assets/risk-mgmt.drawio.svg
diff --git a/guides/assets/providing-services/service-apis.drawio.svg b/guides/services/assets/service-apis.drawio.svg
similarity index 100%
rename from guides/assets/providing-services/service-apis.drawio.svg
rename to guides/services/assets/service-apis.drawio.svg
diff --git a/guides/assets/providing-services/service-as-facades.drawio.svg b/guides/services/assets/service-as-facades.drawio.svg
similarity index 100%
rename from guides/assets/providing-services/service-as-facades.drawio.svg
rename to guides/services/assets/service-as-facades.drawio.svg
diff --git a/guides/assets/providing-services/service-centric-paradigm.drawio.svg b/guides/services/assets/service-centric-paradigm.drawio.svg
similarity index 100%
rename from guides/assets/providing-services/service-centric-paradigm.drawio.svg
rename to guides/services/assets/service-centric-paradigm.drawio.svg
diff --git a/guides/assets/providing-services/services-events.drawio.svg b/guides/services/assets/services-events.drawio.svg
similarity index 100%
rename from guides/assets/providing-services/services-events.drawio.svg
rename to guides/services/assets/services-events.drawio.svg
diff --git a/guides/assets/flows/xtravels-flow-previous.svg b/guides/services/assets/xtravels-flow-previous.svg
similarity index 100%
rename from guides/assets/flows/xtravels-flow-previous.svg
rename to guides/services/assets/xtravels-flow-previous.svg
diff --git a/guides/assets/flows/xtravels-flow-simple.svg b/guides/services/assets/xtravels-flow-simple.svg
similarity index 100%
rename from guides/assets/flows/xtravels-flow-simple.svg
rename to guides/services/assets/xtravels-flow-simple.svg
diff --git a/guides/services/constraints.md b/guides/services/constraints.md
index 5e5eee18d6..b92244c687 100644
--- a/guides/services/constraints.md
+++ b/guides/services/constraints.md
@@ -1,20 +1,17 @@
---
-synopsis: >
- Declarative constraints allow you to express conditions using CXL expressions that are validated automatically whenever data is written, greatly reducing the need for extensive custom code for input validation.
status: released
---
# Declarative Constraints
-Declarative constraints allow you to express conditions using [CDS Expression Language (CXL)](/cds/cxl) that are validated automatically whenever data is written. This greatly reduces the need for extensive custom code for input validation.
-
-> [!note]
-> Don't confuse declarative constraints as discussed in here with [database constraints](../databases#database-constraints). Declarative constraints are meant for domain-specific input validation with error messages meant to be shown to end users, while database constraints are meant to prevent data corruption due to programming error, with error messages not intended for end users.
-
-
+Declarative constraints allow you to express data validity conditions using [CDS Expression Language (CXL)](../../cds/cxl.md) that are enforced automatically whenever data is written. This greatly reduces the need for extensive custom code for input validation.
+{.abstract}
[[toc]]
+> [!note]
+> Don't confuse constraints as discussed in here with [database constraints](../databases/cdl-to-ddl#database-constraints). Declarative constraints are meant for domain-specific input validation with error messages meant to be shown to end users, while database constraints are meant to prevent data corruption due to programming error, with error messages not intended for end users.
+
## Introduction
@@ -59,7 +56,8 @@ annotate TravelService.Travels with {
:::
-> [!tip] BEST PRACTICES
+> [!tip]
+> **BEST PRACTICES** applied here
>
> **Separation of Concerns** – always put secondary concerns, such as constraints in this case, into separate files as in the example, instead of polluting your core service definitions.
>
@@ -81,7 +79,7 @@ Some of the checks, e.g. the static `@mandatory` checks, are validated directly
::: details Behind the scenes...
-The automatically compiled and executed validation query would look like that (in [CQL](/cds/cql)) for the constraints from the sample above:
+The automatically compiled and executed validation query would look like that (in [CQL](../../cds/cql)) for the constraints from the sample above:
```sql
SELECT from TravelService.Travels {
@@ -116,7 +114,8 @@ SELECT from TravelService.Travels {
-> [!tip] BEST PRACTICES
+> [!tip]
+> **BEST PRACTICES** applied here
>
> **Push down to the database** is a general principle applied in CAP. Applied to input validation with declarative constraints it means that instead of reading a lot of related data into the service layer to do the checks there, we push down the respective checks to where the data is (in the database).
>
@@ -130,7 +129,7 @@ SELECT from TravelService.Travels {
For Fiori UIs as clients the error messages will be automatically be equiped with relevant `target` properties to attach them to the respective fields on the UIs. For example a Fiori UI for the sample above, would display returned errors like that:
-
+
::: details Behind the scenes ...
@@ -225,7 +224,7 @@ annotate TravelService.Bookings with {
```
-We can also do checks with sets of related data using path expressions which navigate along **to-many associations** or compositions, combined with SQL's `exists` quantifier, and optional [infix filters](../..//cds/cql#with-infix-filters), as shown in this example:
+We can also do checks with sets of related data using path expressions which navigate along **to-many associations** or compositions, combined with SQL's `exists` quantifier, and optional [infix filters](../../cds/cql#with-infix-filters), as shown in this example:
```cds
annotate TravelService.Travels with {
@@ -312,7 +311,7 @@ dependent values were inserted before the current transaction. For example, in a
The `@assert.target` check constraint is meant to **validate user input** and not to ensure referential integrity.
Therefore only `CREATE`, and `UPDATE` events are supported (`DELETE` events are not supported). To ensure that every
non-null foreign key in a table has a corresponding primary key in the associated/referenced target table
-(ensure referential integrity), the [`@assert.integrity`](../databases#database-constraints) constraint must be used instead.
+(ensure referential integrity), the [`@assert.integrity`](../databases/cdl-to-ddl#database-constraints) constraint must be used instead.
If the reference's target doesn't exist, an HTTP response
(error message) is provided to HTTP client applications and logged to stdout in debug mode. The HTTP response body's
@@ -387,7 +386,7 @@ Elements annotated with `@readonly`, as well as [_calculated elements_](../../cd
By default [`virtual` elements](../../cds/cdl#virtual-elements) are also _calculated_.
::: tip
-The same applies for fields with the [OData Annotations](../../advanced/odata#annotations) `@FieldControl.ReadOnly` (static), `@Core.Computed`, or `@Core.Immutable` (the latter only on UPDATEs).
+The same applies for fields with the [OData Annotations](../protocols/odata#annotations) `@FieldControl.ReadOnly` (static), `@Core.Computed`, or `@Core.Immutable` (the latter only on UPDATEs).
:::
::: warning Not allowed on keys
@@ -455,7 +454,7 @@ entity Person : cuid {
### Localized Messages
-Whenever you specify an error message with the annotations above, i.e., in the `then` part of an `@assert: ()` or in `@mandatory.message`, `@assert.format.message`, or `@assert.range.message`, you can either specify a plain text, or a [I18n text bundle key](../i18n#externalizing-texts-bundles).
+Whenever you specify an error message with the annotations above, i.e., in the `then` part of an `@assert: ()` or in `@mandatory.message`, `@assert.format.message`, or `@assert.range.message`, you can either specify a plain text, or a [I18n text bundle key](../uis/i18n#externalizing-texts-bundles).
Actually, we saw this already in the [sample in the introduction](#introduction):
@@ -494,7 +493,7 @@ annotate TravelService.Travels with {
If you use a message key, the message is automatically looked up in the message bundle of the service with the current user's preferred locale.
-[Learn more about localized messages.](../i18n){.learn-more}
+[Learn more about localized messages.](../uis/i18n){.learn-more}
@@ -534,7 +533,7 @@ Use the `@UI.Hidden` annotation to hide fields in Fiori UIs. You can also use it
@UI.Hidden: (status <> 'visible')
```
-[Learn more about that in the *OData guide*](/advanced/odata#expression-annotations) {.learn-more}
+[Learn more about that in the *OData guide*](../protocols/odata#expression-annotations) {.learn-more}
diff --git a/guides/using-services.md b/guides/services/consuming-services.md
similarity index 91%
rename from guides/using-services.md
rename to guides/services/consuming-services.md
index d4cd4de100..47bcc2a3a3 100644
--- a/guides/using-services.md
+++ b/guides/services/consuming-services.md
@@ -1,43 +1,31 @@
---
-index: 22
synopsis: >
Learn how to use uniform APIs to consume local or remote services.
-status: released
impl-variants: true
-# uacp: Used as link target from Help Portal at
---
-
-
-
# Consuming Services
-
+---
-[[toc]]
+> [!caution] Deprecation Notice
+> **This guide is outdated** and has been replaced by the [_CAP-level Service Integration_](../integration/calesi.md) guide for up-to-date information about integrating remote services in CAP. The content of this guide is kept for archival purposes only for a limited time.
+{.abstract}
-## Introduction
+---
+
If you want to use data from other services or you want to split your application into multiple microservices, you need a connection between those services. We call them **remote services**. As everything in CAP is a service, remote services are modeled the same way as internal services — using CDS.
-CAP supports service consumption with dedicated APIs to [import](#import-api) service definitions, [query](#execute-queries) remote services, [mash up](#building-mashups) services, and [work locally](#local-mocking) as much as possible.
+[[toc]]
+## Introduction
-
### Feature Overview
@@ -63,17 +51,14 @@ Before you start your implementation, you should define your scenario. Answering
+ How do they interact?
+ What needs to be displayed on the UI?
-You have all your answers and know your scenario, go on reading about [external service APIs](#external-service-api), getting an API definition from [the SAP Business Accelerator Hub](#from-api-hub) or [from a CAP project](#from-cap-service), and [importing an API definition](#import-api) to your project.
+You have all your answers and know your scenario, go on reading about [external service APIs](#import-external-apis), getting an API definition from [the SAP Business Accelerator Hub](#from-sap-business-accelerator-hub) or [from a CAP project](#for-a-remote-cap-service), and [importing an API definition](#import-api-definition) to your project.
#### Sample Scenario from End-to-End Tutorial
-
-
-{style="width: 500px"}
+{style="width: 500px"}
-::: info _User Story_
-A company wants to ensure that goods are only sourced from suppliers with acceptable risks. There shall be a software system, that allows a clerk to maintain risks for suppliers and their mitigations. The system shall block the supplier used if risks can't be mitigated.
-:::
+> [!info] _User Story_
+> A company wants to ensure that goods are only sourced from suppliers with acceptable risks. There shall be a software system, that allows a clerk to maintain risks for suppliers and their mitigations. The system shall block the supplier used if risks can't be mitigated.
The application is an extension for SAP S/4HANA. It deals with _risks_ and _mitigations_ that are local entities in the application and _suppliers_ that are stored in SAP S/4HANA Cloud. The application helps to reduce risks associated with suppliers by automatically blocking suppliers with a high risk using a [remote API Call](#execute-queries).
@@ -89,25 +74,23 @@ It should be also possible to search for suppliers and show the associated risks
If you want to learn about this topic based on the [Incident Management](https://github.com/cap-js/incidents-app) sample, you can follow the [BTP Developer's Guide repository](https://github.com/SAP-samples/btp-developer-guide-cap/tree/main/documentation/remote-service).
:::
-## Install Dependencies { .node }
-
-```sh
-npm add @sap-cloud-sdk/http-client@4.x @sap-cloud-sdk/connectivity@4.x @sap-cloud-sdk/resilience@4.x
-```
-## Get and Import an External Service API { #external-service-api }
+
+## Import External APIs
+###### external-service-api
+###### import-api
To communicate to remote services, CAP needs to know their definitions. Having the definitions in your project allows you to mock them during design time.
These definitions are usually made available by the service provider. As they aren't defined within your application but imported from outside, they're called *external* service APIs in CAP. Service APIs can be provided in different formats. Currently, *EDMX* files for OData V2 and V4 are supported.
-### From SAP Business Accelerator Hub { #from-api-hub}
+### From SAP Business Accelerator Hub
The [SAP Business Accelerator Hub](https://api.sap.com/) provides many relevant APIs from SAP. You can download API specifications in different formats. If available, use the EDMX format. The EDMX format describes OData interfaces.
To download the [Business Partner API (A2X) from SAP S/4HANA Cloud](https://api.sap.com/api/API_BUSINESS_PARTNER/overview), go to section **API Resources**, select **API Specification**, and download the **EDMX** file.
-### For a Remote CAP Service { #from-cap-service}
+### For a Remote CAP Service
We recommend using EDMX as exchange format. Export a service API to EDMX:
@@ -142,7 +125,7 @@ Simply copying CDS files from a different application comes with the following i
- CAP creates unneeded database tables and views for all entities in the file.
:::
-### Import API Definition { #import-api}
+### Import API Definition
Import the API to your project using `cds import`.
@@ -194,7 +177,7 @@ Now run `cds import `
- `--as` only supports these formats: "csn","cds", and "json"
- `--force` is applicable only in combination with `--as` option. By default the `--force` flag is set to false.
> If set to true, existing CSN/CDS files from previous imports are overwritten.
-:::
+ :::
When importing the specification files, the `kind` is set according to the following mapping:
@@ -205,7 +188,7 @@ When importing the specification files, the `kind` is set according to the follo
| OpenAPI | `rest` |
| AsyncAPI | `odata` |
-[Learn more about type mappings from OData to CDS and vice versa.](../tools/apis/cds-import#odata-type-mappings){.learn-more}
+[Learn more about type mappings from OData to CDS and vice versa.](../../tools/apis/cds-import#odata-type-mappings){.learn-more}
::: tip
Always use OData V4 (`odata`) when calling another CAP service.
@@ -239,7 +222,7 @@ To work with remote services, add the following dependency to your Maven project
```
-[Learn about all `cds.remote.services` configuration possibilities.](../java/developing-applications/properties#cds-remote-services){.learn-more}
+[Learn about all `cds.remote.services` configuration possibilities.](../../java/developing-applications/properties){.learn-more}
@@ -253,7 +236,7 @@ As for any other CAP service, you can add mocking data.
The CSV file needs to be added to the _srv/external/data_ folder. {.node}
-The CSV file needs to be added to the _db/data_ folder. {.java}
+The CSV file needs to be added to the _db/data_ folder.
::: code-group
```csv [API_BUSINESS_PARTNER-A_BusinessPartner.csv]
@@ -345,7 +328,7 @@ entity API_BUSINESS_PARTNER.A_BusinessPartnerAddress {
```
:::
-To mock an association, you have to modify [the imported file](#import-api). Before doing any modifications, create a local copy and add it to your source code management system.
+To mock an association, you have to modify the imported file. Before doing any modifications, create a local copy and add it to your source code management system.
```sh
@@ -388,7 +371,7 @@ mv API_BUSINESS_PARTNER-new.cds API_BUSINESS_PARTNER-orig.cds
To prevent accidental loss of modifications, the `cds import --as cds` command refuses to overwrite modified files based on a "checksum" that is included in the file.
-### Mock Remote Service as OData Service (Node.js) {.node}
+### Mock Remote Service as OData Service (Node.js)
As shown previously you can run one process including a mocked external service. However, this mock doesn't behave like a real external service. The communication happens in-process and doesn't use HTTP or OData. For a more realistic testing, let the mocked service run in a separate process.
@@ -408,7 +391,7 @@ CAP tracks locally running services. The mocked service `API_BUSINESS_PARTNER` i
Node.js only supports *OData V4* protocol and so does the mocked service. There might still be some differences to the real remote service if it uses a different protocol, but it's much closer to it than using only one instance. In the console output, you can also easily see how the communication between the two processes happens.
-### Mock Remote Service as OData Service (Java) {.java}
+### Mock Remote Service as OData Service (Java)
You configure CAP to do OData and HTTP requests for a mocked service instead of doing it in-process. Configure a new Spring Boot profile (for example `mocked`):
::: code-group
@@ -467,11 +450,11 @@ For example:
[Try out the example application.](https://github.com/SAP-samples/cloud-cap-risk-management/tree/ext-service-s4hc-suppliers-ui-java){.learn-more}
-## Execute Queries {#execute-queries}
+## Execute Queries
You can send requests to remote services using CAP's powerful querying API.
-### Execute Queries with Node.js{.node}
+### Execute Queries with Node.js
Connect to the service before sending a request, as usual in CAP:
@@ -479,7 +462,7 @@ Connect to the service before sending a request, as usual in CAP:
const bupa = await cds.connect.to('API_BUSINESS_PARTNER');
```
-Then execute your queries using the [Querying API](../node.js/core-services#srv-run-query):
+Then execute your queries using the [Querying API](../../node.js/core-services#srv-run-query):
```js
const { A_BusinessPartner } = bupa.entities;
@@ -504,7 +487,7 @@ const result = await bupa.run(SELECT.from(A_BusinessPartner, bp => {
[Learn more about supported querying API features.](#querying-api-features){.learn-more}
-### Execute Queries with Java {.java}
+### Execute Queries with Java
You can use dependency injection to get access to the remote service:
@@ -514,7 +497,7 @@ You can use dependency injection to get access to the remote service:
CqnService bupa;
```
-Then execute your queries using the [Querying API](../java/working-with-cql/query-execution):
+Then execute your queries using the [Querying API](../../java/working-with-cql/query-execution):
```java
CqnSelect select = Select.from(ABusinessPartner_.class).limit(100);
@@ -527,7 +510,7 @@ List