Skip to main content
Version: 1.4

Dynamic Policies

The authentication module includes an OPA runtime used to drive dynamic policies. Wayfinder presents a simpler Domain Specific Language (DSL) to deliver policy into a cluster, while retaining all the features of various open sources projects.

Dynamic policy section

Dynamic policy is specified in the spec.policy section of the policy definition.

apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
# hints inform the runtime about resources you want to reference in
# the data.inventory.
policy:
policy: |
violation[response] {
<expressions>

response = {
"message": "This is a violation message",
}
}

validation[response] {
<expressions>

response = {
"message": "This is a validation message",
"field": "spec.something",
"value": "badvalue",
}
}
selectors: []
target:
selectors: {}
note

Currently, Wayfinder comes embedded with the OPA v0.35.0 runtime.

Violations and validations

Expressions, if positive, should return a map containing at a minimum message or msg (the latter ensures compatibility with Gatekeeper). The only difference from a user's perspective is the return code: 403 and 400 respectively. You can optionally return the following fields:

  • field–must provide a json path into the resource definition, and is used to help debug the issue
  • value–contains a invalid value to highlight to the user

About data inventory

All policies running under the runtime have access to the data inventory. Behind the scenes, Wayfinder watches one or more resources in the Kubernetes cluster and syncs the resources into the inventory, making them available via data.inventory.KIND.NAMESPACE.NAME. The feature lets you make decisions driven by the current state rather than just the payload of an incoming request. As an example, on creation of an ingress resource we look up all other ingress resources to ensure no conflict.

By default Wayfinder watches the following resources out of the box:

  ws, err := watchers.New(kc, dc, watchers.Config{
DisableResources: []schema.GroupVersionResource{
{Version: "v1", Resource: "configmaps"},
{Version: "v1", Resource: "secrets"},
{Version: "v1beta1", Group: "metrics.k8s.io"},
},
DefaultResources: []schema.GroupVersionResource{
{Group: "apps", Version: "v1", Resource: "*"},
{Group: "autoscaling", Resource: "*"},
{Group: "networking.k8s.io", Version: "v1", Resource: "*"},
{Group: "policy", Version: "v1beta1", Resource: "*"},
{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "*"},
{Version: "v1", Resource: "namespaces"},
{Version: "v1", Resource: "persistentvolumes"},
{Version: "v1", Resource: "resourcequotas"},
{Version: "v1", Resource: "serviceaccounts"},
{Version: "v1", Resource: "services"},
},
})
note

For security reasons, we explicitly deny the ability to watch secrets and configmaps.

Update the inventory

While we watch the commonly referenced resources, you might want to bring in additional resource types and make them accessible via the inventory to drive policy decisions. You can do this by using the spec.hints: [] fields. As policies are distributed to the clusters, the runtime reads the hints and automatically creates any watchers required to bring into the inventory. Wayfinder also dynamically registers the admission webhooks so the requests are intercepted. Here's an example using the spec.hints: [] fields:

spec:
hints:
- group: <apigroup>
version: <version>
resource: <kind>