Skip to content

Commit

Permalink
Merge pull request #295 from microsoft/saulparedes/validate_namespace…
Browse files Browse the repository at this point in the history
…_env_var

Saulparedes/validate namespace env var
  • Loading branch information
Redent0r authored Jan 17, 2025
2 parents 02add57 + a3f20ba commit 6058c26
Show file tree
Hide file tree
Showing 64 changed files with 117 additions and 87 deletions.
2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/configmap/pod-cm1.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/configmap/pod-cm2.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/configmap/pod-cm3.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/cron-job/test-cron-job.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/job/test-job.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/job/test-job2.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/kubernetes/fixtures/job.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-exec.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-lifecycle.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-many-layers.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-one-container.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-same-containers.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-spark.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/pod/pod-ubuntu.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/replica-set/replica2.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/stateful-set/web.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/stateful-set/web2.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod1.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod2.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod3.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod4.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod5.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod6.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook/webhook-pod7.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook2/webhook-pod10.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook2/webhook-pod11.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook2/webhook-pod12.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook2/webhook-pod13.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook2/webhook-pod8.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook2/webhook-pod9.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook3/dns-test.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/agent/samples/policy/yaml/webhook3/many-layers.yaml

Large diffs are not rendered by default.

70 changes: 47 additions & 23 deletions src/tools/genpolicy/rules.rego
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ get_state() = state {
state := data["pstate"]
}

get_state_val(key) = value {
state := get_state()
value := state[key]
}

get_state_path(key) = path {
# prepend "/pstate/" to key
path := concat("/", ["/pstate", key])
Expand Down Expand Up @@ -239,7 +244,10 @@ allow_by_anno(p_oci, i_oci, p_storages, i_storages) {
i_s_name := i_oci.Annotations[S_NAME_KEY]
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)
i_s_namespace := i_oci.Annotations[S_NAMESPACE_KEY]
print("allow_by_anno 1: i_s_namespace =", i_s_namespace)

allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, i_s_name, i_s_namespace)

print("allow_by_anno 1: true")
}
Expand All @@ -251,19 +259,23 @@ allow_by_anno(p_oci, i_oci, p_storages, i_storages) {
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)

i_s_namespace := i_oci.Annotations[S_NAMESPACE_KEY]
print("allow_by_anno 2: i_s_namespace =", i_s_namespace)

allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, i_s_name, i_s_namespace)

print("allow_by_anno 2: true")
}

allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, s_name) {
allow_by_sandbox_name(p_oci, i_oci, p_storages, i_storages, s_name, s_namespace) {
print("allow_by_sandbox_name: start")

i_namespace := i_oci.Annotations[S_NAMESPACE_KEY]

allow_by_container_types(p_oci, i_oci, s_name, i_namespace)
allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages)
allow_process(p_oci.Process, i_oci.Process, s_name)
allow_process(p_oci.Process, i_oci.Process, s_name, s_namespace)

print("allow_by_sandbox_name: true")
}
Expand Down Expand Up @@ -557,7 +569,7 @@ allow_by_bundle_or_sandbox_id(p_oci, i_oci, p_storages, i_storages) {
print("allow_by_bundle_or_sandbox_id: true")
}

