0.8.6 • Published 6 days ago

@sap/ams-dev v0.8.6

Weekly downloads
-
License
ISC
Repository
github
Last release
6 days ago

@sap/ams-dev

This module provides tooling support for extending applications which authenticate users via the SAP Cloud Identity Services with authorization checks via AMS (Authorization Management Service).

The primary functionality provided by this module are CLI scripts for compiling DCL as well as starting and stopping a local OPA instance. The compilation takes DCL (Data Control Language) files and outputs files for the ADC (Authorization Decision Controller) of AMS. Currently, a modified OPA (Open Policy Agent) is used as ADC which takes REGO files generated by this module as input.

Sample base DCL

Every application has to define and provide their application specific, so-called, base DCLs. A *.dcl file has to be saved in a named package e.g. "ams" under root/$DCL_SRC_DIR/ams.

SCHEMA {
    salesOrder: {
            type: number
    },
    CountryCode: String
}

POLICY readAll {
    GRANT read ON * WHERE CountryCode IS NOT RESTRICTED;
}

POLICY readAll_Europe {
    USE readAll RESTRICT CountryCode IN ('AT', 'BE', 'BG', ...);
}

POLICY adminAllSales {
    GRANT read, write, delete, activate ON salesOrders, salesOrderItems;
}

POLICY anyActionOnSales {
    GRANT * ON salesOrders, salesOrderItems;
}

POLICY readSalesOrders_Type {
    GRANT read ON salesOrders WHERE salesOrder.type BETWEEN 100 AND 500;
}

Setup

There are different many ways this library can be used:

npm global

npm install -g @sap/ams-dev

The advantage of this approach is that the scripts are available everywhere and nothing more needs to be done. You can check if evrything works by calling:

compile-dcl

npm project

Or you can install it on project level. Inside your project run:

npm install @sap/ams-dev --save-dev

In addition the package.json can be extended by adding the desired scripts, e.g.:

"scripts": {
    "compile-dcl": "compile-dcl -s (DCL_SRC_PATH) -t (REGO_PATH)",
    "start-opa": "start-opa -r (REGO_PATH) -p 8181 -d true",
    "stop-opa": "stop-opa"
}

Now inside of your project folder the command npm run start-opa can be executed. Instead of defining the script command in the package.json one can make use npx to directly start the scripts. For example:

npx compile-dcl -d dcl-src -r dcl-target

config

Instead of setting the log-level for every cli command it's possible to define a global log-level by creating the file $HOME/.ams/config.json.

{
  "log": "debug"
}

Furthermore as long as the folder $HOME/.ams exists all temporary files like the information which processes are running background are stored there.

Documentation

DCL compilation

The folder resources/dcl-compiler contains a file dcl.jar which is executed by the compile-dcl script. To update the compiler set the correct version in package.json and start the update script.

Usage

The dcl-compilation script requires both a source and a target directory as parameter. We highly recommend to always use the flag --failOn warning although default is --failOn error in order get notified if for example features become deprecated in future dcl versions. For more information on how to execute, the dcl-compilation script run compile-dcl --help:

Usage: compile-dcl --dcl [DCL_SRC_DIR] --rego [DCL_TARGET_DIR]

Options:
      --help       Show help                                           [boolean]
      --version    Show version number                                 [boolean]
  -d, --dcl        path to DCL source directory              [string] [required]
  -r, --rego       path to REGO target directory             [string] [required]
  -l, --log-level  log level
        [string] [choices: "debug", "info", "warn", "error", "silent"] [default:
                                                                        "error"]
  -f, --failOn     fail on error, deprecation or warning
        [string] [choices: "error", "deprecation", "warning"] [default: "error"]

Examples:
  compile-dcl -d dcl-src/ -r rego/

Example globally:

compile-dcl -s dcl-src -t dcl-target

Example npx:

npx compile-dcl -s dcl-src -t dcl-target

Example in module:

npm run dcl-compile

DCL tests

A useful feature of DCL is testing of policies. From version 0.3.1 this library supports dcl tests which are automatically executed within the DCL compilation script. The output of all tests is printed to the console:

> compile-dcl -d test/integration/dcl-resources -r test/dcl-target
...
.../dcl-target/procurement/procurement_test_dcl_test.rego:
data.procurement.test_procurement_test_dcl_CanReadPurchaseRequestGermany: PASS (11.18601ms)
data.procurement.test_procurement_test_dcl_CanUpdatePurchaseRequestGermany: PASS (3.429217ms)
data.procurement.test_procurement_test_dcl_CanInsertPurchaseRequestGermany: PASS (3.25077ms)
data.procurement.test_procurement_test_dcl_CanReadPurchaseRequestUK: PASS (6.008628ms)
data.procurement.test_procurement_test_dcl_CanReadPurchaseRequestAll: PASS (1.711102ms)

