diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index a5fa620..a090e45 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -33,7 +33,9 @@ export default defineConfig({ { text: 'Authorization Bundle', link: '/Authorization/AuthorizationBundle' }, { text: 'Authorization Checks', link: '/Authorization/AuthorizationChecks' }, { text: 'Testing', link: '/Authorization/Testing' }, - { text: 'Technical Communication', link: '/Authorization/TechnicalCommunication' }, + { text: 'System-to-System Communication', link: '/Authorization/SystemToSystem', collapsed: true, items: [ + { text: 'App-to-App', link: '/Authorization/App2App' }, + ]}, { text: 'Deploying DCL', link: '/Authorization/DeployDCL' }, { text: 'Changing DCL', link: '/Authorization/ChangingDCL' }, { text: 'Value Help', link: '/Authorization/ValueHelp' }, diff --git a/docs/Authorization/TechnicalCommunication.md b/docs/Authorization/App2App.md similarity index 72% rename from docs/Authorization/TechnicalCommunication.md rename to docs/Authorization/App2App.md index 54d4e6d..0109ef5 100644 --- a/docs/Authorization/TechnicalCommunication.md +++ b/docs/Authorization/App2App.md @@ -1,12 +1,16 @@ -# Technical Communication +# App-to-App -The Authorization Management Service (**AMS**) supports authorization of technical communication for both *technical users* (systems) and *principal propagation*. In principle propagation, user requests are forwarded, as documented below. +The recommended strategy for authorizing technical communication requests in provider applications is to use SAP Cloud Identity Services [App-to-App Integration](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/consume-apis-from-other-applications). Here, the request of the caller is authorized by authorization policies in the provider application based on the consumed API permission groups. -## App-to-App +App-to-App is one of the patterns described under [System-to-System Communication](/Authorization/SystemToSystem), which also explains the difference between authorizing a *technical user* and *principal propagation*. -The recommended strategy for authorizing technical communication requests in provider applications is to use SAP Cloud Identity Services [App-to-App Integration](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/consume-apis-from-other-applications). Here, the request of the caller is authorized by authorization policies in the provider application based on the consumed API permission groups. +## When to Use App-to-App -The consumed API permission groups can be found in the the `ias_apis` claim of the tokens from SAP Cloud Identity Services: +App-to-App integration exposes APIs using JWT tokens issued by SAP Cloud Identity Services. It can be used whenever the +calling and the called application are registered in the same SAP Cloud Identity Services tenant and accept JWT tokens +for authentication. + +The consumed API permission groups can be found in the `ias_apis` claim of the tokens from SAP Cloud Identity Services: ```json { @@ -42,7 +46,21 @@ The decision **which application** may consume which API permission group is mad The CAP authentication handlers use the list of `ias_apis` to automatically grant **cds roles** with the same name in case of **technical user** tokens. The strategy described below is only relevant outside CAP or if you want to use the API permission groups in the context of principal propagation requests. ::: -### API Policies +## Choosing API Permission Groups + +The API permission groups that an application provides are free-text names. SAP Cloud Identity Services doesn't make any assumptions about their content, so it's up to the application to choose a meaningful granularity. + +We recommend to keep API permission groups **coarse-grained**, at a level comparable to a *plan* of a service. The callee should define names that describe what a caller is allowed to do as a whole, together with a corresponding description, for example: + +- `full-access` +- `read-only-access` +- `manage-sales-orders` + +Fine-grained API permission groups, for example one per endpoint, push authorization decisions into the tenant administrator's configuration and make the integration harder to reason about for both sides. + +Keeping them coarse-grained works because API permission groups and authorization policies form two layers. The API permission group decides **whether** a caller may use a set of endpoints at all, and is configured by the tenant administrator. The internal policy behind it decides **which privileges** that grants, down to instance-based restrictions, and is defined by the application. + +## API Policies For each API permission group that is provided by the application, it defines an *internal* policy. This is a policy that is not visible to administrators. @@ -64,7 +82,7 @@ It's best practice to map policies separately for the *technical user* and *forw If you want to define different privileges for technical und forwarded user tokens consuming the same API permission group, you can map the API permission group to different internal policies depending on the flow. ::: -### Authorization via API Permission Groups +## Authorization via API Permission Groups For technical user requests, the resulting policy is used directly in subsequent authorization checks to determine the caller's privileges. @@ -88,9 +106,17 @@ graph TD ::: info Principal propagation requests that consume the special `principal-propagation` API permission group are authorized based on the user's policies without imposing an upper limit. This API permission group corresponds to `All APIs` consumption in the SCI administration console and can be [optionally provided](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/consume-apis-from-other-applications) by the application if it's not necessary to distinguish between internal and external user requests. + +This is also the right choice if you don't want to restrict the user's privileges at all but still need the user principal in the callee, for example to write audit log entries that attribute an action to the user on whose behalf it was performed. ::: -### Mapping implementation +## Administration of API Permission Groups + +Once the callee application is visible in the SCI administration console, either as an application or as an application reference, administrators can assign its authorization policies to users just like for an application that end users access directly. The policies are managed on the *Authorization Policies* tab of the application. + +To review which API permission groups a calling application consumes, administrators navigate from the **calling** application to the callee and its policies via `Trust -> Application APIs -> Dependencies -> APIs`. + +## Mapping Implementation The *API Name -> Policy Name* mapping is typically implemented as a simple function in the application code. ::: tip @@ -128,19 +154,22 @@ function mapPrincipalPropagationApi(api) { ``` ```java [Java] -final Map> TECHNICAL_USER_API_TO_POLICY = Map.of( - "ReadCatalog", Set.of("internal.ReadCatalog")); +import com.sap.cloud.security.ams.api.ApiMapper; +import com.sap.cloud.security.ams.api.PolicyName; + +final Map> TECHNICAL_USER_API_TO_POLICY = Map.of( + "ReadCatalog", Set.of(PolicyName.of("internal.ReadCatalog"))); final ApiMapper technicalUserApiMapper = ApiMapper.ofMap(TECHNICAL_USER_API_TO_POLICY); -final Map> PRINCIPAL_PROPAGATION_API_TO_POLICY = Map.of( - "AMS_ValueHelp", Set.of("internal.AMS_ValueHelp"), - "ReadCatalog", Set.of("internal.ReadCatalog")); +final Map> PRINCIPAL_PROPAGATION_API_TO_POLICY = Map.of( + "AMS_ValueHelp", Set.of(PolicyName.of("internal.AMS_ValueHelp")), + "ReadCatalog", Set.of(PolicyName.of("internal.ReadCatalog"))); final ApiMapper principalPropagationApiMapper = ApiMapper.ofMap(PRINCIPAL_PROPAGATION_API_TO_POLICY); ``` ::: -### Mapping registration +## Mapping Registration Finally, a bit of configuration is required to register the mapping functions, so that the correct policies apply when external requests are made against the API permission groups. The mapping can be registered in `IdentityServiceAuthProvider` (Node.js) / `SciAuthorizationsProvider` (Java) and its subclasses, such as `HybridAuthProvider` (Node.js) / `HybridAuthorizationsProvider` (Java). @@ -178,7 +207,7 @@ const authProvider = new IdentityServiceAuthProvider(ams) ``` ```java [Spring Boot/Spring Boot (CAP)] -import static com.sap.cloud.security.ams.api.App2AppFlow.RESTRICTED_PRINCIPAL_PROPAGATION; +import static com.sap.cloud.security.ams.api.App2AppFlow.FILTERED_PRINCIPAL_PROPAGATION; import static com.sap.cloud.security.ams.api.App2AppFlow.TECHNICAL_USER; @Configuration @@ -194,7 +223,7 @@ public class AmsAuthProviderConfiguration { authProvider .withApiMapper(TECHNICAL_USER_API_MAPPER, TECHNICAL_USER) - .withApiMapper(PRINCIPAL_PROPAGATION_API_MAPPER, RESTRICTED_PRINCIPAL_PROPAGATION); + .withApiMapper(PRINCIPAL_PROPAGATION_API_MAPPER, FILTERED_PRINCIPAL_PROPAGATION); } } ``` @@ -202,12 +231,12 @@ public class AmsAuthProviderConfiguration { ```java [Java] import com.sap.cloud.security.ams.core.SciAuthorizationsProvider; -import static com.sap.cloud.security.ams.api.App2AppFlow.RESTRICTED_PRINCIPAL_PROPAGATION; +import static com.sap.cloud.security.ams.api.App2AppFlow.FILTERED_PRINCIPAL_PROPAGATION; import static com.sap.cloud.security.ams.api.App2AppFlow.TECHNICAL_USER; SciAuthorizationsProvider authProvider = SciAuthorizationsProvider.create(ams) .withApiMapper(TECHNICAL_USER_API_MAPPER, TECHNICAL_USER) - .withApiMapper(PRINCIPAL_PROPAGATION_API_MAPPER, RESTRICTED_PRINCIPAL_PROPAGATION); + .withApiMapper(PRINCIPAL_PROPAGATION_API_MAPPER, FILTERED_PRINCIPAL_PROPAGATION); ``` ::: \ No newline at end of file diff --git a/docs/Authorization/AuthorizationChecks.md b/docs/Authorization/AuthorizationChecks.md index da9142d..66f83fb 100644 --- a/docs/Authorization/AuthorizationChecks.md +++ b/docs/Authorization/AuthorizationChecks.md @@ -126,7 +126,7 @@ By default*, the authorizations of these two layers are combined as follows: | null | null | Fully denied, empty authorizations (unexpected scenario) | \* *In the future, it might be possible to explicitly decide -for [principal propagation tokens](/Authorization/TechnicalCommunication) how the authorizations +for [principal propagation tokens](/Authorization/App2App) how the authorizations should be enforced with a configuration property of the App-to-App dependency. In that case, this default logic would be overridden based on this information in the token.* @@ -145,7 +145,7 @@ Consider an authorization check with [conditional policies](#conditional-policie `SciAuthorizationsProvider` supports customization through configuration methods and method overriding. -The current configuration methods are for [Technical Communication](/Authorization/TechnicalCommunication). They are +The current configuration methods are for [Technical Communication](/Authorization/App2App). They are described on that page in detail. ##### Overriding Methods diff --git a/docs/Authorization/GettingStarted.md b/docs/Authorization/GettingStarted.md index 278e0e9..7eb44f4 100644 --- a/docs/Authorization/GettingStarted.md +++ b/docs/Authorization/GettingStarted.md @@ -21,8 +21,8 @@ resources: config: authorization: # [!code focus:4] enabled: true - value-help-url: "", - value-help-api-name: "", + value-help-url: "" + value-help-api-name: "" ``` ### Configuration details diff --git a/docs/Authorization/SystemToSystem.md b/docs/Authorization/SystemToSystem.md new file mode 100644 index 0000000..bd494b4 --- /dev/null +++ b/docs/Authorization/SystemToSystem.md @@ -0,0 +1,46 @@ +# System-to-System Communication + +System-to-System communication describes a programmatic data exchange between two applications or services. The +Authorization Management Service (**AMS**) supports authorization of system-to-system communication for both *technical +users* (systems acting on their own behalf) and *principal propagation* (systems acting on behalf of a user whose +request is forwarded). + +The main difference between the communication patterns is how trust between the parties is established and how they authenticate. Understanding the authentication side is a prerequisite for the authorization side described here. See [Consume APIs from Other Applications](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/consume-apis-from-other-applications) for the authentication details. + +## Authorization Approaches + +When you develop an application that needs to authorize requests coming from another system, the first question is **what** should be authorized. The answer depends entirely on the use case, and the two approaches are: + +- **Technical Communication** (also referred to as *technical access*): the calling application itself is the principal. The caller is the entity that is authenticated and authorized, and no user is involved in the decision. Different authorization levels are typically mapped to different usage scenarios of the callee. +- **Principal Propagation**: the calling application acts on behalf of a user. The application is authenticated, but the user is the principal, so the effective authorizations depend on both the caller's and the user's access levels. This is the right approach when the data in the receiving application is owned by the user, or when actions should be performed on the user's behalf. + +An application can support both approaches at the same time, and it decides per request which one applies based on the incoming token. + +## Internal Policies + +Regardless of which approach you choose, AMS lets you define special `INTERNAL` policies for authorizing the calling application. Internal policies have the following characteristics: + +- They're **not assignable to users** and don't appear in the administration console, because they aren't relevant for tenant administrators. +- The same DCL schema applies as for all other policies. We recommend to define them in a dedicated package, typically named `internal`. +- The mapping from an internal policy to the caller's usage scenario is considered static and is therefore implemented in the application itself, rather than configured by an administrator. +- Every application is in charge of enforcing its own internal policies, as described on the pattern pages below. + +For the `INTERNAL` keyword itself, see the [Data Control Language (DCL) reference](https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/data-control-language-dcl). + +## Effective Authorizations + +In technical communication, the policies derived from the caller are the only input to the authorization decision, so they determine the caller's privileges directly. + +In principal propagation, the policies assigned to the user form the basis of the decision, and the policies derived from the caller act as an **upper limit** on what may be granted during that request. The effective privileges are the intersection of both. This lets an application restrict what an external caller can do on behalf of a user, while still respecting the user's own assignments. + +The `SciAuthorizationsProvider` implements this combination out of the box. See [Authorization Checks](/Authorization/AuthorizationChecks#sciauthorizationsprovider) for the exact rules, including what happens when only one of the two layers is present. + +## Communication Patterns + +### App-to-App + +Communication between two applications that are registered in the same SAP Cloud Identity Services tenant, based on JWT tokens. The caller's authorizations are derived from the **API permission groups** it consumes, which are carried in the `ias_apis` claim of the token. + +This pattern doesn't require the participating applications to follow the SAP BTP tenancy model, so it also works between BTP and non-BTP applications. + +See [App-to-App](/Authorization/App2App) for the full documentation. diff --git a/docs/Authorization/ValueHelp.md b/docs/Authorization/ValueHelp.md index f9a8135..75d0665 100644 --- a/docs/Authorization/ValueHelp.md +++ b/docs/Authorization/ValueHelp.md @@ -119,12 +119,12 @@ If the attribute for which value help is requested [depends on other attributes] ## Authorizing Value Help Requests -The value help endpoints in your application MUST be protected because they return business data. To allow the application to authorize value help requests, the AMS server calls the application with an [App-To-App](/Authorization/TechnicalCommunication#app-to-app) principal propagation token based on the administrator who requests value help in the administration console. +The value help endpoints in your application MUST be protected because they return business data. To allow the application to authorize value help requests, the AMS server calls the application with an [App-To-App](/Authorization/App2App) principal propagation token based on the administrator who requests value help in the administration console. ### API Permission Group The API permission group consumed by the AMS server can be freely chosen in the service configuration of the AMS instance. -It is best practice to setup an internal policy for this API permission group to limit privileges to those that are necessary for the value help endpoints as described in the App-To-App documentation for [principal propagation](/Authorization/TechnicalCommunication.html#authorization-via-api-permission-groups). +It is best practice to setup an internal policy for this API permission group to limit privileges to those that are necessary for the value help endpoints as described in the App-To-App documentation for [principal propagation](/Authorization/App2App#authorization-via-api-permission-groups). ::: warning Important Note that such an API policy defines just an upper limit for the privileges that can be used with this token. The administrator using the administration console must additionally have the necessary privileges based on assigned policies to access the value help endpoints in your application. diff --git a/docs/Libraries/java/changelog.md b/docs/Libraries/java/changelog.md index 261524d..f543b21 100644 --- a/docs/Libraries/java/changelog.md +++ b/docs/Libraries/java/changelog.md @@ -85,7 +85,7 @@ The CAP Spring Boot starter already wraps the standard `Authorizations` in a `Cd - Provided [CAP Spring beans](/Libraries/java/cap-ams.html#auto-configuration) for custom authorization checks - Improved [Spring Security beans](/Libraries/java/spring-boot-ams#auto-configuration) for custom authorization checks - New [event logging API](/Libraries/java/ams-core#events-logging) for logging authorization events -- Configuration options for [technical communication](/Authorization/TechnicalCommunication) scenarios via SAP Identity Service +- Configuration options for [technical communication](/Authorization/App2App) scenarios via SAP Identity Service - Customization of authorization strategy via `AuthorizationsProvider` interface, e.g. [granting additional policies based on token attributes](/Authorization/AuthorizationChecks#overriding-methods) - JUnit 5+ extension for unit testing policy semantics without a full-blown integration test using [`ams-test`](/Libraries/java/ams-test). - Detailed [**DEBUG**](/Troubleshooting) logging about construction of `Authorizations` from token diff --git a/docs/Libraries/java/v3/jakarta-ams.md b/docs/Libraries/java/v3/jakarta-ams.md index 7597e7f..f8d240b 100644 --- a/docs/Libraries/java/v3/jakarta-ams.md +++ b/docs/Libraries/java/v3/jakarta-ams.md @@ -309,7 +309,7 @@ To enable that audit logging of the application must configure and register this To correlate this audit log message with logs written for the same request context `PolicyEvaluationV2AuditLogger` also fills `sap-passport` if provided with the mapped diagnostic context (MDC) context. These applications must - leverage a slf4j implementation that supports MDC like [logback](http://logback.qos.ch/manual/mdc.html) -- provide dependencies to [Audit Log Service Java Client](https://github.wdf.sap.corp/xs-audit-log/audit-java-client) +- provide dependencies to the Audit Log Service Java Client - fetch `sap_passport, for example, from the http header - enrich the MDC as following:
diff --git a/docs/Libraries/java/v3/migration-v3-to-v4.md b/docs/Libraries/java/v3/migration-v3-to-v4.md index d17f7c8..eb01000 100644 --- a/docs/Libraries/java/v3/migration-v3-to-v4.md +++ b/docs/Libraries/java/v3/migration-v3-to-v4.md @@ -57,7 +57,7 @@ If you use a Spring Boot starter, it performs a synchronous startup check by def - Remove any implementations of the `AttributesProcessor` interface and the meta data configuration for the service loader. -Typical use cases for `AttributesProcessor` such as [technical communication](/Authorization/TechnicalCommunication), [XSUAA scope mapping](/Authorization/AuthorizationChecks#hybridauthorizationsprovider) or [custom user attribute injection](/Authorization/AuthorizationChecks#overriding-methods) can now be implemented much simpler via `AuthorizationsProvider` configuration. +Typical use cases for `AttributesProcessor` such as [technical communication](/Authorization/App2App), [XSUAA scope mapping](/Authorization/AuthorizationChecks#hybridauthorizationsprovider) or [custom user attribute injection](/Authorization/AuthorizationChecks#overriding-methods) can now be implemented much simpler via `AuthorizationsProvider` configuration. ### PolicyDecisionPoint checks diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index f13fa6f..abf23f9 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -156,7 +156,7 @@ If the policies listed here are different from the ones used for the authorizati Make sure there are no typos in API names in the mapping functions. ::: warning -If you want to enable the special [`principal-propagation`](/Authorization/TechnicalCommunication#authorization-via-api-permission-groups) API, make sure to name it correctly. The name is case-sensitive and must be exactly `principal-propagation` and *not* `principle-propagation`. +If you want to enable the special [`principal-propagation`](/Authorization/App2App#authorization-via-api-permission-groups) API, make sure to name it correctly. The name is case-sensitive and must be exactly `principal-propagation` and *not* `principle-propagation`. ::: ##### Incorrect Policy Names