organize deployment configuration
Kube-bench CIS scan / Scan ephemeral K3s cluster (push) Successful in 1m6s

This commit is contained in:
2026-08-15 13:17:46 -04:00
parent 12f3276465
commit fc53e16dd4
18 changed files with 26 additions and 13 deletions
+41
View File
@@ -0,0 +1,41 @@
# ArgoCD GitOps bootstrap
ArgoCD is installed once into the local cluster; everything after that is
declared through the root Application. The root uses the app-of-apps pattern:
it watches `deployments/argocd/apps/`, and each child Application owns one platform or
workload boundary.
## Bootstrap
1. Push this repository to the configured Git server and use the repository URL
in the Application manifests.
2. Create the local cluster from `local-quickstart/`.
3. Run:
```bash
kubectl create namespace argocd --dry-run=client -o yaml | kubectl apply -f -
kubectl apply --server-side --force-conflicts -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl -n argocd rollout status deployment/argocd-server --timeout=180s
kubectl apply -f deployments/argocd/app-of-apps.yaml
kubectl get applications -n argocd -w
```
The first command is idempotent. The official install manifest is fetched at
bootstrap time rather than vendored into this repository, keeping the repo
reviewable and making the ArgoCD version choice visible in the command.
For local UI access:
```bash
kubectl -n argocd port-forward svc/argocd-server 8081:443
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath='{.data.password}' | base64 -d; echo
```
The initial admin secret is for local bootstrap only. A later hardening phase
should replace this with SSO/RBAC and remove the bootstrap credential.
For a kube-proxy-free Cilium cluster, install Cilium before ArgoCD using the
profile in `local-quickstart/cilium.md` or the Flatcar cloud bootstrap. The
Cilium Application is stored under `deployments/argocd/optional-apps/` and is not watched
by the default root app until the cluster is ready for it.
+23
View File
@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: security-baseline-root
namespace: argocd
labels:
app.kubernetes.io/part-of: kubernetes-security-baseline
spec:
project: default
source:
# Replace the owner after publishing this repository.
repoURL: https://git.swaphb.com/swaphb/kubernetes-security-baseline-lab.git
targetRevision: main
path: deployments/argocd/apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+33
View File
@@ -0,0 +1,33 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: falco
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "-1"
spec:
project: default
sources:
- repoURL: https://falcosecurity.github.io/charts
chart: falco-operator
# Operator chart 0.3.1 deploys Falco Operator 0.4.1.
targetRevision: 0.3.1
helm:
valueFiles:
- $values/deployments/falco/falco-operator-values.yaml
- repoURL: https://git.swaphb.com/swaphb/kubernetes-security-baseline-lab.git
targetRevision: main
ref: values
- repoURL: https://git.swaphb.com/swaphb/kubernetes-security-baseline-lab.git
targetRevision: main
path: deployments/falco/operator-resources
destination:
server: https://kubernetes.default.svc
namespace: falco-operator
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
+29
View File
@@ -0,0 +1,29 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kyverno
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "-2"
spec:
project: default
source:
repoURL: https://kyverno.github.io/kyverno/
chart: kyverno
targetRevision: 3.8.2
helm:
values: |
crds:
annotations:
# The two policy CRDs exceed client-side apply's annotation limit.
argocd.argoproj.io/sync-options: ServerSideApply=true
destination:
server: https://kubernetes.default.svc
namespace: kyverno
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true
+23
View File
@@ -0,0 +1,23 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: security-policies
namespace: argocd
annotations:
# Policies wait for Kyverno's CRDs/controller to exist.
argocd.argoproj.io/sync-wave: "0"
spec:
project: default
source:
repoURL: https://git.swaphb.com/swaphb/kubernetes-security-baseline-lab.git
targetRevision: main
path: policies/kyverno
destination:
server: https://kubernetes.default.svc
namespace: security-baseline
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: security-test-workloads
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
project: default
source:
repoURL: https://git.swaphb.com/swaphb/kubernetes-security-baseline-lab.git
targetRevision: main
path: test-workloads
destination:
server: https://kubernetes.default.svc
namespace: security-baseline
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
# Test Pods are intentionally disposable and their command fields are immutable.
- Replace=true
@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cilium
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "-4"
spec:
project: default
sources:
- repoURL: https://helm.cilium.io/
chart: cilium
targetRevision: 1.20.0
helm:
valueFiles:
- $values/deployments/cilium/cilium-values.yaml
- repoURL: https://git.swaphb.com/swaphb/kubernetes-security-baseline-lab.git
targetRevision: main
ref: values
destination:
server: https://kubernetes.default.svc
namespace: kube-system
# Apply this Application manually only after bootstrapping a kube-proxy-free
# cluster and replacing the API endpoint placeholder.
+23
View File
@@ -0,0 +1,23 @@
# Cilium is the CNI, network-policy engine, and eBPF service datapath for the
# production-style K3s profile. Set this endpoint before bootstrapping a
# cluster because kube-proxy is intentionally disabled.
kubeProxyReplacement: true
k8sServiceHost: "127.0.0.1"
k8sServicePort: 6443
ipam:
mode: kubernetes
routingMode: tunnel
tunnelProtocol: vxlan
hubble:
enabled: true
relay:
enabled: true
ui:
enabled: true
operator:
replicas: 1
@@ -0,0 +1,17 @@
# Falco Operator settings. Falco instances and their artifacts are managed by
# the CRs under deployments/falco/operator-resources.
replicaCount: 1
# Keep ArgoCD tracking labels on the operator itself, not on resources created
# by the operator from Falco, Config, Plugin, or Rulesfile resources.
excludedLabels:
- argocd.argoproj.io/instance
- argocd.argoproj.io/tracking-id
resources:
requests:
cpu: 10m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
@@ -0,0 +1,14 @@
apiVersion: artifact.falcosecurity.dev/v1alpha1
kind: Plugin
metadata:
name: container
namespace: falco
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
ociArtifact:
image:
repository: falcosecurity/plugins/plugin/container
tag: latest
registry:
name: ghcr.io
@@ -0,0 +1,42 @@
# Custom runtime detections for the portfolio baseline.
# These rules supplement the default Falco rules and are intentionally scoped
# to container activity for a clear admission-to-runtime demonstration.
- list: sensitive_container_paths
items: [/etc/passwd, /etc/shadow, /etc/sudoers, /etc/ssh/sshd_config]
- macro: container_activity
condition: container.id != host
- rule: Shell spawned in container
desc: A shell process was started inside a running container.
condition: evt.type in (execve, execveat) and container_activity and proc.name in (bash, sh, ash, zsh, ksh, fish)
output: >-
Shell spawned in container
(user=%user.name user_uid=%user.uid shell=%proc.name command=%proc.cmdline
container_id=%container.id container_image=%container.image.repository
container_name=%container.name k8s_ns=%k8s.ns.name k8s_pod=%k8s.pod.name)
priority: WARNING
tags: [container, process, baseline]
- rule: Sensitive file modified in container
desc: A process attempted to write a sensitive host-like file from a container.
condition: evt.type in (open, openat, openat2) and evt.is_open_write=true and container_activity and fd.name in (sensitive_container_paths)
output: >-
Sensitive file modified in container
(user=%user.name command=%proc.cmdline file=%fd.name
container_id=%container.id container_image=%container.image.repository
k8s_ns=%k8s.ns.name k8s_pod=%k8s.pod.name)
priority: ERROR
tags: [container, filesystem, persistence, baseline]
- rule: Unexpected outbound connection from container
desc: A container opened a connection to a non-loopback address.
condition: evt.type=connect and container_activity and not fd.sip in (127.0.0.1, 0.0.0.0)
output: >-
Outbound connection from container
(user=%user.name command=%proc.cmdline connection=%fd.name
container_id=%container.id container_image=%container.image.repository
k8s_ns=%k8s.ns.name k8s_pod=%k8s.pod.name)
priority: NOTICE
tags: [container, network, baseline]
@@ -0,0 +1,11 @@
apiVersion: artifact.falcosecurity.dev/v1alpha1
kind: Rulesfile
metadata:
name: custom-rules
namespace: falco
annotations:
argocd.argoproj.io/sync-wave: "2"
spec:
priority: 60
configMapRef:
name: falco-custom-rules
@@ -0,0 +1,12 @@
apiVersion: artifact.falcosecurity.dev/v1alpha1
kind: Config
metadata:
name: falco-output
namespace: falco
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
priority: 50
config:
json_output: true
json_include_output_property: true
@@ -0,0 +1,9 @@
apiVersion: instance.falcosecurity.dev/v1alpha1
kind: Falco
metadata:
name: falco
namespace: falco
annotations:
# Apply the instance after the Operator chart has installed its CRDs.
argocd.argoproj.io/sync-wave: "1"
spec: {}
@@ -0,0 +1,17 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: falco
resources:
- namespace.yaml
- falco-instance.yaml
- falco-config.yaml
- container-plugin.yaml
- custom-rulesfile.yaml
configMapGenerator:
- name: falco-custom-rules
files:
- rules.yaml=custom-rules.yaml
generatorOptions:
disableNameSuffixHash: true
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: falco