...

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

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

     1# securitypolicy
     2
     3Takes a configuration to a TOML file and outputs a Base64 encoded string of the
     4generated security policy.
     5
     6`securitypolicy` exists as a tool to make it easier to generate security policies
     7for developers working functionality related to security policy in this repository.
     8It is not intended to be used by "end users" but could be used as a basis for
     9such a tool.
    10
    11A Base64 encoded version of policy is sent as an annotation to GCS for processing.
    12The `securitypolicy` tool will, by default, output Base64 encoded JSON.
    13
    14Running the tool can take a long time as each layer for each container must
    15be downloaded, turned into an ext4, and finally a dm-verity root hash calculated.
    16
    17## Example TOML configuration file
    18
    19```toml
    20allow_capability_dropping = true
    21
    22[[container]]
    23image_name = "rust:1.52.1"
    24command = ["rustc", "--help"]
    25working_dir = "/home/user"
    26allow_elevated = true
    27
    28[container.capabilities]
    29bounding = ["CAP_SYS_ADMIN"]
    30effective = ["CAP_SYS_ADMIN"]
    31inheritable = ["CAP_SYS_ADMIN"]
    32permitted = ["CAP_SYS_ADMIN"]
    33ambient = ["CAP_SYS_ADMIN"]
    34
    35[[container.env_rule]]
    36strategy = "re2"
    37rule = "PREFIX_.+=.+"
    38
    39[[container.mount]]
    40host_path = "sandbox:///host/path/one"
    41container_path = "/container/path/one"
    42readonly = false
    43
    44[[container.mount]]
    45host_path = "sandbox:///host/path/two"
    46container_path = "/container/path/two"
    47readonly = true
    48
    49[[container.exec_process]]
    50command = ["top"]
    51working_dir = "/home/user"
    52
    53[[container.exec_process.env_rule]]
    54strategy = "string"
    55rule = "FOO=bar"
    56
    57[[external_process]]
    58command = ["bash"]
    59working_dir = "/"
    60
    61[[fragment]]
    62issuer = "did:web:contoso.com"
    63feed = "contoso.azurecr.io/infra"
    64minimum_svn = "1"
    65include = ["containers"]
    66```
    67
    68### Converted to JSON
    69
    70The result of the command:
    71
    72    securitypolicytool -c sample.toml -t json -r
    73
    74The above TOML configuration gets translated into the appropriate policy that is
    75represented in JSON.
    76
    77```json
    78{
    79  "allow_all": false,
    80  "containers": {
    81    "length": 2,
    82    "elements": {
    83      "0": {
    84        "command": {
    85          "length": 2,
    86          "elements": {
    87            "0": "rustc",
    88            "1": "--help"
    89          }
    90        },
    91        "env_rules": {
    92          "length": 6,
    93          "elements": {
    94            "0": {
    95              "strategy": "string",
    96              "rule": "PATH=/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    97              "required": false
    98            },
    99            "1": {
   100              "strategy": "string",
   101              "rule": "RUSTUP_HOME=/usr/local/rustup",
   102              "required": false
   103            },
   104            "2": {
   105              "strategy": "string",
   106              "rule": "CARGO_HOME=/usr/local/cargo",
   107              "required": false
   108            },
   109            "3": {
   110              "strategy": "string",
   111              "rule": "RUST_VERSION=1.52.1",
   112              "required": false
   113            },
   114            "4": {
   115              "strategy": "string",
   116              "rule": "TERM=xterm",
   117              "required": false
   118            },
   119            "5": {
   120              "strategy": "re2",
   121              "rule": "PREFIX_.+=.+",
   122              "required": false
   123            }
   124          }
   125        },
   126        "layers": {
   127          "length": 6,
   128          "elements": {
   129            "0": "fe84c9d5bfddd07a2624d00333cf13c1a9c941f3a261f13ead44fc6a93bc0e7a",
   130            "1": "4dedae42847c704da891a28c25d32201a1ae440bce2aecccfa8e6f03b97a6a6c",
   131            "2": "41d64cdeb347bf236b4c13b7403b633ff11f1cf94dbc7cf881a44d6da88c5156",
   132            "3": "eb36921e1f82af46dfe248ef8f1b3afb6a5230a64181d960d10237a08cd73c79",
   133            "4": "e769d7487cc314d3ee748a4440805317c19262c7acd2fdbdb0d47d2e4613a15c",
   134            "5": "1b80f120dbd88e4355d6241b519c3e25290215c469516b49dece9cf07175a766"
   135          }
   136        },
   137        "working_dir": "/home/user",
   138        "mounts": {
   139          "length": 2,
   140          "elements": {
   141            "0": {
   142              "source": "sandbox:///host/path/one",
   143              "destination": "/container/path/one",
   144              "type": "bind",
   145              "options": {
   146                "length": 3,
   147                "elements": {
   148                  "0": "rbind",
   149                  "1": "rshared",
   150                  "2": "rw"
   151                }
   152              }
   153            },
   154            "1": {
   155              "source": "sandbox:///host/path/two",
   156              "destination": "/container/path/two",
   157              "type": "bind",
   158              "options": {
   159                "length": 3,
   160                "elements": {
   161                  "0": "rbind",
   162                  "1": "rshared",
   163                  "2": "ro"
   164                }
   165              }
   166            }
   167          }
   168        },
   169        "allow_elevated": true
   170      },
   171      "1": {
   172        "command": {
   173          "length": 1,
   174          "elements": {
   175            "0": "/pause"
   176          }
   177        },
   178        "env_rules": {
   179          "length": 2,
   180          "elements": {
   181            "0": {
   182              "strategy": "string",
   183              "rule": "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
   184              "required": false
   185            },
   186            "1": {
   187              "strategy": "string",
   188              "rule": "TERM=xterm",
   189              "required": false
   190            }
   191          }
   192        },
   193        "layers": {
   194          "length": 1,
   195          "elements": {
   196            "0": "16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"
   197          }
   198        },
   199        "working_dir": "/",
   200        "mounts": {
   201          "length": 0,
   202          "elements": {}
   203        },
   204        "allow_elevated": false
   205      }
   206    }
   207  }
   208}
   209```
   210
   211## Converted to Rego Policy
   212
   213The result of the command:
   214
   215    securitypolicytool -c sample.toml -t rego -r
   216
   217Is the following Rego policy:
   218
   219``` rego
   220package policy
   221
   222api_version := "0.10.0"
   223framework_version := "0.3.0"
   224
   225fragments := [
   226    {"issuer": "did:web:contoso.com", "feed": "contoso.azurecr.io/infra", "minimum_svn": 1, "includes": ["containers"]},
   227]
   228containers := [
   229    {
   230        "command": ["rustc","--help"],
   231        "env_rules": [{"pattern": `PATH=/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, "strategy": "string", "required": true},{"pattern": `RUSTUP_HOME=/usr/local/rustup`, "strategy": "string", "required": true},{"pattern": `CARGO_HOME=/usr/local/cargo`, "strategy": "string", "required": true},{"pattern": `RUST_VERSION=1.52.1`, "strategy": "string", "required": true},{"pattern": `TERM=xterm`, "strategy": "string", "required": false},{"pattern": `PREFIX_.+=.+`, "strategy": "re2", "required": false}],
   232        "layers": ["fe84c9d5bfddd07a2624d00333cf13c1a9c941f3a261f13ead44fc6a93bc0e7a","4dedae42847c704da891a28c25d32201a1ae440bce2aecccfa8e6f03b97a6a6c","41d64cdeb347bf236b4c13b7403b633ff11f1cf94dbc7cf881a44d6da88c5156","eb36921e1f82af46dfe248ef8f1b3afb6a5230a64181d960d10237a08cd73c79","e769d7487cc314d3ee748a4440805317c19262c7acd2fdbdb0d47d2e4613a15c","1b80f120dbd88e4355d6241b519c3e25290215c469516b49dece9cf07175a766"],
   233        "mounts": [{"destination": "/container/path/one", "options": ["rbind","rshared","rw"], "source": "sandbox:///host/path/one", "type": "bind"},{"destination": "/container/path/two", "options": ["rbind","rshared","ro"], "source": "sandbox:///host/path/two", "type": "bind"}],
   234        "exec_processes": [{"command": ["top"], "signals": []}],
   235        "signals": [],
   236        "user": {
   237            "user_idname": {"pattern": ``, "strategy": "any"},
   238            "group_idnames": [{"pattern": ``, "strategy": "any"}],
   239            "umask": "0022"
   240        },
   241        "capabilities": {
   242            "bounding": ["CAP_SYS_ADMIN"],
   243            "effective": ["CAP_SYS_ADMIN"],
   244            "inheritable": ["CAP_SYS_ADMIN"],
   245            "permitted": ["CAP_SYS_ADMIN"],
   246            "ambient": ["CAP_SYS_ADMIN"],
   247        },
   248        "seccomp_profile_sha256": "",
   249        "allow_elevated": true,
   250        "working_dir": "/home/user",
   251        "allow_stdio_access": false,
   252        "no_new_privileges": true,
   253    },
   254    {
   255        "command": ["/pause"],
   256        "env_rules": [{"pattern": `PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, "strategy": "string", "required": true},{"pattern": `TERM=xterm`, "strategy": "string", "required": false}],
   257        "layers": ["16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"],
   258        "mounts": [],
   259        "exec_processes": [],
   260        "signals": [],
   261        "user": {
   262            "user_idname": {"pattern": ``, "strategy": "any"},
   263            "group_idnames": [{"pattern": ``, "strategy": "any"}],
   264            "umask": "0022"
   265        },
   266        "capabilities": null,
   267        "seccomp_profile_sha256": "",
   268        "allow_elevated": false,
   269        "working_dir": "/",
   270        "allow_stdio_access": false,
   271        "no_new_privileges": true,
   272    },
   273]
   274external_processes := [
   275    {"command": ["bash"], "env_rules": [{"pattern": `PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, "strategy": "string", "required": true}], "working_dir": "/", "allow_stdio_access": false},
   276]
   277allow_properties_access := false
   278allow_dump_stacks := false
   279allow_runtime_logging := false
   280allow_environment_variable_dropping := false
   281allow_unencrypted_scratch := false
   282allow_capability_dropping := true
   283
   284
   285mount_device := data.framework.mount_device
   286unmount_device := data.framework.unmount_device
   287mount_overlay := data.framework.mount_overlay
   288unmount_overlay := data.framework.unmount_overlay
   289create_container := data.framework.create_container
   290exec_in_container := data.framework.exec_in_container
   291exec_external := data.framework.exec_external
   292shutdown_container := data.framework.shutdown_container
   293signal_container_process := data.framework.signal_container_process
   294plan9_mount := data.framework.plan9_mount
   295plan9_unmount := data.framework.plan9_unmount
   296get_properties := data.framework.get_properties
   297dump_stacks := data.framework.dump_stacks
   298runtime_logging := data.framework.runtime_logging
   299load_fragment := data.framework.load_fragment
   300scratch_mount := data.framework.scratch_mount
   301scratch_unmount := data.framework.scratch_unmount
   302reason := {
   303    "errors": data.framework.errors,
   304    "error_objects": data.framework.error_objects,
   305}
   306```
   307
   308## Converted to Rego Fragment
   309
   310The result of the command
   311
   312    securitypolicytool -c sample.toml -t fragment -n sample -v 1 -r
   313
   314is the following Rego fragment:
   315
   316``` rego
   317package sample
   318
   319svn := 1
   320framework_version := "0.3.0"
   321
   322fragments := [
   323    {"issuer": "did:web:contoso.com", "feed": "contoso.azurecr.io/infra", "minimum_svn": 1, "includes": ["containers"]},
   324]
   325containers := [
   326    {
   327        "command": ["rustc","--help"],
   328        "env_rules": [{"pattern": `PATH=/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, "strategy": "string", "required": true},{"pattern": `RUSTUP_HOME=/usr/local/rustup`, "strategy": "string", "required": true},{"pattern": `CARGO_HOME=/usr/local/cargo`, "strategy": "string", "required": true},{"pattern": `RUST_VERSION=1.52.1`, "strategy": "string", "required": true},{"pattern": `TERM=xterm`, "strategy": "string", "required": false},{"pattern": `PREFIX_.+=.+`, "strategy": "re2", "required": false}],
   329        "layers": ["fe84c9d5bfddd07a2624d00333cf13c1a9c941f3a261f13ead44fc6a93bc0e7a","4dedae42847c704da891a28c25d32201a1ae440bce2aecccfa8e6f03b97a6a6c","41d64cdeb347bf236b4c13b7403b633ff11f1cf94dbc7cf881a44d6da88c5156","eb36921e1f82af46dfe248ef8f1b3afb6a5230a64181d960d10237a08cd73c79","e769d7487cc314d3ee748a4440805317c19262c7acd2fdbdb0d47d2e4613a15c","1b80f120dbd88e4355d6241b519c3e25290215c469516b49dece9cf07175a766"],
   330        "mounts": [{"destination": "/container/path/one", "options": ["rbind","rshared","rw"], "source": "sandbox:///host/path/one", "type": "bind"},{"destination": "/container/path/two", "options": ["rbind","rshared","ro"], "source": "sandbox:///host/path/two", "type": "bind"}],
   331        "exec_processes": [{"command": ["top"], "signals": []}],
   332        "signals": [],
   333        "user": {
   334            "user_idname": {"pattern": ``, "strategy": "any"},
   335            "group_idnames": [{"pattern": ``, "strategy": "any"}],
   336            "umask": "0022"
   337        },
   338        "capabilities": {
   339            "bounding": ["CAP_SYS_ADMIN"],
   340            "effective": ["CAP_SYS_ADMIN"],
   341            "inheritable": ["CAP_SYS_ADMIN"],
   342            "permitted": ["CAP_SYS_ADMIN"],
   343            "ambient": ["CAP_SYS_ADMIN"],
   344        },
   345        "seccomp_profile_sha256": "",
   346        "allow_elevated": true,
   347        "working_dir": "/home/user",
   348        "allow_stdio_access": false,
   349        "no_new_privileges": true,
   350    },
   351    {
   352        "command": ["/pause"],
   353        "env_rules": [{"pattern": `PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, "strategy": "string", "required": true},{"pattern": `TERM=xterm`, "strategy": "string", "required": false}],
   354        "layers": ["16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"],
   355        "mounts": [],
   356        "exec_processes": [],
   357        "signals": [],
   358        "user": {
   359            "user_idname": {"pattern": ``, "strategy": "any"},
   360            "group_idnames": [{"pattern": ``, "strategy": "any"}],
   361            "umask": "0022"
   362        },
   363        "capabilities": null,
   364        "seccomp_profile_sha256": "",
   365        "allow_elevated": false,
   366        "working_dir": "/",
   367        "allow_stdio_access": false,
   368        "no_new_privileges": true,
   369    },
   370]
   371external_processes := [
   372    {"command": ["bash"], "env_rules": [{"pattern": `PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`, "strategy": "string", "required": true}], "working_dir": "/", "allow_stdio_access": false},
   373]
   374```
   375
   376## CLI Options
   377
   378### `-c`
   379
   380TOML configuration file to process (required)
   381
   382### `-r`
   383
   384output raw marshaled policy in addition to the base64
   385
   386### `-t`
   387
   388one of:
   389- `rego`: outputs a Rego policy
   390- `json`: outputs a legacy JSON policy (NOTE: some TOML elements are not supported in the legacy format)
   391- `fragment`: outputs a Rego fragment. The `-n` and `-v` are required for this option.
   392
   393### `-n`
   394
   395Required for `-t fragment`. Specifies the fragment Rego namespace.
   396
   397### `-v`
   398
   399Required for `-t fragment`. Specified the fragment SVN as a semantic versioning number, *e.g.*, "1.0.0"
   400
   401## Authorization
   402
   403Some images will be pulled from registries that require authorization. To add
   404authorization information for a given image, you would add an `[auth]` object
   405to the TOML definition for that image. For example:
   406
   407```toml
   408[[container]]
   409image_name = "rust:1.52.1"
   410command = ["rustc", "--help"]
   411
   412[auth]
   413username = "my username"
   414password = "my password"
   415```
   416
   417Authorization information needs to be added on a per-image basis as it can vary
   418from image to image and their respective registries.
   419
   420To pull an image using anonymous access, no `[auth]` object is required.
   421
   422## Pause container
   423
   424All LCOW pods require a pause container to run. The pause container must be
   425included in the policy. As this tool is aimed at LCOW developers, a default
   426version of the pause container is automatically added to policy even though it
   427isn't in the TOML configuration.
   428
   429If the version of the pause container changes from 3.1, you will need to update
   430the hardcoded root hash by running the `dmverity-vhd` to compute the root hash
   431for the new container and update this tool accordingly.

View as plain text