.../dcl-target/sales/sales_test_dcl_test.rego:
data.sales.test_sales_test_dcl_readAllSalesOrdersTest: PASS (639.761µs)
data.sales.test_sales_test_dcl_readSalesOrdersUserCountryCode: PASS (376.242µs)
--------------------------------------------------------------------------------
PASS: 7/7

If the dcl tests fail the dcl-compile script returns with a non zero exit code. For local dcl testing we recommend the following package.json structure:

{
  "scripts": {
    "compile-dcl": "compile-dcl -d (DCL_PATH) -r (REGO_PATH)",
    "start-opa": "start-opa -r (REGO_PATH)",
    "pretest": "npm run compile-dcl && npm run start-opa",
    "test": "...",
    "posttest": "stop-opa && rm -rf (REGO_PATH)"
  }
}

This pretest ensures that your dcl code contains no errors and all the dcl tests succeed before executing the actual tests. If this library is installed globally via npm install -g . just run the following statement to test your dcl code:

compile-dcl -d (DCL_PATH) -r (REGO_PATH)

Start/Stop local opa

The folder resources/opa currently has three sap custom opa executable binaries for the operating systems mac, darwin and linux. There's also a VERSION file to keep track of the current opa version. When executing the start-opa or stop-opa script the operating system is automatically detected by process.platform.

Usage

Start Opa Server: Run start-opa --help to check the usage:

Usage: start-opa -r [REGO_PATH] -u [USER_TO_POLICY_FILE] -p [PORT]

Options:
      --help         Show help                                         [boolean]
      --version      Show version number                               [boolean]
  -r, --rego         path to rego policies folder         [string] [default: ""]
  -u, --user2policy  optional path to a json file which maps policies to users
                                                          [string] [default: ""]
  -p, --port         port of the opa server           [string] [default: "8181"]
  -d, --daemonize    starts the opa as detached background process
                                                       [boolean] [default: true]
  -n, --name         gives the opa process a name which can be used to stop it
                                                          [string] [default: ""]
  -l, --log-level    log level
        [string] [choices: "debug", "info", "warn", "error", "silent"] [default:
                                                                        "error"]
  -w, --watch        starts OPA in watch mode          [boolean] [default: true]
  -c, --config-file  start opa with a config file                       [string]

Examples:
  start-opa -r rego/ -u user2policies.json

The only required option is the path to the directory which contains the compiled dcl files (rego). Therefore the most simple option is to call:

start-opa -r ""

This will start the opa server in the background on 127.0.0.1:8181 but without any policies. Opening the browser on http://127.0.0.1:8181 should show the opa landing page. Because the opa runs now in a detached background process the script will store the it's pid. When the stop-opa script is executed this pid will be taken to shutdown the all opa servers running in the background. Alternatively the opa server can be started with daemonize set to false which will then not run in background and forward all opa logs to the console:

start-opa -r "" -d false

To stop the opa one can just press Control+C and no stop-opa script has to be executed. In order to test the opa with the own DCL policies one can pass the relative path to the rego files, e.g.:

start-opa -r ./REGO_DIR -u ./user2policy.json

The policies can be verified by calling http://127.0.0.1:8181/v1/policies. For the assignment of policies to users a data.json file is used:

{
    "principal2policies": {
        "TEST_ZONE": {
            "TEST_USR": [
                "sales.readAllSalesOrders"
            ],
            "CONDITION_USR": [
                "sales.readAllSalesOrdersCondition"
            ]
        }
    }
}

The path of this file must be specified:

start-opa -r ./REGO_DIR/ -u ./data.json -i true

It can be verified by calling http://127.0.0.1:8181/v1/data.

Stop Opa Server: Run stop-opa --help to check the usage:

Usage: stop-opa -p [PORT] -n [NAME]

Options:
      --help       Show help                                           [boolean]
      --version    Show version number                                 [boolean]
  -p, --port       stops the opa process running on this port           [string]
  -n, --name       stops the opa process with this given name           [string]
  -l, --log-level  log level
        [string] [choices: "debug", "info", "warn", "error", "silent"] [default:
                                                                        "error"]
  -d, --dry-run    list running instances to delete   [boolean] [default: false]

Examples:
  stop-opa -p 8181  stopps opa on port 8181

This script is used to stop opa servers running in background. If no parameters are passed all opa background processes will be killed:

stop-opa

Tests

Tests are implemented with mocha and chai.

npm test

Tests:

  • Unit tests that verify dcl to rego compilation
  • Integration test that validates functionality of the launch opa script

CAP integration

This module provides a devtime plugin for CAP (Cloud Application Programming Model) applications which is documented in the docs of @sap/ams.

0.8.6

6 days ago

0.8.5

7 days ago

0.8.4

2 months ago

0.8.3

3 months ago

0.8.2

3 months ago

0.8.1

4 months ago

0.8.0

5 months ago

0.7.1

8 months ago