Policy Resource Definition
As a Wayfinder or workspace administrator you can write your own custom security or access policies. Wayfinder delivers access controls and policy to both the Wayfinder API and managed clusters via the Policy CRD. Whether you want to control access or resource usage across Wayfinder, or any cluster within a workspace, Policy is the instrument you can use to do it.
This topic contains a breakdown of the policy resource definition with some examples.
How policies are shipped
The distribution of the policy is defined by the spec.target.selector
. The structure of this uses the metav1.LabelSelector
, allowing you to filter down which clusters have the policies shipped based on the labels associated to the resource. This means policy distribution can take into account aspects such provider (appvia.io/provider
), stages (appvia.io/stage
), and other labels on the cluster.
Providing no target indicates the policy is related to the Wayfinder API.
apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
target:
# Used to filter on the clusters in the workspace
selector:
# You can use matchLabel
matchLabels:
name: test
appvia.io/stage: "*"
# Alternatively or in combination you can use label expressions
matchExpressions:
- key: appvia.io/stage
operator: Exists
- key: appvia.io/stage
operator: NotIn
values: [prod]
- key: appvia.io/provider
operator: In
values: [EKS, GKE]
Sections of the policy resource definition
Policies can be broken down into the following sections:
- A filter for the subjects for which the policy is intended: which users, robots, or roles
- A filter for the resources that are being acted on
- A filter for the location of those resources being acted on
- A decision on the outcome, which can be statically or dynamically driven
These sections are explained below.
Define who the policy applies to
Embedded in the policy document is a collection of selectors for resources, namespaces and subjects. The subjects filter permits you to filter on the users, their roles, their workspace, or their scopes.
Wayfinder has three scopes for the subjects:
wayfinder:system:user
is scoped to all users within Wayfinder.wayfinder:system:robot
is scoped to all subjects that are robot accounts created by Wayfinder.wayfinder:system:kubernetes
is scoped to all subjects that are bound to kubernetes service accounts.
Notes on scope definition:
- Values support wildcards, so
scopes: ["*"]
is acceptable. - The order of the selectors does not matter.
- Multiple declarations are also taken into account, so you can specify the
subject
selector multiple times if needed.
apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
selectors:
- subject:
# A collection of scopes (see above) which the policy
# should apply - note,
scopes:
- wayfinder:system:kubernetes
# A collection of individual subjects which the policy
# is applied to - these can be a robot account, a user
# account or a kuberneres service account name
subjects:
- user@example.org
# A robot account
- wayfinder:system:robot:<workspace>:<robot>
# A kubernetes service account
- system:serviceaccount:<namespace>:<service account>
# Roles profiles a filter on the roles the 'user' processes
# within the workspace - i.e. member, admin, support and so forth.
roles:
- member
- support
# Groups are a one-to-one binding to workspace names -
# these are added to the groups of the user JWT token and
# can use used to filter on.
groups: []
Define which resources the policies applies to
Once you have filtered on who the policy applies to, there must be a resource
or nonresourceurl
definition. Otherwise, the policy is an automatic denial. The resource selector is a one-to-one mapping to the standard RBAC format supported in kubernetes.
apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
selectors:
resource:
# Filter on the API Group of the resource being requested.
- groups:
- core
- apps
resources:
- deployments
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- groups:
- networking
resources:
- ingresses
verbs:
- "*"
Define the location of the policy
The namespace selector lets you filter the request to one or more namespaces based on labeling.
Notes on defining the location:
- The absence of a
namespace
selector indicates that anyresource
selector is directed towards resources that are cluster scoped. - When specifying a
namespace
selector, if the resource has ametadata.namespace
field, it is immediately rejected.
apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
selectors:
namespace:
# matchlabels to filter the policy to specific namespaces with labels x
matchLabels:
name: test
# or
name: "*"
# matchExpressions again permits you to narrow down the scope of
# the policy to one of more namespaces in the cluster
matchExpressions:
- key: appvia.io/stage
operator: In
values: [prod]
- key: name
operator: ["*"]
- key: name
operator: NotIn
values: [test]
Define how the policy decides the outcome
Policies have both static and dynamic means to determine the outcome of a request, as shown in the following examples.
Static Decisions
apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
policy:
decision:
action: <allow|denied>
message: A message which is shown to the user as a violation
# The selectors from above
selectors: []
Dynamic Decisions
The example below denies all daemonset access for users with a specific role.
---
apiVersion: policy.appvia.io/v1alpha1
kind: Policy
metadata:
name: cluster.services.v1
spec:
policy:
# We deny the action
decision:
action: denied
message: You are not permitted to perform this action
selectors:
# We filter on all user whom have the role 'member'
- subject:
roles:
- members
# We apply this to all namespaces which have the workspace label
- namespace:
matchExpressions:
- key: appvia.io/workspace
operator: Exists
# We filter only actions related to daemonsets
- resource:
groups:
- apps
resources:
- daemonsets
verbs:
- "*"
target:
selector:
# We target only clusters related to production
matchExpressions:
- key: appvia.io/stage
operator: In
values: [prod]
See Dynamic Policies for more information.