@intentius/chant-lexicon-k8s 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composites/index.d.ts +2 -0
- package/dist/composites/index.d.ts.map +1 -1
- package/dist/composites/operator-stack.d.ts +183 -0
- package/dist/composites/operator-stack.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/integrity.json +35 -35
- package/dist/lint/post-synth/argo-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/crd-schema-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/k8s-helpers.d.ts +28 -5
- package/dist/lint/post-synth/k8s-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8005.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8006.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8041.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8042.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8101.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8102.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8103.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8104.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8105.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8201.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8202.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8203.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8204.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8205.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8207.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8208.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8209.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8301.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8302.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8303.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8304.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8305.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8306.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8401.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8402.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8403.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8404.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8405.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8406.d.ts.map +1 -1
- package/dist/lint/post-synth/wk8407.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/op/builders.d.ts +69 -0
- package/dist/op/builders.d.ts.map +1 -0
- package/dist/rules/argo-helpers.ts +2 -6
- package/dist/rules/crd-schema-helpers.ts +4 -6
- package/dist/rules/k8s-helpers.ts +32 -23
- package/dist/rules/wk8005.ts +27 -32
- package/dist/rules/wk8006.ts +33 -38
- package/dist/rules/wk8041.ts +19 -24
- package/dist/rules/wk8042.ts +17 -22
- package/dist/rules/wk8101.ts +29 -34
- package/dist/rules/wk8102.ts +13 -18
- package/dist/rules/wk8103.ts +17 -22
- package/dist/rules/wk8104.ts +30 -35
- package/dist/rules/wk8105.ts +16 -21
- package/dist/rules/wk8201.ts +26 -31
- package/dist/rules/wk8202.ts +17 -22
- package/dist/rules/wk8203.ts +17 -22
- package/dist/rules/wk8204.ts +46 -51
- package/dist/rules/wk8205.ts +27 -32
- package/dist/rules/wk8207.ts +14 -19
- package/dist/rules/wk8208.ts +14 -19
- package/dist/rules/wk8209.ts +14 -19
- package/dist/rules/wk8301.ts +25 -30
- package/dist/rules/wk8302.ts +19 -24
- package/dist/rules/wk8303.ts +23 -26
- package/dist/rules/wk8304.ts +35 -40
- package/dist/rules/wk8305.ts +39 -42
- package/dist/rules/wk8306.ts +20 -25
- package/dist/rules/wk8401.ts +59 -64
- package/dist/rules/wk8402.ts +13 -18
- package/dist/rules/wk8403.ts +32 -37
- package/dist/rules/wk8404.ts +15 -21
- package/dist/rules/wk8405.ts +15 -18
- package/dist/rules/wk8406.ts +29 -34
- package/dist/rules/wk8407.ts +17 -22
- package/dist/serializer.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/composites/composites.test.ts +283 -0
- package/src/composites/index.ts +4 -0
- package/src/composites/operator-stack.ts +385 -0
- package/src/index.ts +11 -0
- package/src/lint/post-synth/argo-helpers.ts +2 -6
- package/src/lint/post-synth/crd-schema-helpers.ts +4 -6
- package/src/lint/post-synth/k8s-helpers.test.ts +26 -9
- package/src/lint/post-synth/k8s-helpers.ts +32 -23
- package/src/lint/post-synth/wk8005.ts +27 -32
- package/src/lint/post-synth/wk8006.ts +33 -38
- package/src/lint/post-synth/wk8041.ts +19 -24
- package/src/lint/post-synth/wk8042.ts +17 -22
- package/src/lint/post-synth/wk8101.ts +29 -34
- package/src/lint/post-synth/wk8102.ts +13 -18
- package/src/lint/post-synth/wk8103.ts +17 -22
- package/src/lint/post-synth/wk8104.ts +30 -35
- package/src/lint/post-synth/wk8105.ts +16 -21
- package/src/lint/post-synth/wk8201.ts +26 -31
- package/src/lint/post-synth/wk8202.ts +17 -22
- package/src/lint/post-synth/wk8203.ts +17 -22
- package/src/lint/post-synth/wk8204.ts +46 -51
- package/src/lint/post-synth/wk8205.ts +27 -32
- package/src/lint/post-synth/wk8207.ts +14 -19
- package/src/lint/post-synth/wk8208.ts +14 -19
- package/src/lint/post-synth/wk8209.ts +14 -19
- package/src/lint/post-synth/wk8301.ts +25 -30
- package/src/lint/post-synth/wk8302.ts +19 -24
- package/src/lint/post-synth/wk8303.ts +23 -26
- package/src/lint/post-synth/wk8304.ts +35 -40
- package/src/lint/post-synth/wk8305.ts +39 -42
- package/src/lint/post-synth/wk8306.ts +20 -25
- package/src/lint/post-synth/wk8401.ts +59 -64
- package/src/lint/post-synth/wk8402.ts +13 -18
- package/src/lint/post-synth/wk8403.ts +32 -37
- package/src/lint/post-synth/wk8404.ts +15 -21
- package/src/lint/post-synth/wk8405.ts +15 -18
- package/src/lint/post-synth/wk8406.ts +29 -34
- package/src/lint/post-synth/wk8407.ts +17 -22
- package/src/op/builders.test.ts +82 -0
- package/src/op/builders.ts +95 -0
- package/src/serializer.ts +9 -1
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8201: PostSynthCheck = {
|
|
13
13
|
id: "WK8201",
|
|
@@ -16,36 +16,31 @@ export const wk8201: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!limits
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" is missing resource limits for ${missing.join(", ")}`,
|
|
45
|
-
entity: resourceName,
|
|
46
|
-
lexicon: "k8s",
|
|
47
|
-
});
|
|
48
|
-
}
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
21
|
+
|
|
22
|
+
const containers = extractContainers(manifest);
|
|
23
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
24
|
+
|
|
25
|
+
for (const container of containers) {
|
|
26
|
+
const limits = container.resources?.limits;
|
|
27
|
+
const missing: string[] = [];
|
|
28
|
+
|
|
29
|
+
if (!limits || typeof limits !== "object") {
|
|
30
|
+
missing.push("cpu", "memory");
|
|
31
|
+
} else {
|
|
32
|
+
if (!limits.cpu) missing.push("cpu");
|
|
33
|
+
if (!limits.memory) missing.push("memory");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (missing.length > 0) {
|
|
37
|
+
diagnostics.push({
|
|
38
|
+
checkId: "WK8201",
|
|
39
|
+
severity: "warning",
|
|
40
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" is missing resource limits for ${missing.join(", ")}`,
|
|
41
|
+
entity: resourceName,
|
|
42
|
+
lexicon: "k8s",
|
|
43
|
+
});
|
|
49
44
|
}
|
|
50
45
|
}
|
|
51
46
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8202: PostSynthCheck = {
|
|
13
13
|
id: "WK8202",
|
|
@@ -16,27 +16,22 @@ export const wk8202: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" runs in privileged mode — this grants full host access and should be avoided`,
|
|
36
|
-
entity: resourceName,
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
21
|
+
|
|
22
|
+
const containers = extractContainers(manifest);
|
|
23
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
24
|
+
|
|
25
|
+
for (const container of containers) {
|
|
26
|
+
const secCtx = container.securityContext;
|
|
27
|
+
if (secCtx && secCtx.privileged === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8202",
|
|
30
|
+
severity: "error",
|
|
31
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" runs in privileged mode — this grants full host access and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8203: PostSynthCheck = {
|
|
13
13
|
id: "WK8203",
|
|
@@ -16,27 +16,22 @@ export const wk8203: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not set readOnlyRootFilesystem: true — set it to reduce the attack surface`,
|
|
36
|
-
entity: resourceName,
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
21
|
+
|
|
22
|
+
const containers = extractContainers(manifest);
|
|
23
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
24
|
+
|
|
25
|
+
for (const container of containers) {
|
|
26
|
+
const secCtx = container.securityContext;
|
|
27
|
+
if (!secCtx || secCtx.readOnlyRootFilesystem !== true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8203",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not set readOnlyRootFilesystem: true — set it to reduce the attack surface`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
14
|
-
import {
|
|
14
|
+
import { docsToManifests, extractContainers, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
15
15
|
|
|
16
16
|
export const wk8204: PostSynthCheck = {
|
|
17
17
|
id: "WK8204",
|
|
@@ -20,63 +20,58 @@ export const wk8204: PostSynthCheck = {
|
|
|
20
20
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
21
21
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
22
22
|
|
|
23
|
-
for (const
|
|
24
|
-
|
|
25
|
-
const manifests = parseK8sManifests(yaml);
|
|
23
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
24
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
27
|
+
const podSpec = extractPodSpec(manifest);
|
|
28
|
+
if (!podSpec) continue;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
// Check pod-level securityContext
|
|
31
|
+
const podSecCtx = podSpec.securityContext as Record<string, unknown> | undefined;
|
|
32
|
+
const podRunAsNonRoot = podSecCtx?.runAsNonRoot === true;
|
|
33
|
+
const podRunAsUser = podSecCtx?.runAsUser;
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
35
|
+
const containers = extractContainers(manifest);
|
|
36
|
+
for (const container of containers) {
|
|
37
|
+
const secCtx = container.securityContext;
|
|
38
|
+
const containerRunAsNonRoot = secCtx?.runAsNonRoot === true;
|
|
39
|
+
const containerRunAsUser = secCtx?.runAsUser;
|
|
38
40
|
|
|
39
|
-
const
|
|
40
|
-
for (const container of containers) {
|
|
41
|
-
const secCtx = container.securityContext;
|
|
42
|
-
const containerRunAsNonRoot = secCtx?.runAsNonRoot === true;
|
|
43
|
-
const containerRunAsUser = secCtx?.runAsUser;
|
|
41
|
+
const hasRunAsNonRoot = podRunAsNonRoot || containerRunAsNonRoot;
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
43
|
+
if (!hasRunAsNonRoot) {
|
|
44
|
+
diagnostics.push({
|
|
45
|
+
checkId: "WK8204",
|
|
46
|
+
severity: "warning",
|
|
47
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not set runAsNonRoot: true — set it at container or pod level`,
|
|
48
|
+
entity: resourceName,
|
|
49
|
+
lexicon: "k8s",
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
// runAsNonRoot is true — check for explicit runAsUser
|
|
55
|
+
const effectiveRunAsUser = containerRunAsUser ?? podRunAsUser;
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
57
|
+
if (effectiveRunAsUser === 0) {
|
|
58
|
+
// Contradictory: runAsNonRoot: true + runAsUser: 0
|
|
59
|
+
diagnostics.push({
|
|
60
|
+
checkId: "WK8204",
|
|
61
|
+
severity: "warning",
|
|
62
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has runAsNonRoot: true but runAsUser: 0 — these settings are contradictory and the container will fail to start`,
|
|
63
|
+
entity: resourceName,
|
|
64
|
+
lexicon: "k8s",
|
|
65
|
+
});
|
|
66
|
+
} else if (effectiveRunAsUser === undefined || effectiveRunAsUser === null) {
|
|
67
|
+
// runAsNonRoot: true but no explicit UID
|
|
68
|
+
diagnostics.push({
|
|
69
|
+
checkId: "WK8204",
|
|
70
|
+
severity: "warning",
|
|
71
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" has runAsNonRoot: true but no explicit runAsUser — set a numeric UID to ensure the container doesn't run as root`,
|
|
72
|
+
entity: resourceName,
|
|
73
|
+
lexicon: "k8s",
|
|
74
|
+
});
|
|
80
75
|
}
|
|
81
76
|
}
|
|
82
77
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8205: PostSynthCheck = {
|
|
13
13
|
id: "WK8205",
|
|
@@ -16,37 +16,32 @@ export const wk8205: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not drop ALL capabilities — add securityContext.capabilities.drop: ["ALL"]`,
|
|
46
|
-
entity: resourceName,
|
|
47
|
-
lexicon: "k8s",
|
|
48
|
-
});
|
|
49
|
-
}
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
21
|
+
|
|
22
|
+
const containers = extractContainers(manifest);
|
|
23
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
24
|
+
|
|
25
|
+
for (const container of containers) {
|
|
26
|
+
const secCtx = container.securityContext;
|
|
27
|
+
const capabilities = secCtx?.capabilities as Record<string, unknown> | undefined;
|
|
28
|
+
const drop = capabilities?.drop;
|
|
29
|
+
|
|
30
|
+
const dropsAll =
|
|
31
|
+
Array.isArray(drop) &&
|
|
32
|
+
drop.some(
|
|
33
|
+
(cap) =>
|
|
34
|
+
(typeof cap === "string" && cap.toUpperCase() === "ALL"),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
if (!dropsAll) {
|
|
38
|
+
diagnostics.push({
|
|
39
|
+
checkId: "WK8205",
|
|
40
|
+
severity: "warning",
|
|
41
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" does not drop ALL capabilities — add securityContext.capabilities.drop: ["ALL"]`,
|
|
42
|
+
entity: resourceName,
|
|
43
|
+
lexicon: "k8s",
|
|
44
|
+
});
|
|
50
45
|
}
|
|
51
46
|
}
|
|
52
47
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8207: PostSynthCheck = {
|
|
13
13
|
id: "WK8207",
|
|
@@ -16,27 +16,22 @@ export const wk8207: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const podSpec = extractPodSpec(manifest);
|
|
23
|
+
if (!podSpec) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (!podSpec) continue;
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
27
|
+
if (podSpec.hostNetwork === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8207",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `${manifest.kind} "${resourceName}" uses hostNetwork: true — this bypasses network isolation and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8208: PostSynthCheck = {
|
|
13
13
|
id: "WK8208",
|
|
@@ -16,27 +16,22 @@ export const wk8208: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const podSpec = extractPodSpec(manifest);
|
|
23
|
+
if (!podSpec) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (!podSpec) continue;
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
27
|
+
if (podSpec.hostPID === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8208",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `${manifest.kind} "${resourceName}" uses hostPID: true — this allows visibility into all host processes and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
10
|
-
import {
|
|
10
|
+
import { docsToManifests, extractPodSpec, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
11
11
|
|
|
12
12
|
export const wk8209: PostSynthCheck = {
|
|
13
13
|
id: "WK8209",
|
|
@@ -16,27 +16,22 @@ export const wk8209: PostSynthCheck = {
|
|
|
16
16
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
17
17
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
18
18
|
|
|
19
|
-
for (const
|
|
20
|
-
|
|
21
|
-
const manifests = parseK8sManifests(yaml);
|
|
19
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
20
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const podSpec = extractPodSpec(manifest);
|
|
23
|
+
if (!podSpec) continue;
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
if (!podSpec) continue;
|
|
25
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lexicon: "k8s",
|
|
38
|
-
});
|
|
39
|
-
}
|
|
27
|
+
if (podSpec.hostIPC === true) {
|
|
28
|
+
diagnostics.push({
|
|
29
|
+
checkId: "WK8209",
|
|
30
|
+
severity: "warning",
|
|
31
|
+
message: `${manifest.kind} "${resourceName}" uses hostIPC: true — this exposes host shared memory segments and should be avoided`,
|
|
32
|
+
entity: resourceName,
|
|
33
|
+
lexicon: "k8s",
|
|
34
|
+
});
|
|
40
35
|
}
|
|
41
36
|
}
|
|
42
37
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
15
|
-
import {
|
|
15
|
+
import { docsToManifests, extractContainers, WORKLOAD_KINDS } from "./k8s-helpers";
|
|
16
16
|
|
|
17
17
|
export const wk8301: PostSynthCheck = {
|
|
18
18
|
id: "WK8301",
|
|
@@ -21,35 +21,30 @@ export const wk8301: PostSynthCheck = {
|
|
|
21
21
|
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
22
22
|
const diagnostics: PostSynthDiagnostic[] = [];
|
|
23
23
|
|
|
24
|
-
for (const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" is missing ${missing.join(" and ")}`,
|
|
49
|
-
entity: resourceName,
|
|
50
|
-
lexicon: "k8s",
|
|
51
|
-
});
|
|
52
|
-
}
|
|
24
|
+
for (const manifest of docsToManifests(ctx)) {
|
|
25
|
+
if (!manifest.kind || !WORKLOAD_KINDS.has(manifest.kind)) continue;
|
|
26
|
+
// CronJobs and Jobs are short-lived — probes are less relevant
|
|
27
|
+
if (manifest.kind === "Job" || manifest.kind === "CronJob") continue;
|
|
28
|
+
|
|
29
|
+
const containers = extractContainers(manifest);
|
|
30
|
+
const resourceName = manifest.metadata?.name ?? manifest.kind;
|
|
31
|
+
|
|
32
|
+
for (const container of containers) {
|
|
33
|
+
// No declared port → no inbound traffic → nothing to HTTP-probe.
|
|
34
|
+
if (!container.ports || container.ports.length === 0) continue;
|
|
35
|
+
|
|
36
|
+
const missing: string[] = [];
|
|
37
|
+
if (!container.livenessProbe) missing.push("livenessProbe");
|
|
38
|
+
if (!container.readinessProbe) missing.push("readinessProbe");
|
|
39
|
+
|
|
40
|
+
if (missing.length > 0) {
|
|
41
|
+
diagnostics.push({
|
|
42
|
+
checkId: "WK8301",
|
|
43
|
+
severity: "warning",
|
|
44
|
+
message: `Container "${container.name ?? "(unnamed)"}" in ${manifest.kind} "${resourceName}" is missing ${missing.join(" and ")}`,
|
|
45
|
+
entity: resourceName,
|
|
46
|
+
lexicon: "k8s",
|
|
47
|
+
});
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
50
|
}
|