Skipping Sentinel’s “soft-mandatory” Enforcement Level

Hashicorp Sentinel currently offers three enforcement levels:

  • Advisory: The policy is allowed to fail. However, a warning should be shown to the user or logged.
  • Soft Mandatory: The policy must pass unless an override is specified. The semantics of “override” are specific to each Sentinel-enabled application. The purpose of this level is to provide a level of privilege separation for a behavior. Additionally, the override provides non-repudiation since at least the primary actor was explicitly overriding a failed policy.
  • Hard Mandatory: The policy must pass no matter what. The only way to override a hard mandatory policy is to explicitly remove the policy. Hard mandatory is the default enforcement level. It should be used in situations where an override is not possible.

Soft-mandatory sounds nice, but I don’t use it at all. Below I’ll explain why, and what I wish they had.

Why soft-mandatory doesn’t help me

At my company, developers don’t have console access into the Terraform Cloud/Enterprise UI; instead, all information is forwarded into their pipeline logs for actioning. Further, we keep things pretty ephemeral around here, so the concept of a workspace admin isn’t really something that resonates with us. Finally, deciding who would have the authority to approve one-off policy bypasses is a bit of a challenge in a large & complex org, and it comes with the added challenge of building out additional tooling to capture everything needed for audits. That’s a lot of work to enable someone to bypass a security control!

Also, let’s not forget that in addition to the in-pipeline checks from Sentinel, there are additional gates, controls, and auto-remediations once resources land in the cloud platforms, so bypassing Sentinel is far from the only area that changes would be needed.

Therefore, our stance is to not use any soft-mandatory and to instead slow-roll our policies in as Advisory, then start slow-rolling them in as Hard-Mandatory, working with our module developers and cloud developers along the way. It’s crucial to work as a team through this to build smart, useful, effective controls which don’t prevent legitimate business from occuring. That last bit implies that we must be reasonable as we put in new policies, but once in place across the board & backported to all modules, we should be safe to keep it hard-mandatory moving forwards.

This pattern works well for us!

A new enforcement level

I’d really like to see something like the below options added:

  • Hidden: Only visible to Sentinel Admins, and any errors in execution are logged but suppressed from the regular developers. This would be great for gathering data before making policies visible to developers as a sort of pre-rollout staging
  • Upcoming: (or Pending, Disabled, etc.) Visible to developers, perhaps even evaluates, but does not raise issues like advisory. To me this would be great if Hidden can’t be a thing, because it would be a way to let policies “soak” in place while NOT teaching developers to ignore Advisory warnings
  • Debug: Visible to developers, does not block, but is more verbose (currently we do this through rolling out a modified version of the policy with additional debugging on and/or downloading mocks to test locally)

I want to reiterate the idea behind bullets 1 & 2 above: Currently my solution to a misbehaving policy is to put it into Advisory whilst I troubleshoot it. This has the effect of teaching thousands of developers that Advisory means that the Sentinel team is probably fixing it… Instead, I want them to see Advisory as a “hey, this is something you need to look at soon before it’s blocked in Hard-Mandatory”, and have a separate enforcement level to let them know “hey, this may be coming and/or is being worked on”. A “Maintenance-Mode” of sorts.


I love the idea behind a Soft-Mandatory enforcement; however, it didn’t fit my organization’s needs. There are a few other enforcement levels though that I think would be super cool to have. Let me know what you think!