allow_process_common(p_process, i_process, s_name) {
allow_process_common(p_process, i_process, s_name, s_namespace) {
print("allow_process_common: p_process =", p_process)
print("allow_process_common: i_process = ", i_process)
print("allow_process_common: s_name =", s_name)
Expand All @@ -566,28 +578,28 @@ allow_process_common(p_process, i_process, s_name) {
p_process.NoNewPrivileges == i_process.NoNewPrivileges

allow_user(p_process, i_process)
allow_env(p_process, i_process, s_name)
allow_env(p_process, i_process, s_name, s_namespace)

print("allow_process_common: true")
}

# Compare the OCI Process field of a policy container with the input OCI Process from a CreateContainerRequest
allow_process(p_process, i_process, s_name) {
allow_process(p_process, i_process, s_name, s_namespace) {
print("allow_process: start")

allow_args(p_process, i_process, s_name)
allow_process_common(p_process, i_process, s_name)
allow_process_common(p_process, i_process, s_name, s_namespace)
allow_caps(p_process.Capabilities, i_process.Capabilities)
p_process.Terminal == i_process.Terminal

print("allow_process: true")
}

# Compare the OCI Process field of a policy container with the input process field from ExecProcessRequest
allow_interactive_process(p_process, i_process, s_name) {
allow_interactive_process(p_process, i_process, s_name, s_namespace) {
print("allow_interactive_process: start")

allow_process_common(p_process, i_process, s_name)
allow_process_common(p_process, i_process, s_name, s_namespace)
allow_exec_caps(i_process.Capabilities)

# These are commands enabled using ExecProcessRequest commands and/or regex from the settings file.
Expand All @@ -597,10 +609,10 @@ allow_interactive_process(p_process, i_process, s_name) {
}

# Compare the OCI Process field of a policy container with the input process field from ExecProcessRequest
allow_probe_process(p_process, i_process, s_name) {
allow_probe_process(p_process, i_process, s_name, s_namespace) {
print("allow_probe_process: start")

allow_process_common(p_process, i_process, s_name)
allow_process_common(p_process, i_process, s_name, s_namespace)
allow_exec_caps(i_process.Capabilities)
p_process.Terminal == i_process.Terminal

Expand Down Expand Up @@ -675,27 +687,27 @@ allow_arg(i, i_arg, p_process, s_name) {
}

# OCI process.Env field
allow_env(p_process, i_process, s_name) {
allow_env(p_process, i_process, s_name, s_namespace) {
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)
allow_var(p_process, i_process, i_var, s_name, s_namespace)
}

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) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
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) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
some p_var in p_process.Env
p_var2 := replace(p_var, "$(sandbox-name)", s_name)

Expand All @@ -706,7 +718,7 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow input env variables that match with a request_defaults regex.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
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)
Expand All @@ -720,7 +732,7 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow fieldRef "fieldPath: status.podIP" values.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
name_value := split(i_var, "=")
count(name_value) == 2
is_ip(name_value[1])
Expand All @@ -732,7 +744,7 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow common fieldRef variables.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
name_value := split(i_var, "=")
count(name_value) == 2

Expand All @@ -751,7 +763,7 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow fieldRef "fieldPath: status.hostIP" values.
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
name_value := split(i_var, "=")
count(name_value) == 2
is_ip(name_value[1])
Expand All @@ -763,7 +775,7 @@ allow_var(p_process, i_process, i_var, s_name) {
}

# Allow resourceFieldRef values (e.g., "limits.cpu").
allow_var(p_process, i_process, i_var, s_name) {
allow_var(p_process, i_process, i_var, s_name, s_namespace) {
name_value := split(i_var, "=")
count(name_value) == 2

Expand All @@ -781,6 +793,16 @@ allow_var(p_process, i_process, i_var, s_name) {
print("allow_var 7: true")
}

allow_var(p_process, i_process, i_var, s_name, s_namespace) {
some p_var in p_process.Env
p_var2 := replace(p_var, "$(sandbox-namespace)", s_namespace)

print("allow_var 8: p_var2 =", p_var2)
p_var2 == i_var

print("allow_var 8: true")
}

allow_pod_ip_var(var_name, p_var) {
print("allow_pod_ip_var: var_name =", var_name, "p_var =", p_var)

Expand Down Expand Up @@ -1323,7 +1345,8 @@ allow_exec(p_container, i_process) {

p_oci = p_container.OCI
p_s_name = p_oci.Annotations[S_NAME_KEY]
allow_probe_process(p_oci.Process, i_process, p_s_name)
s_namespace = get_state_val("namespace")
allow_probe_process(p_oci.Process, i_process, p_s_name, s_namespace)

print("allow_exec: true")
}
Expand All @@ -1333,7 +1356,8 @@ allow_interactive_exec(p_container, i_process) {

p_oci = p_container.OCI
p_s_name = p_oci.Annotations[S_NAME_KEY]
allow_interactive_process(p_oci.Process, i_process, p_s_name)
s_namespace = get_state_val("namespace")
allow_interactive_process(p_oci.Process, i_process, p_s_name, s_namespace)

print("allow_interactive_exec: true")
}
Expand Down
8 changes: 7 additions & 1 deletion src/tools/genpolicy/src/pod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,13 @@ impl EnvVar {
let path: &str = &field_ref.fieldPath;
match path {
"metadata.name" => return "$(sandbox-name)".to_string(),
"metadata.namespace" => return namespace.to_string(),
"metadata.namespace" => {
return if namespace.is_empty() {
"$(sandbox-namespace)".to_string()
} else {
namespace.to_string()
};
}
"metadata.uid" => return "$(pod-uid)".to_string(),
"status.hostIP" => return "$(host-ip)".to_string(),
"status.podIP" => return "$(pod-ip)".to_string(),
Expand Down

0 comments on commit 6058c26

Please sign in to comment.