This sample uses the CAP bookshop sample to demonstrate authentication via SAP Cloud Identity Services (SCI) and policy based authorization via its Authorization Management Service (AMS) component.
The repository contains a guided tour for the CodeTour VSCode extension. The tour guides you through all files in the project related to AMS step-by-step with explanations. Additionally, for a brief overview of the changes required to add AMS to a minimal version of the sample, you can also compare the file changes in this PR.
AMS is the component of SCI for managing authorization policies that control access rights of the application. It allows defining fine-grained access rules at runtime without re-deploying or restarting the application.
Multi-Tenant applications benefit from a ready-to-use authorization cockpit in which administrators of customers are able to extend and manage policies for a tenant-specific user base.
When deployed, the application's authorizations are managed in the SCI administration cockpit. When running locally, e.g. during development or testing, policies are edited in the IDE and can be assigned to mocked users via the CAP configuration.
Refer to the @sap/ams CAP integration guide for additional documentation.
- Authentication via SCI (
auth.kind = "ias") - Authorization via AMS
- Role Assignments
- Instance-based authorization with genre-based attribute filters
- Advanced filter conditions that exceed the capabilities of the standard instance-based cds conditions
- Principal propagation with API policies that further restrict access
- Hybrid testing via
cds bind - Auto-Configuration for deployment via cds add
After cloning the sample, first install the necessary node dependencies.
npm iTo play with the sample, we suggest to start your CAP application in watch mode with debug output enabled for the AMS runtime and development plugin:
DEBUG=ams npx cds watch # uses the @sap/cds-dk installed locally as devDependency
DEBUG=ams cds watch # requires @sap/cds-dk installed globallyYou can look at the integration tests for the CatalogService, AdminService, and AmsValueHelpService. They demonstrate the expected behavior of the application for mocked users with different combinations of authorization policies.
Advanced AMS capabilities includes in the tests:
- Filtered access: The
juniorReadercan only access books in specific genres (Fairy Tale, Fantasy, Mystery) - Principal propagation: The
principalPropagationuser demonstrates how API policies can further restrict access for user requests from external applications - combining JuniorReader policy (allows Fairy Tale, Fantasy, Mystery) of user with ReadCatalog API policy (excludes Mystery, Romance, Thriller, Dystopia) results in access to only Fantasy books
To test the effect of changes, you can make manual requests against the server by authenticating via Basic Auth as one of the mocked users (and an empty password). In the cds env configuration, you can see and change the list of policies that is assigned to the mocked users.
If the application was started in watch mode, get creative by making changes and observe the effects. Here's some ideas:
- Create a new policy in adminPolicies.dcl with a different genre filter condition
- Assign the policy to a user via the cds env configuration
- Validate it works as intended
- Make a request to
/odata/v4/catalog/Booksas that user - Verify only books matching the genre filter are returned
- Extend the unit tests to cover the new scenario
- Make a request to
- Add more attribute filters via
@ams.attributesannotations in authorization.cds- Example: Add author-based filtering by mapping
Author: author.name
- Example: Add author-based filtering by mapping
- Extend the role policies in basePolicies.dcl to additionally filter by the new attribute where it makes sense
- Create a new admin policy that filters a role based on this attribute
- Extend the vh-service.js to return possible values for the new attribute
- Observe how the
principalPropagationuser's access is restricted by both the JuniorReader policy AND the ReadCatalog API policy - Try creating different combinations of user policies and API policies to see how they interact
- The intersection of filters determines the final access rights
For CAP Hybrid Testing, you can cds bind -2 <yourIdentityServiceInstance> and start the application via
DBEUG=ams cds w --profile hybridThis allows you to test the application locally but bind it against a SAP Identity Service instance in which you can manage and assign policies for your local application.
Refer to @sap/ams Hybrid Testing for details.
@sap/cds-dk version to get correct deployment configurations for ams/ias. Remember to update your global npm installation of @sap/cds-dk if you have one as it has priority over the version specified in node_modules. Use cds version -i to check.
Before deploying the application, you may want to add additional facets via cds add <facet> --for production that you would like to use in your deployment, e.g. an approuter to login via the browser. However, such facets are out-of-scope of this sample and not necessary to test the ams-related features.
Just follow the standard Deployment guides on Capire to deploy this sample. It should work with mta, helm and even cf-manifest deployments.
For Cloud Foundry deployments, the recommended way by CAP is to use MTA deployment descriptors.
You can always generate a reference mta.yaml via cds add mta for this sample.
This is also helpful as a reference for existing applications who want to manually adjust their mta.yaml to add AMS.
In issue #29 of this repository, we posted a mta.yaml that was created this way. It contains the additional adjustments mentioned below.
@sap/cds-dk version to be sure.
To deploy with sqlite, you must copy the db.sqlite file to gen/srv/db.sqlite after cds build --production.
Please note that cds add mta creates a mta.yaml that contains a before-all command that runs cds build --production. This deletes and re-creates the gen folder after you manually copied the file. In that case, you should add another command behind it such as cp db.sqlite gen/srv/db.sqlite instead of manually copying.
To add value help to your application, include provided-apis, value-help-url and value-help-api-name in ams-cap-nodejs-bookshop-auth:
provided-apis:
- name: AMS_ValueHelp
description: Value Help Callback from AMS
type: public
authorization:
enabled: true
value-help-url: ~{srv-api/srv-cert-url}/odata/v4/ams-value-help/
value-help-api-name: AMS_ValueHelp
requires:
- name: srv-api
- name: app-apiTo understand what is going on under the hood in the deployed application, we suggest you set environment variable DEBUG to ams in your deployed application to see debug output from AMS*. Make sure to restart the application for this to take effect.
*This is just for understanding the sample and not recommended for real applications.
You must fetch an IAS token and use it to call the different services of the application.
First, find your IAS service credentials in the environment of your application or: create a certificate-based service key for your IAS service instance.
Use the service credentials and a test user's credentials to fetch a user token with an HTTP Client such a curl or Postman based on the official documentation.
As an alternative, xssec 4 provides an easy to use Node.js API to fetch IAS tokens.
Then, use the id token from the response as Bearer token when making requests to the deployed application.
You can manage AMS policies in the SAP Identity Service administration of your tenant. Find the IAS service instance called ams-cap-nodejs-bookshop in the Applications tab and create or assign policies under Authorization Policies. Give your application up to 15s to react to changes in policy assignments because roles and are cached for 15s.
Enable debug log output for AMS to analyze the problem. For deployment related problems, please refer to the relevant documentation of SAP BTP.
This sample comes without any guarantees. If you find any problems in the sample, kindly help the community by creating an issue or pull request.