»Traces

Sentinel provides execution traces to better understand the execution of a policy.

When using the Sentinel CLI, traces are shown on policy failure during apply or test, or when the -trace flag is explicitly specified. For Sentinel-enabled applications, traces are optional and may require special configuration to enable.

The availability of the trace may vary from application to application. While some applications may only log traces on failure, others, such as Terraform Cloud, log the trace on every execution. For more details, consult your implementation's documentation.

»Analyzing a Trace

To show traces, let's use the example policy below with the CLI:

param day
param hour

is_weekday = rule { day not in ["saturday", "sunday"] }
is_open_hours = rule { hour > 8 and hour < 17 }

main = rule { is_open_hours and is_weekday }

Let's cause the policy to fail so the trace is more interesting. If you're on a terminal that supports it, the trace output will be colored so you can more clearly see passes, failures, and rules.

$ sentinel apply main.sentinel
main.sentinel:1:7: requires value for parameter day


  Values can be strings, floats, or JSON array or object values. To force
  strings, use quotes.

  Enter a value: sunday

main.sentinel:2:7: requires value for parameter hour


  Values can be strings, floats, or JSON array or object values. To force
  strings, use quotes.

  Enter a value: 14

Execution trace. The information below will show the values of all
the rules evaluated. Note that some rules may be missing if
short-circuit logic was taken.

Note that for collection types and long strings, output may be
truncated; re-run "sentinel apply" with the -json flag to see the
full contents of these values.

The trace is displayed due to a failed policy.

Fail - main.sentinel

main.sentinel:7:1 - Rule "main"
  Value:
    false

main.sentinel:5:1 - Rule "is_open_hours"
  Value:
    true

main.sentinel:4:1 - Rule "is_weekday"
  Value:
    false

We can see all of our rules neatly and clearly displayed along with the result of the policy. If you are getting the trace due to a failed policy and not because you explicitly used -trace, an informational message is displayed.

As we can see from our basic example, the main rule has failed and its result is highlighted in red. All peripheral rules that were also evaluated as part of the policy are also displayed below the main rule. Source positions are also displayed so that you can find the references to the rules in your code.

Via the trace, we can clearly see that while is_open_hours returned a true result, is_weekday did not, and per the logic in our code, the policy is rejected.

»Non-Boolean Rules and the Trace

The trace is particularly important when working with rules that return non-boolean data, such as rules where you want to see violations instead of a simple opaque boolean value. Let's take our example from the rules section, and write a small static policy for it:

Here is the output of our policy:

Execution trace. The information below will show the values of all
the rules evaluated. Note that some rules may be missing if
short-circuit logic was taken.

Note that for collection types and long strings, output may be
truncated; re-run "sentinel apply" with the -json flag to see the
full contents of these values.

The trace is displayed due to a failed policy.


Fail - weather.sentinel

weather.sentinel:11:1 - Rule "main"
  Value:
    [
      {
        "weekday": "Sunday"
        "weather": "clouds"
      }
      {
        "weekday": "Monday"
        "weather": "rain"
      }
      {
        "weekday": "Thursday"
        "weather": "clouds"
      }
      {
        "weekday": "Friday"
        "weather": "rain"
      }
    ]

We can now see all of the weekdays with non-sunny weather.

Note that prevent formatting issues and excessive output, the human-readable trace is limited in the volume of output it will display for collections.

»JSON Output

The trace can also be displayed in JSON by adding -json to sentinel apply and sentinel test, and will display the trace in its entirety, unlike the standard CLI output.

Here is the result of running sentinel apply -json against our weather policy:

{
  "can_override": false,
  "error": null,
  "policies": [
    {
      "allowed_failure": false,
      "error": null,
      "policy": "weather.sentinel",
      "result": false,
      "trace": {
        "description": "",
        "error": null,
        "print": "",
        "result": false,
        "rules": {
          "main": {
            "desc": "",
            "ident": "main",
            "position": {
              "filename": "weather.sentinel",
              "offset": 328,
              "line": 11,
              "column": 1
            },
            "value": [
              {
                "weather": "clouds",
                "weekday": "Sunday"
              },
              {
                "weather": "rain",
                "weekday": "Monday"
              },
              {
                "weather": "clouds",
                "weekday": "Thursday"
              },
              {
                "weather": "rain",
                "weekday": "Friday"
              }
            ]
          }
        }
      }
    }
  ],
  "result": false
}

Note that the trace is always included with this output, regardless of whether or not the policy passes or fails; using -trace is unnecessary.

Additionally, with sentinel apply, you can display the value of a single rule in JSON, instead of the entire trace. This is done with the -json-rule flag.

Here is the result of executing sentinel apply -json-rule main weather.sentinel:

[
  {
    "weather": "clouds",
    "weekday": "Sunday"
  },
  {
    "weather": "rain",
    "weekday": "Monday"
  },
  {
    "weather": "clouds",
    "weekday": "Thursday"
  },
  {
    "weather": "rain",
    "weekday": "Friday"
  }
]

»Other Trace Details

There are some other details that are good to know when working with the trace:

  • Only rules that get executed are added to the trace. Considering our first example where the main rule is the expression is_open_hours and is_weekday, if our expression was using an or operator instead of and, in addition to the policy passing, is_open_hours would be present in the trace, but is_weekday would not be, as the policy would have never evaluated that rule.
  • Descriptions for both rules and policies will show up in the trace as well if present. Here is the output to our first policy with the appropriate annotations:
...

Execution trace. The information below will show the values of all
the rules evaluated. Note that some rules may be missing if
short-circuit logic was taken.

Note that for collection types and long strings, output may be
truncated; re-run "sentinel apply" with the -json flag to see the
full contents of these values.

The trace is displayed due to a failed policy.

Fail - main.sentinel

Description:
  A very basic policy to determine if a run is within working
  hours.

main.sentinel:7:1 - Rule "main"
  Value:
    false

main.sentinel:5:1 - Rule "is_open_hours"
  Description:
    Passes if run during business hours.

  Value:
    true

main.sentinel:4:1 - Rule "is_weekday"
  Description:
    Passes if the day does not fall on the weekend.

  Value:
    false