...

Text file src/github.com/Microsoft/hcsshim/internal/tools/policyenginesimulator/README.md

Documentation: github.com/Microsoft/hcsshim/internal/tools/policyenginesimulator

     1# Policy Engine Simulator
     2
     3This tool provides a means to test out security policies. Usage:
     4
     5```
     6  -commands string
     7        path to commands JSON file
     8  -data string
     9        path to initial data state JSON file (optional)
    10  -log string
    11        path to output log file
    12  -logLevel string
    13        None|Info|Results|Metadata (default "Info")
    14  -policy string
    15        path to policy Rego file
    16```
    17
    18## Getting started
    19
    20From the tool directory run:
    21
    22   go run . -policy [samples/simple_framework/policy.rego](samples/simple_framework/policy.rego) -commands [samples/simple_framework/commands.json](samples/simple_framework/commands.json)
    23
    24This will load the authored policy and then simulate the enforcement behavior
    25for the provided commands.
    26
    27This policy uses the framework, however, the simulator also handles completely
    28custom policies:
    29
    30   go run . -policy [samples/simple_custom/policy.rego](samples/simple_framework/policy.rego) -commands [samples/simple_custom/commands.json](samples/simple_custom/commands.json)
    31
    32## Commands
    33
    34Consists of a sequential list of commands that will be issued for enforcement to
    35the policy. Some sample commands can be seen here:
    36
    37- [Framework Example Commands](samples/simple_custom/commands.json)
    38- [Custom Example Commands](samples/simple_framework/commands.json)
    39
    40These commands take the form of JSON objects, *e.g.*:
    41
    42``` json
    43[
    44    {
    45        "name": "load_fragment",
    46        "input": {
    47            "issuer": "did:web:contoso.github.io",
    48            "feed": "contoso.azurecr.io/custom",
    49            "namespace": "custom",
    50            "local_path": "custom.rego"
    51        }
    52    },
    53    {
    54        "name": "mount_device",
    55        "input": {
    56            "target": "/mnt/layer0",
    57            "deviceHash": "16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"
    58        }
    59    },
    60    {
    61        "name": "mount_overlay",
    62        "input": {
    63            "target": "/mnt/overlay0",
    64            "containerID": "container0",
    65            "layerPaths": [
    66                "/mnt/layer0"
    67            ]
    68        }
    69    },
    70    {
    71        "name": "create_container",
    72        "input": {
    73            "containerID": "container0",
    74            "argList": [
    75                "/pause"
    76            ],
    77            "envList": [
    78                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    79                "TERM=xterm"
    80            ],
    81            "mounts": [],
    82            "workingDir": "/",
    83            "sandboxDir": "/sandbox",
    84            "hugePagesDir": "/hugepages"
    85        }
    86    }
    87]
    88```
    89
    90Each command has a name (corresponding to the API enforcement point) and then
    91an input which will be passed directly to the policy. The API being tested
    92is defined in [`api.rego`](../../../pkg/securitypolicy/api.rego).
    93
    94## Data
    95
    96If the authored policy requires certain values in the Rego data structure to
    97function, or if the author wants to test enforcement behavior given a known
    98starting state, they can provide an optional initial data file as an argument
    99to the tool. This should take the form of a single JSON object, *e.g.*:
   100
   101``` json
   102{
   103    "defaultMounts": [/*some mount constraint objects*/],
   104    "privilegedMounts": [/*some mount constraint objects*/],
   105    "sandboxPrefix": "sandbox://",
   106    "hugePagesPrefix": "hugepages://"
   107}
   108```
   109
   110## Log
   111
   112To aid in debugging, the user can specify a log file. This will enable logging
   113at the `Info` level, which consists of the output of any Rego `print()` calls
   114from the policy.
   115
   116## Log Level
   117
   118There are several log levels that the user can use to gain greater insight into
   119policy enforcement:
   120
   121|    Name    |                       Description                         |
   122| ---------- | --------------------------------------------------------- |
   123| `None`     | Used when no log file is provided via the `-log` argument |
   124| `Info`     | Outputs the results of Rego `print()` statements.         |
   125| `Results`  | Outputs the results returned by each policy query         |
   126| `Metadata` | Outputs the entire metadata state after each query        |
   127
   128## Policy
   129
   130This can be any Rego with a package name of `policy`, though policies which do
   131not define the required enforcement point rules will result in enforcement
   132failures. We include some straightforward samples below, but see
   133[simple_custom](simple_custom) and [simple_framework](simple_framework)
   134for more detail.
   135
   136### Framework-based policy
   137
   138``` rego
   139package policy
   140
   141api_version := "0.7.0"
   142
   143import future.keywords.every
   144import future.keywords.in
   145
   146containers := [
   147    {
   148        "command": ["/pause"],
   149        "env_rules": [
   150            {
   151                "pattern": "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
   152                "strategy": "string",
   153                "required": false
   154            },
   155            {
   156                "pattern": "TERM=xterm",
   157                "strategy": "string",
   158                "required": false
   159            }
   160        ],
   161        "layers": ["16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"],
   162        "mounts": [],
   163        "exec_processes": [],
   164        "signals": [],
   165        "allow_elevated": false,
   166        "working_dir": "/"
   167    }
   168]
   169
   170mount_device := data.framework.mount_device
   171unmount_device := data.framework.unmount_device
   172mount_overlay := data.framework.mount_overlay
   173unmount_overlay := data.framework.unmount_overlay
   174create_container := data.framework.create_container
   175exec_in_container := data.framework.exec_in_container
   176exec_external := data.framework.exec_external
   177shutdown_container := data.framework.shutdown_container
   178signal_container_process := data.framework.signal_container_process
   179plan9_mount := data.framework.plan9_mount
   180plan9_unmount := data.framework.plan9_unmount
   181load_fragment := data.framework.load_fragment
   182reason := {"errors": data.framework.errors}
   183```
   184
   185### Custom Policy
   186
   187``` rego
   188package policy
   189
   190api_version := "0.7.0"
   191
   192overlays := {
   193    "pause": {
   194        "deviceHashes": ["16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"],
   195        "mounts": []
   196    }
   197}
   198
   199custom_containers := [
   200    {
   201        "id": "pause",
   202        "command": ["/pause"],
   203        "overlayID": "pause",
   204        "depends": []
   205    }
   206]
   207
   208mount_device := data.custom.mount_device
   209mount_overlay := data.custom.mount_overlay
   210create_container := data.custom.create_container
   211unmount_device := {"allowed": true}
   212unmount_overlay := {"allowed": true}
   213exec_in_container := {"allowed": true}
   214exec_external := {"allowed": true}
   215shutdown_container := {"allowed": true}
   216signal_container_process := {"allowed": true}
   217plan9_mount := {"allowed": true}
   218plan9_unmount := {"allowed": true}
   219
   220default load_fragment := {"allowed": false}
   221load_fragment := {"allowed": true, "add_module": true} {
   222    input.issuer == "did:web:contoso.github.io"
   223    input.feed == "contoso.azurecr.io/custom"
   224}
   225```

View as plain text