From fe9894518ccb3430e6bf593b75a2a6fcdc52ab19 Mon Sep 17 00:00:00 2001 From: John Krug Date: Thu, 28 Nov 2024 14:26:53 +0100 Subject: [PATCH 1/2] Test new approach to referencing content in code blocks. To be more in alignment with asciidoc. Signed-off-by: John Krug --- docs/reference/monitor-mode.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/reference/monitor-mode.md b/docs/reference/monitor-mode.md index 0f322c2250..853ded4511 100644 --- a/docs/reference/monitor-mode.md +++ b/docs/reference/monitor-mode.md @@ -32,8 +32,9 @@ The `mode` is an attribute included in the `ClusterAdmissionPolicy` and `Admissi There are two values that the `mode` attribute can assume: `monitor` and `protect`. The `mode` defaults to `protect` if omitted. -To create a policy in `monitor mode` you to need include the `mode: monitor` as part of the specification of the resource. -For example, as highlighted, in this `ClusterAdmissionPolicy`: +To create a policy in `monitor mode` you to need to include the statement `mode: +monitor` in the specification of the resource. For example, in the +`spec` section (marked ➀), of this `ClusterAdmissionPolicy`: ```yaml apiVersion: policies.kubewarden.io/v1alpha2 @@ -41,8 +42,7 @@ kind: ClusterAdmissionPolicy metadata: name: psp-capabilities spec: -// highlight-next-line - mode: monitor + mode: monitor # ➀ policyServer: reserved-instance-for-tenant-a module: registry://ghcr.io/kubewarden/policies/psp-capabilities:v0.1.3 rules: @@ -60,6 +60,9 @@ spec: - NET_ADMIN ``` +➀ The `mode: monitor` attribute in the `spec` section. +
+ ## Changing policy mode For security purposes, a user with `UPDATE` permissions on policy resources can make the policy more restrictive. @@ -69,7 +72,7 @@ However, you can't change the `mode` of an existing `ClusterAdmissionPolicy` or So, to change the `mode` of a policy from `protect` to `monitor`, you need to delete the policy and re-create it in `monitor` mode. -Switching a policy from `protect` to `monitor` is effectively the same as deleting the policy so this approach ensures that the user has policy delete permissions. +Switching a policy from `protect` to `monitor` is the same as deleting the policy so this approach ensures that the user has policy delete permissions. ## A note on mutating policies From aa16bf31c5943aa13fe3e89b9d748fb3ab703e95 Mon Sep 17 00:00:00 2001 From: John Krug Date: Wed, 4 Dec 2024 14:38:46 +0100 Subject: [PATCH 2/2] Further chnages to remove the use of line number and highlighting in code blocks Signed-off-by: John Krug --- .../pod-security-admission-with-kubewarden.md | 8 ++----- docs/howtos/secure-supply-chain.md | 20 ++++++++-------- docs/reference/verification-config.md | 5 ++-- .../writing-policies/go/04-validation.md | 23 +++++++------------ .../go/09-validation-with-queries.md | 7 +----- .../writing-policies/go/10-raw-policies.md | 1 - .../rego/open-policy-agent/05-raw-policies.md | 4 +--- .../writing-policies/rust/02-create-policy.md | 2 -- .../rust/04-write-validation-logic.md | 16 ++++++------- .../writing-policies/wasi/02-raw-policies.md | 2 -- 10 files changed, 33 insertions(+), 55 deletions(-) diff --git a/docs/howtos/pod-security-admission-with-kubewarden.md b/docs/howtos/pod-security-admission-with-kubewarden.md index 9ca88885ef..d274362b64 100644 --- a/docs/howtos/pod-security-admission-with-kubewarden.md +++ b/docs/howtos/pod-security-admission-with-kubewarden.md @@ -68,7 +68,7 @@ So, the following resource won't reach its desired state:
-kubectl command configuring a resource with the highlighted runAsUser: 0 +`kubectl` command configuring a resource with `runAsUser: 0` marked as ➀ ```shell kubectl apply -n my-namespace -f - < After creating the `ConfigMap` to store the signature requirements, you can configure a Policy Server. -To start validating policy signatures by setting the `ConfigMap` name in the highlighted field `verificationConfig`. +To start validating policy signatures by setting the `ConfigMap` name in the field `verificationConfig` (marked ➀). ```yaml apiVersion: policies.kubewarden.io/v1alpha2 @@ -432,8 +432,8 @@ spec: image: ghcr.io/kubewarden/policy-server:v0.2.7 serviceAccountName: policy-server replicas: 1 -//highlight-next-line - verificationConfig: your_configmap #name of the confimap with the signatures requirements + #name of the configmap with the signatures requirements + verificationConfig: your_configmap # ➀ env: - name: KUBEWARDEN_ENABLE_METRICS value: "1" @@ -442,6 +442,8 @@ spec: - name: "KUBEWARDEN_LOG_LEVEL" value: "info" ``` +➀ `verificationConfig` +
If you deploy the default Policy Server using the `kubewarden-defaults` Helm chart then you configure this field by setting the `ConfigMap` name in the @@ -463,15 +465,13 @@ A file of signature requirements ```yaml apiVersion: v1 -//highlight-next-line -allOf: +allOf: # ➀ - kind: githubAction owner: kubewarden # mandatory annotations: env: prod -//highlight-next-line -anyOf: # at least `anyOf.minimumMatches` are required to match +anyOf: # ➁ : at least `anyOf.minimumMatches` are required to match minimumMatches: 2 # default is 1 signatures: - kind: pubKey @@ -506,16 +506,18 @@ anyOf: # at least `anyOf.minimumMatches` are required to match owner: alice # optional key: .... # mandatory ``` - +➀ : `allOf`
+➁ : `anyOf`
### Signature validation -The configuration above contains the two highlighted sections, `allOf` and `anyOf`: +The configuration above contains the two sections, `allOf` and `anyOf`: - `allOf`: The policy is trusted only if all signature requirements here are valid. - `anyOf`: The policy is trusted if the `minimumMatches` criterion is met. + Above, the `minimumMatches` field is 2. So, at least two of the signature requirements must be met. The default value for `minimumMatches` field is `1`. diff --git a/docs/reference/verification-config.md b/docs/reference/verification-config.md index 5cb1f398d6..38722da251 100644 --- a/docs/reference/verification-config.md +++ b/docs/reference/verification-config.md @@ -109,14 +109,12 @@ A file of signature requirements ```yaml apiVersion: v1 -//highlight-next-line allOf: - kind: githubAction owner: kubewarden # mandatory annotations: env: prod -//highlight-next-line anyOf: # at least `anyOf.minimumMatches` are required to match minimumMatches: 2 # default is 1 signatures: @@ -157,11 +155,12 @@ anyOf: # at least `anyOf.minimumMatches` are required to match ### Signature validation -The configuration above contains the two highlighted sections, `allOf` and `anyOf`: +The configuration above contains the two sections, `allOf` and `anyOf`: - `allOf`: The policy is trusted only if all signature requirements here are valid. - `anyOf`: The policy is trusted if the `minimumMatches` criterion is met. + Above, the `minimumMatches` field is 2. So, at least two of the signature requirements must be met. The default value for `minimumMatches` field is `1`. diff --git a/docs/tutorials/writing-policies/go/04-validation.md b/docs/tutorials/writing-policies/go/04-validation.md index 7e52ae39c2..c5fa9c5b77 100644 --- a/docs/tutorials/writing-policies/go/04-validation.md +++ b/docs/tutorials/writing-policies/go/04-validation.md @@ -55,7 +55,6 @@ This is how the function should be when complete: ```go func validate(payload []byte) ([]byte, error) { - // highlight-next-line // NOTE 1 // Create a ValidationRequest instance from the incoming payload validationRequest := kubewarden_protocol.ValidationRequest{} @@ -66,7 +65,6 @@ func validate(payload []byte) ([]byte, error) { kubewarden.Code(400)) } - // highlight-next-line // NOTE 2 // Create a Settings instance from the ValidationRequest object settings, err := NewSettingsFromValidationReq(&validationRequest) @@ -76,12 +74,10 @@ func validate(payload []byte) ([]byte, error) { kubewarden.Code(400)) } - // highlight-next-line // NOTE 3 // Access the **raw** JSON that describes the object podJSON := validationRequest.Request.Object - // highlight-next-line // NOTE 4 // Try to create a Pod instance using the RAW JSON we got from the // ValidationRequest. @@ -98,7 +94,6 @@ func validate(payload []byte) ([]byte, error) { e.String("namespace", pod.Metadata.Namespace) }) - // highlight-next-line // NOTE 5 for label, value := range pod.Metadata.Labels { if err := validateLabel(label, value, &settings); err != nil { @@ -112,7 +107,7 @@ func validate(payload []byte) ([]byte, error) { } ``` -The code has `NOTE` sections: +The code has five `NOTE` sections: 1. Create a `kubewarden_protocol.ValidationRequest` by unmarshaling the JSON payload. 1. Create a `Settings` object by using the function you earlier defined in the `settings.go` file. @@ -169,7 +164,6 @@ import ( ) func TestValidateLabel(t *testing.T) { - // highlight-next-line // NOTE 1 cases := []struct { podLabels map[string]string @@ -178,7 +172,7 @@ func TestValidateLabel(t *testing.T) { expectedIsValid bool }{ { - // highlight-next-line + // ➀ // Pod has no labels -> should be accepted podLabels: map[string]string{}, deniedLabels: mapset.NewThreadUnsafeSet[string]("owner"), @@ -186,7 +180,7 @@ func TestValidateLabel(t *testing.T) { expectedIsValid: true, }, { - // highlight-next-line + // ➁ // Pod has labels, none is denied -> should be accepted podLabels: map[string]string{ "hello": "world", @@ -196,7 +190,7 @@ func TestValidateLabel(t *testing.T) { expectedIsValid: true, }, { - // highlight-next-line + // ➂ // Pod has labels, one is denied -> should be rejected podLabels: map[string]string{ "hello": "world", @@ -206,7 +200,7 @@ func TestValidateLabel(t *testing.T) { expectedIsValid: false, }, { - // highlight-next-line + // ➃ // Pod has labels, one has constraint that is respected -> should be accepted podLabels: map[string]string{ "cc-center": "team-123", @@ -220,7 +214,7 @@ func TestValidateLabel(t *testing.T) { expectedIsValid: true, }, { - // highlight-next-line + // ➄ // Pod has labels, one has constraint that are not respected -> should be rejected podLabels: map[string]string{ "cc-center": "team-kubewarden", @@ -234,7 +228,7 @@ func TestValidateLabel(t *testing.T) { expectedIsValid: false, }, { - // highlight-next-line + // ➅ // Settings have a constraint, pod doesn't have this label -> should be rejected podLabels: map[string]string{ "owner": "team-kubewarden", @@ -249,7 +243,6 @@ func TestValidateLabel(t *testing.T) { }, } - // highlight-next-line // NOTE 2 for _, testCase := range cases { settings := Settings{ @@ -308,7 +301,7 @@ struct { ``` You then declare several test cases. -They have the start lines highlighted in the code block above. +They have the start lines marked ➀ to ➅ in the large code block above. For example, you should consider a Pod that has no labels to be valid. diff --git a/docs/tutorials/writing-policies/go/09-validation-with-queries.md b/docs/tutorials/writing-policies/go/09-validation-with-queries.md index 15f5099ca6..612fff1b5a 100644 --- a/docs/tutorials/writing-policies/go/09-validation-with-queries.md +++ b/docs/tutorials/writing-policies/go/09-validation-with-queries.md @@ -74,7 +74,6 @@ func validate(payload []byte) ([]byte, error) { // Access the **raw** JSON that describes the object podJSON := validationRequest.Request.Object - // highlight-next-line // NOTE 1 data := gjson.GetBytes( podJSON, @@ -83,12 +82,10 @@ func validate(payload []byte) ([]byte, error) { var validationErr error labels := mapset.NewThreadUnsafeSet[string]() data.ForEach(func(key, value gjson.Result) bool { - // highlight-next-line // NOTE 2 label := key.String() labels.Add(label) - // highlight-next-line // NOTE 3 validationErr = validateLabel(label, value.String(), &settings) @@ -96,7 +93,6 @@ func validate(payload []byte) ([]byte, error) { return validationErr == nil }) - // highlight-next-line // NOTE 4 if validationErr != nil { return kubewarden.RejectRequest( @@ -104,7 +100,6 @@ func validate(payload []byte) ([]byte, error) { kubewarden.NoCode) } - // highlight-next-line // NOTE 5 for requiredLabel := range settings.ConstrainedLabels { if !labels.Contains(requiredLabel) { @@ -121,7 +116,7 @@ func validate(payload []byte) ([]byte, error) { The first part of the `validate` function is similar as before. -'NOTE' highlights the changes. +The 'NOTE's mark the changes. 1. You use a `gjson` selector to get the `label` map provided by the object embedded into the request 1. You use a `gjson` helper to iterate over the results of the query. diff --git a/docs/tutorials/writing-policies/go/10-raw-policies.md b/docs/tutorials/writing-policies/go/10-raw-policies.md index 4d488b67eb..173414b0c8 100644 --- a/docs/tutorials/writing-policies/go/10-raw-policies.md +++ b/docs/tutorials/writing-policies/go/10-raw-policies.md @@ -36,7 +36,6 @@ rules: mutating: false contextAware: false executionMode: kubewarden-wapc -// highlight-next-line policyType: raw # Consider the policy for the background audit scans. Default is true. Note the # intrinsic limitations of the background audit feature on docs.kubewarden.io; diff --git a/docs/tutorials/writing-policies/rego/open-policy-agent/05-raw-policies.md b/docs/tutorials/writing-policies/rego/open-policy-agent/05-raw-policies.md index c27db36f9c..2fbf72ba07 100644 --- a/docs/tutorials/writing-policies/rego/open-policy-agent/05-raw-policies.md +++ b/docs/tutorials/writing-policies/rego/open-policy-agent/05-raw-policies.md @@ -60,7 +60,7 @@ deny[msg] { } ``` -The `utility/policy.rego` module must needs modification to remove Kubernetes-specific code: +The `utility/policy.rego` module needs modification to remove Kubernetes-specific code: ```rego package policy @@ -71,13 +71,11 @@ main = { "response": response, } -// highlight-start # OPA policy responses need the uid field to be set. # If the request doesn't contain a uid, set it to an empty string. default uid = "" uid = input.request.uid -// highlight-end response = { "uid": uid, diff --git a/docs/tutorials/writing-policies/rust/02-create-policy.md b/docs/tutorials/writing-policies/rust/02-create-policy.md index a82e5c4d9c..d6a85fa2b6 100644 --- a/docs/tutorials/writing-policies/rust/02-create-policy.md +++ b/docs/tutorials/writing-policies/rust/02-create-policy.md @@ -31,7 +31,6 @@ The policy should accept the creation of a Pod like the following one: apiVersion: v1 kind: Pod metadata: -// highlight-next-line name: nginx spec: containers: @@ -45,7 +44,6 @@ It should reject the creation of a Pod like: apiVersion: v1 kind: Pod metadata: -// highlight-next-line name: bad_name1 spec: containers: diff --git a/docs/tutorials/writing-policies/rust/04-write-validation-logic.md b/docs/tutorials/writing-policies/rust/04-write-validation-logic.md index 9494815ce7..20270367ad 100644 --- a/docs/tutorials/writing-policies/rust/04-write-validation-logic.md +++ b/docs/tutorials/writing-policies/rust/04-write-validation-logic.md @@ -20,7 +20,7 @@ This is the scaffolding provided function: ```rust showLineNumbers fn validate(payload: &[u8]) -> CallResult { - // highlight-next-line + // ➀ let validation_request: ValidationRequest = ValidationRequest::new(payload)?; info!(LOG_DRAIN, "starting validation"); @@ -29,11 +29,11 @@ fn validate(payload: &[u8]) -> CallResult { return kubewarden::accept_request(); } // TODO: you can unmarshal any Kubernetes API type you are interested in - // highlight-next-line + // ➁ match serde_json::from_value::(validation_request.request.object) { Ok(pod) => { // TODO: your logic goes here - // highlight-next-line + // ➂ if pod.metadata.name == Some("invalid-pod-name".to_string()) { let pod_name = pod.metadata.name.unwrap(); info!( @@ -57,7 +57,7 @@ fn validate(payload: &[u8]) -> CallResult { // We were forwarded a request we cannot unmarshal or // understand, just accept it warn!(LOG_DRAIN, "cannot unmarshal resource: this policy does not know how to evaluate this resource; accept it"); - // highlight-next-line + // ➃ kubewarden::accept_request() } } @@ -66,12 +66,12 @@ fn validate(payload: &[u8]) -> CallResult { Walking through the code listing: -- In line 2. Parse the incoming `payload` into a `ValidationRequest` object. +- In the line marked ➀. Parse the incoming `payload` into a `ValidationRequest` object. This automatically populates the `Settings` instance inside the `ValidationRequest` with the parameters provided by the user. -- In line 10. Convert the Kubernetes raw JSON object embedded into the request into an instance of the +- In the line marked ➁. Convert the Kubernetes raw JSON object embedded into the request into an instance of the [Pod struct](https://arnavion.github.io/k8s-openapi/v0.11.x/k8s_openapi/api/core/v1/struct.Pod.html) -- In line 13. The request has a Pod object, the code approves only the requests that don't have `metadata.name` equal to the hard-coded value `invalid-pod-name` -- In line 36. The request doesn't contain a Pod object, hence the policy accepts the request. +- In the line marked ➂. The request has a Pod object, the code approves only the requests that don't have `metadata.name` equal to the hard-coded value `invalid-pod-name` +- In the line marked ➃. The request doesn't contain a Pod object, hence the policy accepts the request. As you can see, the code is already doing a validation that resembles the one you want to implement. You just have to remove the hard-coded value and use the values provided by the user via the policy settings. diff --git a/docs/tutorials/writing-policies/wasi/02-raw-policies.md b/docs/tutorials/writing-policies/wasi/02-raw-policies.md index dca74ec6fe..232e95b4a4 100644 --- a/docs/tutorials/writing-policies/wasi/02-raw-policies.md +++ b/docs/tutorials/writing-policies/wasi/02-raw-policies.md @@ -222,13 +222,11 @@ type ValidationResponse struct { // Optional - ignored if accepted Code *uint16 `json:"code,omitempty"` // Optional - used only by mutating policies - // highlight-next-line MutatedObject *Request `json:"mutated_object,omitempty"` } // MutateRequest accepts the request. The given `mutatedObject` is how // the evaluated object must look once accepted -// highlight-next-line func MutateRequest(mutatedObject *Request) ValidationResponse { return ValidationResponse{ Accepted: true,