» Command: apply

The sentinel apply command is used to execute a policy locally for development purposes.

» Usage

Usage: sentinel apply [options] POLICY

This command executes the policy file at the path specified by POLICY.

The output will indicate whether the policy passed or failed. The exit code also reflects the status of the policy: 0 is pass, 1 is fail, 2 is undefined (fail, but because the result was undefined), and 2 is a runtime error.

A configuration file can be specified with -config to define available import plugins, mock data, and global values. This is used to simulate a policy embedded within an application. The documentation for this configuration file is below.

The command-line flags are all optional. The list of available flags are:

  • -config=path - Path to a configuration file specifying available imports, mock data, globals, etc.

  • -global key=value - Global values to inject into the running policy. This is equivalent to setting "global" in the configuration file. Any keys set here will override conflicting keys in the configuration. The value should be a JSON value. If the first character is not a valid JSON starting symbol, then the entire value is treated as a string.

  • -explain - Always show the execution trace. This shows intermediate boolean expression values. This always shows for failed policies.

» Configuration File

The format of the configuration file is JSON. The available keys are:

» Mock Imports

Mock imports allow running a policy with an import that you may not have access to or is too difficult to run. For example, it can be easier to mock a Consul import than to run a local Consul server.

Mock imports are specified in the mock key. This value of this configuration is a map of maps, where the key is the import name and the value is a map of the data within that import. The data within the import can nest with any valid JSON type, such as nested maps, maps containing arrays, etc.

Example:

{
    "mock": {
        "time": {
            "hour": 9,
            "minute": 42
        }
    }
}

With the above configuration, the following policy would pass:

import "time"

main = time.hour == 9

» Imports

Imports allow you to run a real import plugin with a policy. The sentinel binary will launch the plugin, connect to it, configure it, and execute it as needed by the policy.

Note the difference between this and mock imports above is that this configuration specifies real import plugins to execute. The mock data fakes an import with static data.

Imports are specified by the import key. The value of this is a map where the key is the name of the import and the value is another map with configuration about that import. The configuration map has the following keys:

  • path (string, required) - Path to the import plugin executable.
  • args (list of string, optional) - A list of arguments to pass to the executable when starting it.
  • env (map of string to string, optional) - A set of environmental variables to set when launching the plugin.
  • config (map, optional) - Configuration for the plugin itself. This is specific to each individual plugin. Please reference the documentation for the plugin for more information.

Example:

{
    "imports": {
        "time": {
            "path": "/path/to/sentinel-import-time",
            "config": { "fixed_time": 1504155600 }
        }
    }
}

With the above configuration, the following policy would pass assuming the import configuration is valid:

import "time"

main = time.day == 31

» Global

Global data is injected directly into the global scope of the policy. This can be used to simulate global data that may be injected by a Sentinel-enabled application.

Global data is specified by the global key. The value is a map of variables to inject directly into the running policy.

Example:

{
    "global": {
        "time": {
            "day": 31
        }
    }
}

With the above configuration, the following policy would pass. Notice that we don't have to do any import. The values of global are injected directly into the global scope.

main = time.day == 31

» Test Cases

Test cases specify the test cases for the test command.

Tests are specified by the test key. The value of this is a map of string to boolean. The key is the name of a rule and the value is the expected value of that rule. If a rule is not specified, than any value is allowed.

Example:

{
    "test": {
        "main": true,
        "valid_day": false
    }
}

For the policy:

valid_day = rule { 2 < 1 } # This is just an example!
main = rule { not valid_day }

For more information, read about the test command.