Skip to content

Default deny when accessing undefined key #1164

@marcelmindemann

Description

@marcelmindemann

Hi,
I am using Conftest: 0.62.0, OPA: 1.6.0 to implement Pull Request checks on several repositories holding configuration in our organization. The config files are mostly JSON or YAML and they are pretty dynamic in their schema and highly nested.

The big problem we've noticed with conftest is the robustness when it comes to accessing nonexistent keys from the input document(s), which could happens due to a typo or an unexpected schema of the input document. A policy that tries to access a nonexistent key like input.changes.before.groups.mygroup.members will evaluate to undefined via Rego's cascading undefined.

This means any policy which tries to access a nonexistent key or that simply contains a typo defaults to allow, with no way of noticing that you have a typo somewhere other than extensive unit testing. This becomes very high effort when your input documents are deeply nested.

I've read the following related issues:
open-policy-agent/opa#1857
open-policy-agent/opa#2345
open-policy-agent/opa#7602

Do I take it correctly that the current best workaround is using object.get()? While that works, it does make our policy code extremely verbose and unreadable. A lookup like

m := input.changes.before.groups.mygroup.members

blows up to six lines of

changes := object.get(input, "changes", {})
before := object.get(changes, "before", {})
...

I think this negates the best part of Rego, readable policies that read close to human language.

Another option would be to use a "default deny" strategy if the deny rule evaluates to undefined, but this seems to be impossible, as Rego only allows default on complete rules and conftest's convention is to use the partial rule deny contains msg. Therefore, I cannot do

default deny := ["default deny msg"] # error: conflicting rules data.play.deny found

Does someone have some guidance on the current best practice to use conftest in a robust way, e.g. not silently defaulting to allow when there is any typo/incorrect lookup in the policy?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions