Files
regorus/tests/kata/data/web/policy.rego
Anand Krishnamoorthi e9cd6d6afc Tests from MSFT fork of kata-containers (#230)
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
2024-05-08 17:38:50 -07:00

1865 lines
54 KiB
Rego

# Copyright (c) 2023 Microsoft Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
package agent_policy
import future.keywords.in
import future.keywords.every
# Default values, returned by OPA when rules cannot be evaluated to true.
default AddARPNeighborsRequest := false
default AddSwapRequest := false
default CloseStdinRequest := false
default CopyFileRequest := false
default CreateContainerRequest := false
default CreateSandboxRequest := false
default DestroySandboxRequest := true
default ExecProcessRequest := false
default GetOOMEventRequest := true
default GuestDetailsRequest := true
default ListInterfacesRequest := false
default ListRoutesRequest := false
default MemHotplugByProbeRequest := false
default OnlineCPUMemRequest := true
default PauseContainerRequest := false
default ReadStreamRequest := false
default RemoveContainerRequest := true
default RemoveStaleVirtiofsShareMountsRequest := true
default ReseedRandomDevRequest := false
default ResumeContainerRequest := false
default SetGuestDateTimeRequest := false
default SetPolicyRequest := false
default SignalProcessRequest := true
default StartContainerRequest := true
default StartTracingRequest := false
default StatsContainerRequest := true
default StopTracingRequest := false
default TtyWinResizeRequest := true
default UpdateContainerRequest := false
default UpdateEphemeralMountsRequest := false
default UpdateInterfaceRequest := true
default UpdateRoutesRequest := true
default WaitProcessRequest := true
default WriteStreamRequest := false
# AllowRequestsFailingPolicy := true configures the Agent to *allow any
# requests causing a policy failure*. This is an unsecure configuration
# but is useful for allowing unsecure pods to start, then connect to
# them and inspect OPA logs for the root cause of a failure.
default AllowRequestsFailingPolicy := false
CreateContainerRequest {
i_oci := input.OCI
i_storages := input.storages
print("CreateContainerRequest: i_oci.Hooks =", i_oci.Hooks)
is_null(i_oci.Hooks)
print("CreateContainerRequest: i_oci.Linux.Seccomp =", i_oci.Linux.Seccomp)
is_null(i_oci.Linux.Seccomp)
some p_container in policy_data.containers
print("======== CreateContainerRequest: trying next policy container")
p_pidns := p_container.sandbox_pidns
i_pidns := input.sandbox_pidns
print("CreateContainerRequest: p_pidns =", p_pidns, "i_pidns =", i_pidns)
p_pidns == i_pidns
p_oci := p_container.OCI
print("CreateContainerRequest: p Version =", p_oci.Version, "i Version =", i_oci.Version)
p_oci.Version == i_oci.Version
print("CreateContainerRequest: p Readonly =", p_oci.Root.Readonly, "i Readonly =", i_oci.Root.Readonly)
p_oci.Root.Readonly == i_oci.Root.Readonly
allow_anno(p_oci, i_oci)
p_storages := p_container.storages
allow_by_anno(p_oci, i_oci, p_storages, i_storages)
allow_linux(p_oci, i_oci)
print("CreateContainerRequest: true")
}
# Reject unexpected annotations.
allow_anno(p_oci, i_oci) {
print("allow_anno 1: start")
not i_oci.Annotations
print("allow_anno 1: true")
}
allow_anno(p_oci, i_oci) {
print("allow_anno 2: p Annotations =", p_oci.Annotations)
print("allow_anno 2: i Annotations =", i_oci.Annotations)
i_keys := object.keys(i_oci.Annotations)
print("allow_anno 2: i keys =", i_keys)
every i_key in i_keys {
allow_anno_key(i_key, p_oci)
}
print("allow_anno 2: true")
}
allow_anno_key(i_key, p_oci) {
print("allow_anno_key 1: i key =", i_key)
startswith(i_key, "io.kubernetes.cri.")
print("allow_anno_key 1: true")
}
allow_anno_key(i_key, p_oci) {
print("allow_anno_key 2: i key =", i_key)
some p_key, _ in p_oci.Annotations
p_key == i_key
print("allow_anno_key 2: true")
}
# Get the value of the "io.kubernetes.cri.sandbox-name" annotation and
# correlate it with other annotations and process fields.
allow_by_anno(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_anno 1: start")
s_name := "io.kubernetes.cri.sandbox-name"
not p_oci.Annotations[s_name]
i_s_name := i_oci.Annotations[s_name]
print("allow_by_anno 1: i_s_name =", i_s_name)
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, i_s_name)
print("allow_by_anno 1: true")
}
allow_by_anno(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_anno 2: start")
s_name := "io.kubernetes.cri.sandbox-name"
p_s_name := p_oci.Annotations[s_name]
i_s_name := i_oci.Annotations[s_name]
print("allow_by_anno 2: i_s_name =", i_s_name, "p_s_name =", p_s_name)
allow_sandbox_name(p_s_name, i_s_name)
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, i_s_name)
print("allow_by_anno 2: true")
}
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, s_name) {
print("allow_by_sandbox_name: start")
s_namespace := "io.kubernetes.cri.sandbox-namespace"
p_namespace := p_oci.Annotations[s_namespace]
i_namespace := i_oci.Annotations[s_namespace]
print("allow_by_sandbox_name: p_namespace =", p_namespace, "i_namespace =", i_namespace)
p_namespace == i_namespace
allow_by_container_types(p_oci, i_oci, s_name, p_namespace)
allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages)
allow_process(p_oci, i_oci, s_name)
print("allow_by_sandbox_name: true")
}
allow_sandbox_name(p_s_name, i_s_name) {
print("allow_sandbox_name 1: start")
p_s_name == i_s_name
print("allow_sandbox_name 1: true")
}
allow_sandbox_name(p_s_name, i_s_name) {
print("allow_sandbox_name 2: start")
# TODO: should generated names be handled differently?
contains(p_s_name, "$(generated-name)")
print("allow_sandbox_name 2: true")
}
# Check that the "io.kubernetes.cri.container-type" and
# "io.katacontainers.pkg.oci.container_type" annotations designate the
# expected type - either a "sandbox" or a "container". Then, validate
# other annotations based on the actual "sandbox" or "container" value
# from the input container.
allow_by_container_types(p_oci, i_oci, s_name, s_namespace) {
print("allow_by_container_types: checking io.kubernetes.cri.container-type")
c_type := "io.kubernetes.cri.container-type"
p_cri_type := p_oci.Annotations[c_type]
i_cri_type := i_oci.Annotations[c_type]
print("allow_by_container_types: p_cri_type =", p_cri_type, "i_cri_type =", i_cri_type)
p_cri_type == i_cri_type
allow_by_container_type(i_cri_type, p_oci, i_oci, s_name, s_namespace)
print("allow_by_container_types: true")
}
allow_by_container_type(i_cri_type, p_oci, i_oci, s_name, s_namespace) {
print("allow_by_container_type 1: i_cri_type =", i_cri_type)
i_cri_type == "sandbox"
i_kata_type := i_oci.Annotations["io.katacontainers.pkg.oci.container_type"]
print("allow_by_container_type 1: i_kata_type =", i_kata_type)
i_kata_type == "pod_sandbox"
allow_sandbox_container_name(p_oci, i_oci)
allow_sandbox_net_namespace(p_oci, i_oci)
allow_sandbox_log_directory(p_oci, i_oci, s_name, s_namespace)
print("allow_by_container_type 1: true")
}
allow_by_container_type(i_cri_type, p_oci, i_oci, s_name, s_namespace) {
print("allow_by_container_type 2: i_cri_type =", i_cri_type)
i_cri_type == "container"
i_kata_type := i_oci.Annotations["io.katacontainers.pkg.oci.container_type"]
print("allow_by_container_type 2: i_kata_type =", i_kata_type)
i_kata_type == "pod_container"
allow_container_name(p_oci, i_oci)
allow_net_namespace(p_oci, i_oci)
allow_log_directory(p_oci, i_oci)
print("allow_by_container_type 2: true")
}
# "io.kubernetes.cri.container-name" annotation
allow_sandbox_container_name(p_oci, i_oci) {
print("allow_sandbox_container_name: start")
container_annotation_missing(p_oci, i_oci, "io.kubernetes.cri.container-name")
print("allow_sandbox_container_name: true")
}
allow_container_name(p_oci, i_oci) {
print("allow_container_name: start")
allow_container_annotation(p_oci, i_oci, "io.kubernetes.cri.container-name")
print("allow_container_name: true")
}
container_annotation_missing(p_oci, i_oci, key) {
print("container_annotation_missing:", key)
not p_oci.Annotations[key]
not i_oci.Annotations[key]
print("container_annotation_missing: true")
}
allow_container_annotation(p_oci, i_oci, key) {
print("allow_container_annotation: key =", key)
p_value := p_oci.Annotations[key]
i_value := i_oci.Annotations[key]
print("allow_container_annotation: p_value =", p_value, "i_value =", i_value)
p_value == i_value
print("allow_container_annotation: true")
}
# "nerdctl/network-namespace" annotation
allow_sandbox_net_namespace(p_oci, i_oci) {
print("allow_sandbox_net_namespace: start")
key := "nerdctl/network-namespace"
p_namespace := p_oci.Annotations[key]
i_namespace := i_oci.Annotations[key]
print("allow_sandbox_net_namespace: p_namespace =", p_namespace, "i_namespace =", i_namespace)
regex.match(p_namespace, i_namespace)
print("allow_sandbox_net_namespace: true")
}
allow_net_namespace(p_oci, i_oci) {
print("allow_net_namespace: start")
key := "nerdctl/network-namespace"
not p_oci.Annotations[key]
not i_oci.Annotations[key]
print("allow_net_namespace: true")
}
# "io.kubernetes.cri.sandbox-log-directory" annotation
allow_sandbox_log_directory(p_oci, i_oci, s_name, s_namespace) {
print("allow_sandbox_log_directory: start")
key := "io.kubernetes.cri.sandbox-log-directory"
p_dir := p_oci.Annotations[key]
regex1 := replace(p_dir, "$(sandbox-name)", s_name)
regex2 := replace(regex1, "$(sandbox-namespace)", s_namespace)
print("allow_sandbox_log_directory: regex2 =", regex2)
i_dir := i_oci.Annotations[key]
print("allow_sandbox_log_directory: i_dir =", i_dir)
regex.match(regex2, i_dir)
print("allow_sandbox_log_directory: true")
}
allow_log_directory(p_oci, i_oci) {
print("allow_log_directory: start")
key := "io.kubernetes.cri.sandbox-log-directory"
not p_oci.Annotations[key]
not i_oci.Annotations[key]
print("allow_log_directory: true")
}
allow_linux(p_oci, i_oci) {
p_namespaces := p_oci.Linux.Namespaces
print("allow_linux: p namespaces =", p_namespaces)
i_namespaces := i_oci.Linux.Namespaces
print("allow_linux: i namespaces =", i_namespaces)
p_namespaces == i_namespaces
allow_masked_paths(p_oci, i_oci)
allow_readonly_paths(p_oci, i_oci)
print("allow_linux: true")
}
allow_masked_paths(p_oci, i_oci) {
p_paths := p_oci.Linux.MaskedPaths
print("allow_masked_paths 1: p_paths =", p_paths)
i_paths := i_oci.Linux.MaskedPaths
print("allow_masked_paths 1: i_paths =", i_paths)
allow_masked_paths_array(p_paths, i_paths)
print("allow_masked_paths 1: true")
}
allow_masked_paths(p_oci, i_oci) {
print("allow_masked_paths 2: start")
not p_oci.Linux.MaskedPaths
not i_oci.Linux.MaskedPaths
print("allow_masked_paths 2: true")
}
# All the policy masked paths must be masked in the input data too.
# Input is allowed to have more masked paths than the policy.
allow_masked_paths_array(p_array, i_array) {
every p_elem in p_array {
allow_masked_path(p_elem, i_array)
}
}
allow_masked_path(p_elem, i_array) {
print("allow_masked_path: p_elem =", p_elem)
some i_elem in i_array
p_elem == i_elem
print("allow_masked_path: true")
}
allow_readonly_paths(p_oci, i_oci) {
p_paths := p_oci.Linux.ReadonlyPaths
print("allow_readonly_paths 1: p_paths =", p_paths)
i_paths := i_oci.Linux.ReadonlyPaths
print("allow_readonly_paths 1: i_paths =", i_paths)
allow_readonly_paths_array(p_paths, i_paths, i_oci.Linux.MaskedPaths)
print("allow_readonly_paths 1: true")
}
allow_readonly_paths(p_oci, i_oci) {
print("allow_readonly_paths 2: start")
not p_oci.Linux.ReadonlyPaths
not i_oci.Linux.ReadonlyPaths
print("allow_readonly_paths 2: true")
}
# All the policy readonly paths must be either:
# - Present in the input readonly paths, or
# - Present in the input masked paths.
# Input is allowed to have more readonly paths than the policy.
allow_readonly_paths_array(p_array, i_array, masked_paths) {
every p_elem in p_array {
allow_readonly_path(p_elem, i_array, masked_paths)
}
}
allow_readonly_path(p_elem, i_array, masked_paths) {
print("allow_readonly_path 1: p_elem =", p_elem)
some i_elem in i_array
p_elem == i_elem
print("allow_readonly_path 1: true")
}
allow_readonly_path(p_elem, i_array, masked_paths) {
print("allow_readonly_path 2: p_elem =", p_elem)
some i_masked in masked_paths
p_elem == i_masked
print("allow_readonly_path 2: true")
}
# Check the consistency of the input "io.katacontainers.pkg.oci.bundle_path"
# and io.kubernetes.cri.sandbox-id" values with other fields.
allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_bundle_or_sandbox_id: start")
bundle_path := i_oci.Annotations["io.katacontainers.pkg.oci.bundle_path"]
bundle_id := replace(bundle_path, "/run/containerd/io.containerd.runtime.v2.task/k8s.io/", "")
key := "io.kubernetes.cri.sandbox-id"
p_regex := p_oci.Annotations[key]
sandbox_id := i_oci.Annotations[key]
print("allow_by_bundle_or_sandbox_id: sandbox_id =", sandbox_id, "regex =", p_regex)
regex.match(p_regex, sandbox_id)
allow_root_path(p_oci, i_oci, bundle_id)
every i_mount in input.OCI.Mounts {
allow_mount(p_oci, i_mount, bundle_id, sandbox_id)
}
allow_storages(p_storages, i_storages, bundle_id, sandbox_id)
print("allow_by_bundle_or_sandbox_id: true")
}
allow_process(p_oci, i_oci, s_name) {
p_process := p_oci.Process
i_process := i_oci.Process
print("allow_process: i terminal =", i_process.Terminal, "p terminal =", p_process.Terminal)
p_process.Terminal == i_process.Terminal
print("allow_process: i cwd =", i_process.Cwd, "i cwd =", p_process.Cwd)
p_process.Cwd == i_process.Cwd
print("allow_process: i noNewPrivileges =", i_process.NoNewPrivileges, "p noNewPrivileges =", p_process.NoNewPrivileges)
p_process.NoNewPrivileges == i_process.NoNewPrivileges
allow_caps(p_process.Capabilities, i_process.Capabilities)
allow_user(p_process, i_process)
allow_args(p_process, i_process, s_name)
allow_env(p_process, i_process, s_name)
print("allow_process: true")
}
allow_user(p_process, i_process) {
p_user := p_process.User
i_user := i_process.User
print("allow_user: input uid =", i_user.UID, "policy uid =", p_user.UID)
p_user.UID == i_user.UID
# TODO: track down the reason for registry.k8s.io/pause:3.9 being
# executed with gid = 0 despite having "65535:65535" in its container image
# config.
#print("allow_user: input gid =", i_user.GID, "policy gid =", p_user.GID)
#p_user.GID == i_user.GID
# TODO: compare the additionalGids field too after computing its value
# based on /etc/passwd and /etc/group from the container image.
}
allow_args(p_process, i_process, s_name) {
print("allow_args 1: no args")
not p_process.Args
not i_process.Args
print("allow_args 1: true")
}
allow_args(p_process, i_process, s_name) {
print("allow_args 2: policy args =", p_process.Args)
print("allow_args 2: input args =", i_process.Args)
count(p_process.Args) == count(i_process.Args)
every i, i_arg in i_process.Args {
allow_arg(i, i_arg, p_process, s_name)
}
print("allow_args 2: true")
}
allow_arg(i, i_arg, p_process, s_name) {
p_arg := p_process.Args[i]
print("allow_arg 1: i =", i, "i_arg =", i_arg, "p_arg =", p_arg)
p_arg2 := replace(p_arg, "$$", "$")
p_arg2 == i_arg
print("allow_arg 1: true")
}
allow_arg(i, i_arg, p_process, s_name) {
p_arg := p_process.Args[i]
print("allow_arg 2: i =", i, "i_arg =", i_arg, "p_arg =", p_arg)
# TODO: can $(node-name) be handled better?
contains(p_arg, "$(node-name)")
print("allow_arg 2: true")
}
allow_arg(i, i_arg, p_process, s_name) {
p_arg := p_process.Args[i]
print("allow_arg 3: i =", i, "i_arg =", i_arg, "p_arg =", p_arg)
p_arg2 := replace(p_arg, "$$", "$")
p_arg3 := replace(p_arg2, "$(sandbox-name)", s_name)
print("allow_arg 3: p_arg3 =", p_arg3)
p_arg3 == i_arg
print("allow_arg 3: true")
}
# OCI process.Env field
allow_env(p_process, i_process, s_name) {
print("allow_env: p env =", p_process.Env)
print("allow_env: i env =", i_process.Env)
every i_var in i_process.Env {
print("allow_env: i_var =", i_var)
allow_var(p_process, i_process, i_var, s_name)
}
print("allow_env: true")
}
# Allow input env variables that are present in the policy data too.
allow_var(p_process, i_process, i_var, s_name) {
some p_var in p_process.Env
p_var == i_var
print("allow_var 1: true")
}
# Match input with one of the policy variables, after substituting $(sandbox-name).
allow_var(p_process, i_process, i_var, s_name) {
some p_var in p_process.Env
p_var2 := replace(p_var, "$(sandbox-name)", s_name)
print("allow_var 2: p_var2 =", p_var2)
p_var2 == i_var
print("allow_var 2: true")
}
# Allow input env variables that match with a request_defaults regex.
allow_var(p_process, i_process, i_var, s_name) {
some p_regex1 in policy_data.request_defaults.CreateContainerRequest.allow_env_regex
p_regex2 := replace(p_regex1, "$(ipv4_a)", policy_data.common.ipv4_a)
p_regex3 := replace(p_regex2, "$(ip_p)", policy_data.common.ip_p)
p_regex4 := replace(p_regex3, "$(svc_name)", policy_data.common.svc_name)
p_regex5 := replace(p_regex4, "$(dns_label)", policy_data.common.dns_label)
print("allow_var 3: p_regex5 =", p_regex5)
regex.match(p_regex5, i_var)
print("allow_var 3: true")
}
# Allow fieldRef "fieldPath: status.podIP" values.
allow_var(p_process, i_process, i_var, s_name) {
name_value := split(i_var, "=")
count(name_value) == 2
is_ip(name_value[1])
some p_var in p_process.Env
allow_pod_ip_var(name_value[0], p_var)
print("allow_var 4: true")
}
# Allow common fieldRef variables.
allow_var(p_process, i_process, i_var, s_name) {
name_value := split(i_var, "=")
count(name_value) == 2
some p_var in p_process.Env
p_name_value := split(p_var, "=")
count(p_name_value) == 2
p_name_value[0] == name_value[0]
# TODO: should these be handled in a different way?
always_allowed := ["$(host-name)", "$(node-name)", "$(pod-uid)"]
some allowed in always_allowed
contains(p_name_value[1], allowed)
print("allow_var 5: true")
}
# Allow fieldRef "fieldPath: status.hostIP" values.
allow_var(p_process, i_process, i_var, s_name) {
name_value := split(i_var, "=")
count(name_value) == 2
is_ip(name_value[1])
some p_var in p_process.Env
allow_host_ip_var(name_value[0], p_var)
print("allow_var 6: true")
}
# Allow resourceFieldRef values (e.g., "limits.cpu").
allow_var(p_process, i_process, i_var, s_name) {
name_value := split(i_var, "=")
count(name_value) == 2
some p_var in p_process.Env
p_name_value := split(p_var, "=")
count(p_name_value) == 2
p_name_value[0] == name_value[0]
# TODO: should these be handled in a different way?
always_allowed = ["$(resource-field)", "$(todo-annotation)"]
some allowed in always_allowed
contains(p_name_value[1], allowed)
print("allow_var 7: true")
}
allow_pod_ip_var(var_name, p_var) {
print("allow_pod_ip_var: var_name =", var_name, "p_var =", p_var)
p_name_value := split(p_var, "=")
count(p_name_value) == 2
p_name_value[0] == var_name
p_name_value[1] == "$(pod-ip)"
print("allow_pod_ip_var: true")
}
allow_host_ip_var(var_name, p_var) {
print("allow_host_ip_var: var_name =", var_name, "p_var =", p_var)
p_name_value := split(p_var, "=")
count(p_name_value) == 2
p_name_value[0] == var_name
p_name_value[1] == "$(host-ip)"
print("allow_host_ip_var: true")
}
is_ip(value) {
bytes = split(value, ".")
count(bytes) == 4
is_ip_first_byte(bytes[0])
is_ip_other_byte(bytes[1])
is_ip_other_byte(bytes[2])
is_ip_other_byte(bytes[3])
}
is_ip_first_byte(component) {
number = to_number(component)
number >= 1
number <= 255
}
is_ip_other_byte(component) {
number = to_number(component)
number >= 0
number <= 255
}
# OCI root.Path
allow_root_path(p_oci, i_oci, bundle_id) {
i_path := i_oci.Root.Path
p_path1 := p_oci.Root.Path
print("allow_root_path: i_path =", i_path, "p_path1 =", p_path1)
p_path2 := replace(p_path1, "$(cpath)", policy_data.common.cpath)
print("allow_root_path: p_path2 =", p_path2)
p_path3 := replace(p_path2, "$(bundle-id)", bundle_id)
print("allow_root_path: p_path3 =", p_path3)
p_path3 == i_path
print("allow_root_path: true")
}
# device mounts
allow_mount(p_oci, i_mount, bundle_id, sandbox_id) {
print("allow_mount: i_mount =", i_mount)
some p_mount in p_oci.Mounts
print("allow_mount: p_mount =", p_mount)
check_mount(p_mount, i_mount, bundle_id, sandbox_id)
# TODO: are there any other required policy checks for mounts - e.g.,
# multiple mounts with same source or destination?
print("allow_mount: true")
}
check_mount(p_mount, i_mount, bundle_id, sandbox_id) {
p_mount == i_mount
print("check_mount 1: true")
}
check_mount(p_mount, i_mount, bundle_id, sandbox_id) {
p_mount.destination == i_mount.destination
p_mount.type_ == i_mount.type_
p_mount.options == i_mount.options
mount_source_allows(p_mount, i_mount, bundle_id, sandbox_id)
print("check_mount 2: true")
}
mount_source_allows(p_mount, i_mount, bundle_id, sandbox_id) {
regex1 := p_mount.source
regex2 := replace(regex1, "$(sfprefix)", policy_data.common.sfprefix)
regex3 := replace(regex2, "$(cpath)", policy_data.common.cpath)
regex4 := replace(regex3, "$(bundle-id)", bundle_id)
print("mount_source_allows 1: regex4 =", regex4)
regex.match(regex4, i_mount.source)
print("mount_source_allows 1: true")
}
mount_source_allows(p_mount, i_mount, bundle_id, sandbox_id) {
regex1 := p_mount.source
regex2 := replace(regex1, "$(sfprefix)", policy_data.common.sfprefix)
regex3 := replace(regex2, "$(cpath)", policy_data.common.cpath)
regex4 := replace(regex3, "$(sandbox-id)", sandbox_id)
print("mount_source_allows 2: regex4 =", regex4)
regex.match(regex4, i_mount.source)
print("mount_source_allows 2: true")
}
mount_source_allows(p_mount, i_mount, bundle_id, sandbox_id) {
print("mount_source_allows 3: i_mount.source=", i_mount.source)
i_source_parts = split(i_mount.source, "/")
b64_direct_vol_path = i_source_parts[count(i_source_parts) - 1]
base64.is_valid(b64_direct_vol_path)
source1 := p_mount.source
print("mount_source_allows 3: source1 =", source1)
source2 := replace(source1, "$(spath)", policy_data.common.spath)
print("mount_source_allows 3: source2 =", source2)
source3 := replace(source2, "$(b64-direct-vol-path)", b64_direct_vol_path)
print("mount_source_allows 3: source3 =", source3)
source3 == i_mount.source
print("mount_source_allows 3: true")
}
######################################################################
# Create container Storages
allow_storages(p_storages, i_storages, bundle_id, sandbox_id) {
p_count := count(p_storages)
i_count := count(i_storages)
print("allow_storages: p_count =", p_count, "i_count =", i_count)
p_count == i_count
# Get the container image layer IDs and verity root hashes, from the "overlayfs" storage.
some overlay_storage in p_storages
overlay_storage.driver == "overlayfs"
print("allow_storages: overlay_storage =", overlay_storage)
count(overlay_storage.options) == 2
layer_ids := split(overlay_storage.options[0], ":")
print("allow_storages: layer_ids =", layer_ids)
root_hashes := split(overlay_storage.options[1], ":")
print("allow_storages: root_hashes =", root_hashes)
every i_storage in i_storages {
allow_storage(p_storages, i_storage, bundle_id, sandbox_id, layer_ids, root_hashes)
}
print("allow_storages: true")
}
allow_storage(p_storages, i_storage, bundle_id, sandbox_id, layer_ids, root_hashes) {
some p_storage in p_storages
print("allow_storage: p_storage =", p_storage)
print("allow_storage: i_storage =", i_storage)
p_storage.driver == i_storage.driver
p_storage.driver_options == i_storage.driver_options
p_storage.fs_group == i_storage.fs_group
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes)
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids)
# TODO: validate the source field too.
print("allow_storage: true")
}
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes) {
print("allow_storage_options 1: start")
p_storage.driver != "overlayfs"
p_storage.options == i_storage.options
print("allow_storage_options 1: true")
}
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes) {
print("allow_storage_options 2: start")
p_storage.driver == "overlayfs"
count(p_storage.options) == 2
policy_ids := split(p_storage.options[0], ":")
print("allow_storage_options 2: policy_ids =", policy_ids)
policy_ids == layer_ids
policy_hashes := split(p_storage.options[1], ":")
print("allow_storage_options 2: policy_hashes =", policy_hashes)
p_count := count(policy_ids)
print("allow_storage_options 2: p_count =", p_count)
p_count >= 1
p_count == count(policy_hashes)
i_count := count(i_storage.options)
print("allow_storage_options 2: i_count =", i_count)
i_count == p_count + 3
print("allow_storage_options 2: i_storage.options[0] =", i_storage.options[0])
i_storage.options[0] == "io.katacontainers.fs-opt.layer-src-prefix=/var/lib/containerd/io.containerd.snapshotter.v1.tardev/layers"
print("allow_storage_options 2: i_storage.options[i_count - 2] =", i_storage.options[i_count - 2])
i_storage.options[i_count - 2] == "io.katacontainers.fs-opt.overlay-rw"
lowerdir := concat("=", ["lowerdir", p_storage.options[0]])
print("allow_storage_options 2: lowerdir =", lowerdir)
print("allow_storage_options 2: i_storage.options[i_count - 1] =", i_storage.options[i_count - 1])
i_storage.options[i_count - 1] == lowerdir
every i, policy_id in policy_ids {
allow_overlay_layer(policy_id, policy_hashes[i], i_storage.options[i + 1])
}
print("allow_storage_options 2: true")
}
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes) {
print("allow_storage_options 3: start")
p_storage.driver == "blk"
count(p_storage.options) == 1
startswith(p_storage.options[0], "$(hash")
hash_suffix := trim_left(p_storage.options[0], "$(hash")
endswith(hash_suffix, ")")
hash_index := trim_right(hash_suffix, ")")
i := to_number(hash_index)
print("allow_storage_options 3: i =", i)
hash_option := concat("=", ["io.katacontainers.fs-opt.root-hash", root_hashes[i]])
print("allow_storage_options 3: hash_option =", hash_option)
count(i_storage.options) == 4
i_storage.options[0] == "ro"
i_storage.options[1] == "io.katacontainers.fs-opt.block_device=file"
i_storage.options[2] == "io.katacontainers.fs-opt.is-layer"
i_storage.options[3] == hash_option
print("allow_storage_options 3: true")
}
allow_storage_options(p_storage, i_storage, layer_ids, root_hashes) {
print("allow_storage_options 4: start")
p_storage.driver == "smb"
count(i_storage.options) == 8
i_storage.options[0] == "dir_mode=0666"
i_storage.options[1] == "file_mode=0666"
i_storage.options[2] == "mfsymlinks"
i_storage.options[3] == "cache=strict"
i_storage.options[4] == "nosharesock"
i_storage.options[5] == "actimeo=30"
startswith(i_storage.options[6], "addr=")
creds = split(i_storage.options[7], ",")
count(creds) == 2
startswith(creds[0], "username=")
startswith(creds[1], "password=")
print("allow_storage_options 4: true")
}
allow_overlay_layer(policy_id, policy_hash, i_option) {
print("allow_overlay_layer: policy_id =", policy_id, "policy_hash =", policy_hash)
print("allow_overlay_layer: i_option =", i_option)
startswith(i_option, "io.katacontainers.fs-opt.layer=")
i_value := replace(i_option, "io.katacontainers.fs-opt.layer=", "")
i_value_decoded := base64.decode(i_value)
print("allow_overlay_layer: i_value_decoded =", i_value_decoded)
policy_suffix := concat("=", ["tar,ro,io.katacontainers.fs-opt.block_device=file,io.katacontainers.fs-opt.is-layer,io.katacontainers.fs-opt.root-hash", policy_hash])
p_value := concat(",", [policy_id, policy_suffix])
print("allow_overlay_layer: p_value =", p_value)
p_value == i_value_decoded
print("allow_overlay_layer: true")
}
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids) {
p_storage.fstype == "tar"
startswith(p_storage.mount_point, "$(layer")
mount_suffix := trim_left(p_storage.mount_point, "$(layer")
endswith(mount_suffix, ")")
layer_index := trim_right(mount_suffix, ")")
i := to_number(layer_index)
print("allow_mount_point 1: i =", i)
layer_id := layer_ids[i]
print("allow_mount_point 1: layer_id =", layer_id)
p_mount := concat("/", ["/run/kata-containers/sandbox/layers", layer_id])
print("allow_mount_point 1: p_mount =", p_mount)
p_mount == i_storage.mount_point
print("allow_mount_point 1: true")
}
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids) {
p_storage.fstype == "fuse3.kata-overlay"
mount1 := replace(p_storage.mount_point, "$(cpath)", policy_data.common.cpath)
mount2 := replace(mount1, "$(bundle-id)", bundle_id)
print("allow_mount_point 2: mount2 =", mount2)
mount2 == i_storage.mount_point
print("allow_mount_point 2: true")
}
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids) {
p_storage.fstype == "local"
mount1 := p_storage.mount_point
print("allow_mount_point 3: mount1 =", mount1)
mount2 := replace(mount1, "$(cpath)", policy_data.common.cpath)
print("allow_mount_point 3: mount2 =", mount2)
mount3 := replace(mount2, "$(sandbox-id)", sandbox_id)
print("allow_mount_point 3: mount3 =", mount3)
regex.match(mount3, i_storage.mount_point)
print("allow_mount_point 3: true")
}
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids) {
p_storage.fstype == "bind"
mount1 := p_storage.mount_point
print("allow_mount_point 4: mount1 =", mount1)
mount2 := replace(mount1, "$(cpath)", policy_data.common.cpath)
print("allow_mount_point 4: mount2 =", mount2)
mount3 := replace(mount2, "$(bundle-id)", bundle_id)
print("allow_mount_point 4: mount3 =", mount3)
regex.match(mount3, i_storage.mount_point)
print("allow_mount_point 4: true")
}
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids) {
p_storage.fstype == "tmpfs"
mount1 := p_storage.mount_point
print("allow_mount_point 5: mount1 =", mount1)
regex.match(mount1, i_storage.mount_point)
print("allow_mount_point 5: true")
}
allow_mount_point(p_storage, i_storage, bundle_id, sandbox_id, layer_ids) {
print("allow_mount_point 6: i_storage.mount_point =", i_storage.mount_point)
allow_direct_vol_driver(p_storage, i_storage)
mount1 := p_storage.mount_point
print("allow_mount_point 6: mount1 =", mount1)
mount2 := replace(mount1, "$(spath)", policy_data.common.spath)
print("allow_mount_point 6: mount2 =", mount2)
direct_vol_path := i_storage.source
mount3 := replace(mount2, "$(b64-direct-vol-path)", base64url.encode(direct_vol_path))
print("allow_mount_point 6: mount3 =", mount3)
mount3 == i_storage.mount_point
print("allow_mount_point 6: true")
}
allow_direct_vol_driver(p_storage, i_storage) {
print("allow_direct_vol_driver 1: start")
p_storage.driver == "blk"
print("allow_direct_vol_driver 1: true")
}
allow_direct_vol_driver(p_storage, i_storage) {
print("allow_direct_vol_driver 2: start")
p_storage.driver == "smb"
print("allow_direct_vol_driver 2: true")
}
# process.Capabilities
allow_caps(p_caps, i_caps) {
print("allow_caps: policy Ambient =", p_caps.Ambient)
print("allow_caps: input Ambient =", i_caps.Ambient)
match_caps(p_caps.Ambient, i_caps.Ambient)
print("allow_caps: policy Bounding =", p_caps.Bounding)
print("allow_caps: input Bounding =", i_caps.Bounding)
match_caps(p_caps.Bounding, i_caps.Bounding)
print("allow_caps: policy Effective =", p_caps.Effective)
print("allow_caps: input Effective =", i_caps.Effective)
match_caps(p_caps.Effective, i_caps.Effective)
print("allow_caps: policy Inheritable =", p_caps.Inheritable)
print("allow_caps: input Inheritable =", i_caps.Inheritable)
match_caps(p_caps.Inheritable, i_caps.Inheritable)
print("allow_caps: policy Permitted =", p_caps.Permitted)
print("allow_caps: input Permitted =", i_caps.Permitted)
match_caps(p_caps.Permitted, i_caps.Permitted)
}
match_caps(p_caps, i_caps) {
print("match_caps 1: start")
p_caps == i_caps
print("match_caps 1: true")
}
match_caps(p_caps, i_caps) {
print("match_caps 2: start")
count(p_caps) == 1
p_caps[0] == "$(default_caps)"
print("match_caps 2: default_caps =", policy_data.common.default_caps)
policy_data.common.default_caps == i_caps
print("match_caps 2: true")
}
match_caps(p_caps, i_caps) {
print("match_caps 3: start")
count(p_caps) == 1
p_caps[0] == "$(privileged_caps)"
print("match_caps 3: privileged_caps =", policy_data.common.privileged_caps)
policy_data.common.privileged_caps == i_caps
print("match_caps 3: true")
}
######################################################################
check_directory_traversal(i_path) {
contains(i_path, "../") == false
endswith(i_path, "/..") == false
i_path != ".."
}
check_symlink_source {
# TODO: delete this rule once the symlink_src field gets implemented
# by all/most Guest VMs.
not input.symlink_src
}
check_symlink_source {
i_src := input.symlink_src
print("check_symlink_source: i_src =", i_src)
startswith(i_src, "/") == false
check_directory_traversal(i_src)
}
allow_sandbox_storages(i_storages) {
print("allow_sandbox_storages: i_storages =", i_storages)
p_storages := policy_data.sandbox.storages
every i_storage in i_storages {
allow_sandbox_storage(p_storages, i_storage)
}
print("allow_sandbox_storages: true")
}
allow_sandbox_storage(p_storages, i_storage) {
print("allow_sandbox_storage: i_storage =", i_storage)
some p_storage in p_storages
print("allow_sandbox_storage: p_storage =", p_storage)
i_storage == p_storage
print("allow_sandbox_storage: true")
}
CopyFileRequest {
print("CopyFileRequest: input.path =", input.path)
check_symlink_source
check_directory_traversal(input.path)
some regex1 in policy_data.request_defaults.CopyFileRequest
regex2 := replace(regex1, "$(sfprefix)", policy_data.common.sfprefix)
regex3 := replace(regex2, "$(cpath)", policy_data.common.cpath)
regex4 := replace(regex3, "$(bundle-id)", "[a-z0-9]{64}")
print("CopyFileRequest: regex4 =", regex4)
regex.match(regex4, input.path)
print("CopyFileRequest: true")
}
CreateSandboxRequest {
print("CreateSandboxRequest: input.guest_hook_path =", input.guest_hook_path)
count(input.guest_hook_path) == 0
print("CreateSandboxRequest: input.kernel_modules =", input.kernel_modules)
count(input.kernel_modules) == 0
i_pidns := input.sandbox_pidns
print("CreateSandboxRequest: i_pidns =", i_pidns)
i_pidns == false
allow_sandbox_storages(input.storages)
}
ExecProcessRequest {
print("ExecProcessRequest 1: input =", input)
i_command = concat(" ", input.process.Args)
print("ExecProcessRequest 1: i_command =", i_command)
some p_command in policy_data.request_defaults.ExecProcessRequest.commands
print("ExecProcessRequest 1: p_command =", p_command)
p_command == i_command
print("ExecProcessRequest 1: true")
}
ExecProcessRequest {
print("ExecProcessRequest 2: input =", input)
# TODO: match input container ID with its corresponding container.exec_commands.
i_command = concat(" ", input.process.Args)
print("ExecProcessRequest 3: i_command =", i_command)
some container in policy_data.containers
some p_command in container.exec_commands
print("ExecProcessRequest 2: p_command =", p_command)
# TODO: should other input data fields be validated as well?
p_command == i_command
print("ExecProcessRequest 2: true")
}
ExecProcessRequest {
print("ExecProcessRequest 3: input =", input)
i_command = concat(" ", input.process.Args)
print("ExecProcessRequest 3: i_command =", i_command)
some p_regex in policy_data.request_defaults.ExecProcessRequest.regex
print("ExecProcessRequest 3: p_regex =", p_regex)
regex.match(p_regex, i_command)
print("ExecProcessRequest 3: true")
}
CloseStdinRequest {
policy_data.request_defaults.CloseStdinRequest == true
}
ReadStreamRequest {
policy_data.request_defaults.ReadStreamRequest == true
}
UpdateEphemeralMountsRequest {
policy_data.request_defaults.UpdateEphemeralMountsRequest == true
}
WriteStreamRequest {
policy_data.request_defaults.WriteStreamRequest == true
}
policy_data := {
"containers": [
{
"OCI": {
"Version": "1.1.0-rc.1",
"Process": {
"Terminal": false,
"User": {
"UID": 65535,
"GID": 65535,
"AdditionalGids": [],
"Username": ""
},
"Args": [
"/pause"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cwd": "/",
"Capabilities": {
"Ambient": [],
"Bounding": [
"$(default_caps)"
],
"Effective": [
"$(default_caps)"
],
"Inheritable": [],
"Permitted": [
"$(default_caps)"
]
},
"NoNewPrivileges": true
},
"Root": {
"Path": "$(cpath)/$(bundle-id)",
"Readonly": true
},
"Mounts": [
{
"destination": "/proc",
"source": "proc",
"type_": "proc",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/dev",
"source": "tmpfs",
"type_": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"source": "devpts",
"type_": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"source": "/run/kata-containers/sandbox/shm",
"type_": "bind",
"options": [
"rbind"
]
},
{
"destination": "/dev/mqueue",
"source": "mqueue",
"type_": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"source": "sysfs",
"type_": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
},
{
"destination": "/etc/resolv.conf",
"source": "$(sfprefix)resolv.conf$",
"type_": "bind",
"options": [
"rbind",
"ro",
"nosuid",
"nodev",
"noexec"
]
}
],
"Annotations": {
"io.katacontainers.pkg.oci.bundle_path": "/run/containerd/io.containerd.runtime.v2.task/k8s.io/$(bundle-id)",
"io.katacontainers.pkg.oci.container_type": "pod_sandbox",
"io.kubernetes.cri.container-type": "sandbox",
"io.kubernetes.cri.sandbox-id": "^[a-z0-9]{64}$",
"io.kubernetes.cri.sandbox-log-directory": "^/var/log/pods/$(sandbox-namespace)_$(sandbox-name)_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
"io.kubernetes.cri.sandbox-namespace": "default",
"nerdctl/network-namespace": "^/var/run/netns/cni-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"Linux": {
"Namespaces": [
{
"Type": "ipc",
"Path": ""
},
{
"Type": "uts",
"Path": ""
},
{
"Type": "mount",
"Path": ""
}
],
"MaskedPaths": [
"/proc/acpi",
"/proc/asound",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/sys/firmware",
"/proc/scsi"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
}
},
"storages": [
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash0)"
],
"mount_point": "$(layer0)",
"fs_group": null
},
{
"driver": "overlayfs",
"driver_options": [],
"source": "",
"fstype": "fuse3.kata-overlay",
"options": [
"5a5aad80055ff20012a50dc25f8df7a29924474324d65f7d5306ee8ee27ff71d",
"817250f1a3e336da76f5bd3fa784e1b26d959b9c131876815ba2604048b70c18"
],
"mount_point": "$(cpath)/$(bundle-id)",
"fs_group": null
}
],
"sandbox_pidns": false,
"exec_commands": []
},
{
"OCI": {
"Version": "1.1.0-rc.1",
"Process": {
"Terminal": false,
"User": {
"UID": 0,
"GID": 0,
"AdditionalGids": [],
"Username": ""
},
"Args": [
"/bin/sh",
"-c",
"while true; do echo $(sandbox-name); sleep 10; done"
],
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"HOSTNAME=$(host-name)",
"META_NAME=$(sandbox-name)"
],
"Cwd": "/",
"Capabilities": {
"Ambient": [],
"Bounding": [
"$(default_caps)"
],
"Effective": [
"$(default_caps)"
],
"Inheritable": [],
"Permitted": [
"$(default_caps)"
]
},
"NoNewPrivileges": false
},
"Root": {
"Path": "$(cpath)/$(bundle-id)",
"Readonly": false
},
"Mounts": [
{
"destination": "/proc",
"source": "proc",
"type_": "proc",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/dev",
"source": "tmpfs",
"type_": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"source": "devpts",
"type_": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"source": "/run/kata-containers/sandbox/shm",
"type_": "bind",
"options": [
"rbind"
]
},
{
"destination": "/dev/mqueue",
"source": "mqueue",
"type_": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"source": "sysfs",
"type_": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
},
{
"destination": "/sys/fs/cgroup",
"source": "cgroup",
"type_": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
},
{
"destination": "/etc/hosts",
"source": "$(sfprefix)hosts$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"rw"
]
},
{
"destination": "/dev/termination-log",
"source": "$(sfprefix)termination-log$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"rw"
]
},
{
"destination": "/etc/hostname",
"source": "$(sfprefix)hostname$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"rw"
]
},
{
"destination": "/etc/resolv.conf",
"source": "$(sfprefix)resolv.conf$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"rw"
]
},
{
"destination": "/var/run/secrets/kubernetes.io/serviceaccount",
"source": "$(sfprefix)serviceaccount$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"ro"
]
},
{
"destination": "/var/run/secrets/azure/tokens",
"source": "$(sfprefix)tokens$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"ro"
]
},
{
"destination": "/usr/share/nginx/html",
"source": "^/run/kata-containers/shared/containers/$(bundle-id)-[a-z0-9]{16}-html$",
"type_": "bind",
"options": [
"rbind",
"rprivate",
"rw"
]
}
],
"Annotations": {
"io.katacontainers.pkg.oci.bundle_path": "/run/containerd/io.containerd.runtime.v2.task/k8s.io/$(bundle-id)",
"io.katacontainers.pkg.oci.container_type": "pod_container",
"io.kubernetes.cri.container-name": "nginx",
"io.kubernetes.cri.container-type": "container",
"io.kubernetes.cri.image-name": "mcr.microsoft.com/cbl-mariner/base/nginx:1.22.1-9-cm2.0.20230904-amd64",
"io.kubernetes.cri.sandbox-id": "^[a-z0-9]{64}$",
"io.kubernetes.cri.sandbox-namespace": "default"
},
"Linux": {
"Namespaces": [
{
"Type": "ipc",
"Path": ""
},
{
"Type": "uts",
"Path": ""
},
{
"Type": "mount",
"Path": ""
}
],
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
}
},
"storages": [
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash0)"
],
"mount_point": "$(layer0)",
"fs_group": null
},
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash1)"
],
"mount_point": "$(layer1)",
"fs_group": null
},
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash2)"
],
"mount_point": "$(layer2)",
"fs_group": null
},
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash3)"
],
"mount_point": "$(layer3)",
"fs_group": null
},
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash4)"
],
"mount_point": "$(layer4)",
"fs_group": null
},
{
"driver": "blk",
"driver_options": [],
"source": "",
"fstype": "tar",
"options": [
"$(hash5)"
],
"mount_point": "$(layer5)",
"fs_group": null
},
{
"driver": "overlayfs",
"driver_options": [],
"source": "",
"fstype": "fuse3.kata-overlay",
"options": [
"1b27bec068016fce230a3c9f4920d3be7251e5baada7dca3204a932cbcde27e2:c8295c80a79c2ed76e03ddb2af390ac3791b8779da798cb183fa985ce5cee1dc:cfb9fe97a1869ee9b0daae3d8cd59720cf371da568a6c14bba16d982e7092983:14f395647869a88f90a33eef50c97e82f4b981b6e20a584d51bf304967b8542c:fc7dd8614820bbafe5b6b6645e19945b4af989b662c989fd46c465fafca702f7:8d311e8e51984cabaccec1fbfcbcdd7bf52a8a978169cd20af07bbd1c3a4692a",
"073dba7831293107f8873eedabf4922d16a506086f6f46b19b4c2386831c3106:ed0feae4f4dccb686628963b1f1f5dae7b3e015c881e72f005ff2f99c649457e:d138152b660d2dbcc5082afae58edb1bf0ee5742b91933a2f61664b847b23281:1d69eaf5c5c25731e9a8ebb038c942f6aa6aff5b15b11d8bd44431e514ccd69f:1eb4bff8040a86c514815a039f6cb4d7aa4c5f1b7a2e1a45f6f86ca8c770ffff:e928fff98ddea2d26dbba075605770bd6f6ef068c975289b49acb3d55030d071"
],
"mount_point": "$(cpath)/$(bundle-id)",
"fs_group": null
}
],
"sandbox_pidns": false,
"exec_commands": []
}
],
"common": {
"cpath": "/run/kata-containers/shared/containers",
"sfprefix": "^$(cpath)/$(bundle-id)-[a-z0-9]{16}-",
"spath": "/run/kata-containers/sandbox/storage",
"ipv4_a": "((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}",
"ip_p": "[0-9]{1,5}",
"svc_name": "[A-Z0-9_\\.\\-]+",
"dns_label": "[a-zA-Z0-9_\\.\\-]+",
"default_caps": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"privileged_caps": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_DAC_READ_SEARCH",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETPCAP",
"CAP_LINUX_IMMUTABLE",
"CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST",
"CAP_NET_ADMIN",
"CAP_NET_RAW",
"CAP_IPC_LOCK",
"CAP_IPC_OWNER",
"CAP_SYS_MODULE",
"CAP_SYS_RAWIO",
"CAP_SYS_CHROOT",
"CAP_SYS_PTRACE",
"CAP_SYS_PACCT",
"CAP_SYS_ADMIN",
"CAP_SYS_BOOT",
"CAP_SYS_NICE",
"CAP_SYS_RESOURCE",
"CAP_SYS_TIME",
"CAP_SYS_TTY_CONFIG",
"CAP_MKNOD",
"CAP_LEASE",
"CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL",
"CAP_SETFCAP",
"CAP_MAC_OVERRIDE",
"CAP_MAC_ADMIN",
"CAP_SYSLOG",
"CAP_WAKE_ALARM",
"CAP_BLOCK_SUSPEND",
"CAP_AUDIT_READ",
"CAP_PERFMON",
"CAP_BPF",
"CAP_CHECKPOINT_RESTORE"
],
"virtio_blk_storage_classes": [
"cc-local-csi",
"cc-managed-csi",
"cc-managed-premium-csi"
],
"smb_storage_classes": [
"cc-azurefile-csi",
"cc-azurefile-premium-csi"
]
},
"sandbox": {
"storages": [
{
"driver": "ephemeral",
"driver_options": [],
"source": "shm",
"fstype": "tmpfs",
"options": [
"noexec",
"nosuid",
"nodev",
"mode=1777",
"size=67108864"
],
"mount_point": "/run/kata-containers/sandbox/shm",
"fs_group": null
}
]
},
"request_defaults": {
"CreateContainerRequest": {
"allow_env_regex": [
"^HOSTNAME=$(dns_label)$",
"^$(svc_name)_PORT_$(ip_p)_TCP=tcp://$(ipv4_a):$(ip_p)$",
"^$(svc_name)_PORT_$(ip_p)_TCP_PROTO=tcp$",
"^$(svc_name)_PORT_$(ip_p)_TCP_PORT=$(ip_p)$",
"^$(svc_name)_PORT_$(ip_p)_TCP_ADDR=$(ipv4_a)$",
"^$(svc_name)_SERVICE_HOST=$(ipv4_a)$",
"^$(svc_name)_SERVICE_PORT=$(ip_p)$",
"^$(svc_name)_SERVICE_PORT_$(dns_label)=$(ip_p)$",
"^$(svc_name)_PORT=tcp://$(ipv4_a):$(ip_p)$",
"^AZURE_CLIENT_ID=[A-Fa-f0-9-]*$",
"^AZURE_TENANT_ID=[A-Fa-f0-9-]*$",
"^AZURE_FEDERATED_TOKEN_FILE=/var/run/secrets/azure/tokens/azure-identity-token$",
"^AZURE_AUTHORITY_HOST=https://login\\.microsoftonline\\.com/$"
]
},
"CopyFileRequest": [
"$(sfprefix)"
],
"ExecProcessRequest": {
"commands": [],
"regex": []
},
"CloseStdinRequest": false,
"ReadStreamRequest": true,
"UpdateEphemeralMountsRequest": false,
"WriteStreamRequest": false
}
}