Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: constraints available in Rego? #3080

Closed
skaven81 opened this issue Oct 18, 2023 · 3 comments
Closed

Question: constraints available in Rego? #3080

skaven81 opened this issue Oct 18, 2023 · 3 comments

Comments

@skaven81
Copy link

This is a question, not a bug report or feature request.

At https://open-policy-agent.github.io/gatekeeper/website/docs/sync it is explained that synced resources can be accessed at data.inventory in our Rego policy.

When running a trace while debugging a problem, I noticed that there's more inside data than just inventory though:

$ grep -A9999999 "DRIVER: Rego:" /tmp/logdump2.txt  | grep -v "DRIVER: Rego:" | grep -v "denied admission: " | ucmjq -r '.["admission.k8s.gatekeeper.sh"].data | keys'
[
  "constraints",
  "inventory"
]

Hey....constraints. That could be handy. But it's not mentioned anywhere in the documentation that I could find. I observed that the contents of this data structure appears to be the parameters provided to each defined Constraint in the cluster (not the contents of the Constraint themselves). data.constraints[<kind>][<name>] appears to resolve to the parameters fed to that particular Constraint. The content of the trace suggests that during evaluation of each Constraint, that all of the cluster's Constraints' parameters are available there.

I would actually find this immensely useful for a specific kind of Constraint Template I need to write, but I don't want to depend on this data being there if it's just an accident or a bug that it's appearing there.

Is this data guaranteed to be there going forward? If so, should it be documented somewhere?

@maxsmythe
Copy link
Contributor

It's not guaranteed to exist, and any template that accesses data.constraints shouldn't compile and should return an error.

It is a local cache of the entire constraint (not just the parameters) that currently exists as a performance optimization.

What are you looking to do that requires more than input.parameters?

It is possible to sync constraints to inventory, but part of the reason visibility is restricted is to ensure that Gatekeeper has room to change the shape of its resources without breaking pre-existing constraint templates.

@skaven81
Copy link
Author

OK it's good that I asked!

What are you looking to do that requires more than input.parameters?

I have some Constraint Templates that have parameters that allow certain namespaces to be exempted from validation, and need to make sure that only administrative users are allowed to create such namespaces. The exempted namespaces are listed in the Constraints' parameters. So what I'm doing right now is (rather painfully) syncing all the Constraints into data.inventory, and then using an (again rather painful) lookup to see if any such overrides exist for the namespace that is being created, and block creation if it's one of the "special" ones.

        protected_namespace(ns) {
          ns in data.inventory.cluster[_][_][_].spec.parameters.overrides[_].projectIdOfNamespaces
        }
        protected_namespace(ns) {
          ns in data.inventory.cluster[_][_][_].spec.parameters.overrides[_].namespaces
        }

If we walk this all back to first principles, this all actually comes down to the fact that Constraints don't have an excludedNamespaceSelector in the match field. This makes it difficult or impossible to create Constraints (or a group of Constraints) that behave in a default manner, but with overrides for specific namespace (namely, overrides for namespaces that have a specific label, rather than a static list of namespaces in excludedNamespaces).

As a result of this gap, I have to write my ConstraintTemplates with this default-and-overrides behavior written directly into the Rego and configured using parameters, not the match field. And this in turn creates opportunities for security problems, so I have other ConstraintTemplates (the ones mentioned above) that evaluate the parameters given to other Constraints against namespace creations, and block those that would cause a security problem.

@skaven81
Copy link
Author

skaven81 commented Oct 18, 2023

I've opened #3081 and #3082 to address the root causes of this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants