Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .arclint
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"(^private\/credentials\/.*\\.yaml)",
"(^src/operator/client/versioned/)",
"(^src/operator/apis/px.dev/v1alpha1/zz_generated.deepcopy.go)",
"(^src/e2e_test/adaptive_export_loadtest/tools/loadgen/)",
"(^src/stirling/bpf_tools/bcc_bpf/system-headers)",
"(^src/stirling/mysql/testing/.*\\.json$)",
"(^src/stirling/obj_tools/testdata/go/test_go_binary.go)",
Expand Down
128 changes: 128 additions & 0 deletions .github/workflows/e2e_log4shell_soc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
# e2e-log4shell-soc — stand up a real SOC stack on k3s, fire log4shell end-to-end,
# assert every canonical harness script actually runs, and profile dx in real life.
#
# Heavy: needs eBPF (Pixie PEM) + 16cpu/64gb → the oracle self-hosted runner, NOT
# ubuntu-latest. Deploy mirrors the sovereignsocdemo lab recipe (k8sstormcenter/soc
# make targets) — that kit is makefile-agent's; keep the deploy block in sync with it.
#
# Uses EXISTING k8sstormcenter/pixie repo secrets (no new ones): PX_DEPLOY_KEY,
# PX_API_KEY (Pixie enroll), DX_ENTLEIN_PAT (private entlein/dx image pull),
# CLICKHOUSE_*_PASSWORD, TAILSCALE_AUTH_KEY. Manual by default (it provisions a
# whole cluster); flip the schedule on once it's green.
name: e2e-log4shell-soc
on:
workflow_dispatch:
inputs:
dx_image:
description: dx-daemon image to test (default = .image-tags pin)
required: false
default: ""
soc_ref:
description: k8sstormcenter/soc branch
required: false
default: "218-clickhouse-schema"
Comment on lines +14 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add concurrency for this host-scoped e2e.

This job mutates k3s state and writes fixed /tmp/evidence; duplicate dispatches can collide or overwrite evidence.

Proposed fix
       soc_ref:
         description: k8sstormcenter/soc branch
         required: false
         default: "218-clickhouse-schema"
+concurrency:
+  group: e2e-log4shell-soc
+  cancel-in-progress: false
 permissions:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
on:
workflow_dispatch:
inputs:
dx_image:
description: dx-daemon image to test (default = .image-tags pin)
required: false
default: ""
soc_ref:
description: k8sstormcenter/soc branch
required: false
default: "218-clickhouse-schema"
on:
workflow_dispatch:
inputs:
dx_image:
description: dx-daemon image to test (default = .image-tags pin)
required: false
default: ""
soc_ref:
description: k8sstormcenter/soc branch
required: false
default: "218-clickhouse-schema"
concurrency:
group: e2e-log4shell-soc
cancel-in-progress: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 14-24: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting

(concurrency-limits)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e_log4shell_soc.yaml around lines 14 - 24, The
workflow_dispatch e2e job currently has no concurrency control, so duplicate
runs can collide on shared k3s state and overwrite /tmp/evidence. Add a
concurrency block to this workflow using a stable group key for the host-scoped
job (for example based on github.workflow plus the selected inputs such as
dx_image and soc_ref), and enable cancel-in-progress or otherwise prevent
overlapping runs in the workflow that defines workflow_dispatch, dx_image, and
soc_ref.

Source: Linters/SAST tools

permissions:
contents: read

jobs:
e2e:
runs-on: oracle-vm-16cpu-64gb-x86-64 # eBPF + 16cpu/64gb; ubuntu-latest cannot run Pixie
timeout-minutes: 90
env:
KUBECONFIG: /etc/rancher/k3s/k3s.yaml
HARNESS: src/e2e_test/adaptive_export_loadtest/harness
steps:
- name: Checkout pixie (harness scripts)
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Comment on lines +36 to +37

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Disable persisted checkout credentials.

The job later runs external repo scripts; leaving the checkout token in local git config unnecessarily exposes the read token to job code.

Proposed fix
     - name: Checkout pixie (harness scripts)
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
+      with:
+        persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout pixie (harness scripts)
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Checkout pixie (harness scripts)
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 36-37: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e_log4shell_soc.yaml around lines 36 - 37, The checkout
in the workflow currently leaves persisted credentials available to later steps,
which can expose the read token to external scripts. Update the existing
actions/checkout usage in the e2e_log4shell_soc job to disable persisted
credentials, keeping the checkout step for the harness scripts but ensuring the
token is not stored in local git config. Refer to the checkout step using
actions/checkout in this workflow and apply the secure checkout setting there.

Source: Linters/SAST tools


- name: Install k3s
run: |
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
for i in $(seq 1 60); do kubectl get nodes --no-headers 2>/dev/null | grep -q ' Ready' && break; sleep 5; done
kubectl get nodes
Comment on lines +39 to +43

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin the k3s version before running the installer.

get.k3s.io installs a moving target; set a validated INSTALL_K3S_VERSION so this privileged e2e is reproducible.

Proposed fix pattern
     - name: Install k3s
       run: |
+        export INSTALL_K3S_VERSION="${INSTALL_K3S_VERSION:?pin the validated k3s version}"
         curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e_log4shell_soc.yaml around lines 39 - 43, The Install
k3s step is using the unpinned get.k3s.io installer, which makes the privileged
e2e environment non-reproducible. Update the k3s install logic in the workflow
step named Install k3s to set a validated INSTALL_K3S_VERSION before invoking
the installer, keeping the rest of the readiness check and kubectl verification
unchanged.


- name: Deploy the SOC stack (Pixie + kubescape + ClickHouse + AE + dx + log4j chain)
env:
PX_CLOUD_ADDR: pixie.austrianopencloudcommunity.org
PX_DEPLOY_KEY: ${{ secrets.PX_DEPLOY_KEY }}
PX_API_KEY: ${{ secrets.PX_API_KEY }}
TS_AUTHKEY: ${{ secrets.TAILSCALE_AUTH_KEY }}
DX_ENTLEIN_PAT: ${{ secrets.DX_ENTLEIN_PAT }} # private entlein/dx image pull
CLICKHOUSE_ANALYST_PASSWORD: ${{ secrets.CLICKHOUSE_ANALYST_PASSWORD }}
CLICKHOUSE_INGEST_PASSWORD: ${{ secrets.CLICKHOUSE_INGEST_PASSWORD }}
CLICKHOUSE_PIXIE_PASSWORD: ${{ secrets.CLICKHOUSE_PIXIE_PASSWORD }}
run: |
set -euo pipefail
sudo apt-get update -qq && sudo apt-get install -y python3-yaml
git clone --depth 1 -b "${{ inputs.soc_ref }}" https://github.com/k8sstormcenter/soc soc
cd soc
make pixie # vizier + AE
make kubescape || true # node-agent (netStreaming)
bash tree/clickhouse-lab/install.sh # forensic_db
make log4j # vulnerable backend + attacker + dx + SBoBs (managed-by=User)
if [ -n "${{ inputs.dx_image }}" ]; then
kubectl -n honey set image ds/dx-daemon dx-daemon="${{ inputs.dx_image }}" || true
fi
# optimal config + enable pprof for the real-life profile (DX_TELEMETRY_CACHE/DX_BENCH
# are defaults in main, set here too in case the kit's manifest predates them)
kubectl -n honey set env ds/dx-daemon DX_PPROF_ADDR=0.0.0.0:6060 DX_TELEMETRY_CACHE=1 DX_BENCH=pemdirect
kubectl -n honey rollout status ds/dx-daemon --timeout=120s
Comment on lines +45 to +70

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Move dispatch inputs out of shell templates and validate them.

${{ inputs.soc_ref }} and ${{ inputs.dx_image }} are expanded before shell parsing. A crafted manual input can break out of quotes and run commands with the secrets in this step.

Proposed fix
       env:
+        SOC_REF: ${{ inputs.soc_ref }}
+        DX_IMAGE: ${{ inputs.dx_image }}
         PX_CLOUD_ADDR: pixie.austrianopencloudcommunity.org
         PX_DEPLOY_KEY: ${{ secrets.PX_DEPLOY_KEY }}
@@
         set -euo pipefail
         sudo apt-get update -qq && sudo apt-get install -y python3-yaml
-        git clone --depth 1 -b "${{ inputs.soc_ref }}" https://github.com/k8sstormcenter/soc soc
+        if ! printf '%s' "$SOC_REF" | grep -Eq '^[A-Za-z0-9._/-]+$'; then
+          echo "Invalid soc_ref"; exit 1
+        fi
+        git clone --depth 1 --branch "$SOC_REF" --single-branch https://github.com/k8sstormcenter/soc soc
@@
-        if [ -n "${{ inputs.dx_image }}" ]; then
-          kubectl -n honey set image ds/dx-daemon dx-daemon="${{ inputs.dx_image }}" || true
+        if [ -n "$DX_IMAGE" ]; then
+          if ! printf '%s' "$DX_IMAGE" | grep -Eq '^[A-Za-z0-9._/:@+-]+$'; then
+            echo "Invalid dx_image"; exit 1
+          fi
+          kubectl -n honey set image ds/dx-daemon "dx-daemon=$DX_IMAGE"
         fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Deploy the SOC stack (Pixie + kubescape + ClickHouse + AE + dx + log4j chain)
env:
PX_CLOUD_ADDR: pixie.austrianopencloudcommunity.org
PX_DEPLOY_KEY: ${{ secrets.PX_DEPLOY_KEY }}
PX_API_KEY: ${{ secrets.PX_API_KEY }}
TS_AUTHKEY: ${{ secrets.TAILSCALE_AUTH_KEY }}
DX_ENTLEIN_PAT: ${{ secrets.DX_ENTLEIN_PAT }} # private entlein/dx image pull
CLICKHOUSE_ANALYST_PASSWORD: ${{ secrets.CLICKHOUSE_ANALYST_PASSWORD }}
CLICKHOUSE_INGEST_PASSWORD: ${{ secrets.CLICKHOUSE_INGEST_PASSWORD }}
CLICKHOUSE_PIXIE_PASSWORD: ${{ secrets.CLICKHOUSE_PIXIE_PASSWORD }}
run: |
set -euo pipefail
sudo apt-get update -qq && sudo apt-get install -y python3-yaml
git clone --depth 1 -b "${{ inputs.soc_ref }}" https://github.com/k8sstormcenter/soc soc
cd soc
make pixie # vizier + AE
make kubescape || true # node-agent (netStreaming)
bash tree/clickhouse-lab/install.sh # forensic_db
make log4j # vulnerable backend + attacker + dx + SBoBs (managed-by=User)
if [ -n "${{ inputs.dx_image }}" ]; then
kubectl -n honey set image ds/dx-daemon dx-daemon="${{ inputs.dx_image }}" || true
fi
# optimal config + enable pprof for the real-life profile (DX_TELEMETRY_CACHE/DX_BENCH
# are defaults in main, set here too in case the kit's manifest predates them)
kubectl -n honey set env ds/dx-daemon DX_PPROF_ADDR=0.0.0.0:6060 DX_TELEMETRY_CACHE=1 DX_BENCH=pemdirect
kubectl -n honey rollout status ds/dx-daemon --timeout=120s
- name: Deploy the SOC stack (Pixie + kubescape + ClickHouse + AE + dx + log4j chain)
env:
SOC_REF: ${{ inputs.soc_ref }}
DX_IMAGE: ${{ inputs.dx_image }}
PX_CLOUD_ADDR: pixie.austrianopencloudcommunity.org
PX_DEPLOY_KEY: ${{ secrets.PX_DEPLOY_KEY }}
PX_API_KEY: ${{ secrets.PX_API_KEY }}
TS_AUTHKEY: ${{ secrets.TAILSCALE_AUTH_KEY }}
DX_ENTLEIN_PAT: ${{ secrets.DX_ENTLEIN_PAT }} # private entlein/dx image pull
CLICKHOUSE_ANALYST_PASSWORD: ${{ secrets.CLICKHOUSE_ANALYST_PASSWORD }}
CLICKHOUSE_INGEST_PASSWORD: ${{ secrets.CLICKHOUSE_INGEST_PASSWORD }}
CLICKHOUSE_PIXIE_PASSWORD: ${{ secrets.CLICKHOUSE_PIXIE_PASSWORD }}
run: |
set -euo pipefail
sudo apt-get update -qq && sudo apt-get install -y python3-yaml
if ! printf '%s' "$SOC_REF" | grep -Eq '^[A-Za-z0-9._/-]+$'; then
echo "Invalid soc_ref"; exit 1
fi
git clone --depth 1 --branch "$SOC_REF" --single-branch https://github.com/k8sstormcenter/soc soc
cd soc
make pixie # vizier + AE
make kubescape || true # node-agent (netStreaming)
bash tree/clickhouse-lab/install.sh # forensic_db
make log4j # vulnerable backend + attacker + dx + SBoBs (managed-by=User)
if [ -n "$DX_IMAGE" ]; then
if ! printf '%s' "$DX_IMAGE" | grep -Eq '^[A-Za-z0-9._/:@+-]+$'; then
echo "Invalid dx_image"; exit 1
fi
kubectl -n honey set image ds/dx-daemon "dx-daemon=$DX_IMAGE"
fi
# optimal config + enable pprof for the real-life profile (DX_TELEMETRY_CACHE/DX_BENCH
# are defaults in main, set here too in case the kit's manifest predates them)
kubectl -n honey set env ds/dx-daemon DX_PPROF_ADDR=0.0.0.0:6060 DX_TELEMETRY_CACHE=1 DX_BENCH=pemdirect
kubectl -n honey rollout status ds/dx-daemon --timeout=120s
🧰 Tools
🪛 zizmor (1.26.1)

[error] 58-58: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 64-64: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 65-65: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e_log4shell_soc.yaml around lines 45 - 70, The deploy
step is interpolating untrusted manual inputs directly into shell commands,
which can allow command injection. In the SOC deployment job, stop embedding
inputs.soc_ref and inputs.dx_image inside the run script and instead pass them
through validated environment variables or precomputed safe outputs before use.
Add strict allowlist-style validation for the ref/image values in the step that
performs git clone and kubectl set image, and only execute the commands after
the values have been verified safe.

Source: Linters/SAST tools


- name: Wait for stack healthy
run: |
set -euo pipefail
kubectl wait --for=condition=Ready pod -l name=adaptive-export -n pl --timeout=300s
kubectl wait --for=condition=Ready pod -l app=dx-daemon -n honey --timeout=300s
kubectl -n pl get pods; kubectl -n honey get pods; kubectl -n log4j-poc get pods
# dx must be non-blind on pemdirect (the optimal default from #29/#33)
kubectl -n honey logs ds/dx-daemon | grep -E "bench=pemdirect|telemetry cache ENABLED" | head

- name: Run canonical harness scripts — assert each actually runs
run: |
set -uo pipefail
mkdir -p /tmp/evidence; fail=0
for s in log4shell_fire exp_matrix nfr exp_row_reconcile; do
echo "::group::$s"
if bash "$HARNESS/$s.sh" > "/tmp/evidence/$s.log" 2>&1; then
echo "PASS $s"; tail -5 "/tmp/evidence/$s.log"
else
echo "FAIL $s (exit $?)"; tail -30 "/tmp/evidence/$s.log"; fail=1
fi
echo "::endgroup::"
done
# detection gate: dx must rule in the log4shell chain (not just run the script)
kubectl -n honey logs ds/dx-daemon | grep -iE "RULE IN|ruled_in" | tee /tmp/evidence/dx_ruleins.txt
if ! grep -qiE "log4shell|control-plane-credential-abuse|RULE IN" \
/tmp/evidence/dx_ruleins.txt; then
echo "NO dx rule-in — detection failed"; fail=1
fi
exit $fail

- name: Profile dx in real life (pprof + metrics)
if: always()
run: |
set -uo pipefail
POD=$(kubectl -n honey get pod -l app=dx-daemon -o jsonpath='{.items[0].metadata.name}')
kubectl -n honey port-forward "$POD" 6060:6060 9095:9095 & PF=$!; sleep 5
# 30s CPU profile under a fresh fire + heap, served by DX_PPROF_ADDR=:6060
( bash "$HARNESS/log4shell_fire.sh" >/dev/null 2>&1 || true ) &
curl -s --max-time 40 -o /tmp/evidence/dx_cpu.pprof \
"http://127.0.0.1:6060/debug/pprof/profile?seconds=30" || true
curl -s "http://127.0.0.1:6060/debug/pprof/heap" -o /tmp/evidence/dx_heap.pprof || true
curl -s "http://127.0.0.1:9095/metrics" -o /tmp/evidence/dx_metrics.txt || true
go tool pprof -top -nodecount=25 /tmp/evidence/dx_cpu.pprof > /tmp/evidence/dx_cpu_top.txt 2>&1 || true
kill $PF 2>/dev/null || true
echo "=== dx CPU top ==="; head -30 /tmp/evidence/dx_cpu_top.txt
echo "=== verdict latency ==="
grep -E \
"dx_(time_to_verdict|bench_query_duration)_seconds_(sum|count)" \
/tmp/evidence/dx_metrics.txt || true
Comment on lines +102 to +120

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Make the always-on profiling step failure-safe.

If earlier steps fail before /tmp/evidence or the dx pod exists, this step silently loses profile artifacts. Create the directory and record an explicit skip.

Proposed fix
       run: |
         set -uo pipefail
-        POD=$(kubectl -n honey get pod -l app=dx-daemon -o jsonpath='{.items[0].metadata.name}')
+        mkdir -p /tmp/evidence
+        POD=$(kubectl -n honey get pod -l app=dx-daemon -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
+        if [ -z "$POD" ]; then
+          echo "dx-daemon pod not found; profiling skipped" | tee /tmp/evidence/profile_skipped.txt
+          exit 0
+        fi
         kubectl -n honey port-forward "$POD" 6060:6060 9095:9095 & PF=$!; sleep 5
+        trap 'kill "$PF" 2>/dev/null || true' EXIT
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Profile dx in real life (pprof + metrics)
if: always()
run: |
set -uo pipefail
POD=$(kubectl -n honey get pod -l app=dx-daemon -o jsonpath='{.items[0].metadata.name}')
kubectl -n honey port-forward "$POD" 6060:6060 9095:9095 & PF=$!; sleep 5
# 30s CPU profile under a fresh fire + heap, served by DX_PPROF_ADDR=:6060
( bash "$HARNESS/log4shell_fire.sh" >/dev/null 2>&1 || true ) &
curl -s --max-time 40 -o /tmp/evidence/dx_cpu.pprof \
"http://127.0.0.1:6060/debug/pprof/profile?seconds=30" || true
curl -s "http://127.0.0.1:6060/debug/pprof/heap" -o /tmp/evidence/dx_heap.pprof || true
curl -s "http://127.0.0.1:9095/metrics" -o /tmp/evidence/dx_metrics.txt || true
go tool pprof -top -nodecount=25 /tmp/evidence/dx_cpu.pprof > /tmp/evidence/dx_cpu_top.txt 2>&1 || true
kill $PF 2>/dev/null || true
echo "=== dx CPU top ==="; head -30 /tmp/evidence/dx_cpu_top.txt
echo "=== verdict latency ==="
grep -E \
"dx_(time_to_verdict|bench_query_duration)_seconds_(sum|count)" \
/tmp/evidence/dx_metrics.txt || true
- name: Profile dx in real life (pprof + metrics)
if: always()
run: |
set -uo pipefail
mkdir -p /tmp/evidence
POD=$(kubectl -n honey get pod -l app=dx-daemon -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)
if [ -z "$POD" ]; then
echo "dx-daemon pod not found; profiling skipped" | tee /tmp/evidence/profile_skipped.txt
exit 0
fi
kubectl -n honey port-forward "$POD" 6060:6060 9095:9095 & PF=$!; sleep 5
trap 'kill "$PF" 2>/dev/null || true' EXIT
# 30s CPU profile under a fresh fire + heap, served by DX_PPROF_ADDR=:6060
( bash "$HARNESS/log4shell_fire.sh" >/dev/null 2>&1 || true ) &
curl -s --max-time 40 -o /tmp/evidence/dx_cpu.pprof \
"http://127.0.0.1:6060/debug/pprof/profile?seconds=30" || true
curl -s "http://127.0.0.1:6060/debug/pprof/heap" -o /tmp/evidence/dx_heap.pprof || true
curl -s "http://127.0.0.1:9095/metrics" -o /tmp/evidence/dx_metrics.txt || true
go tool pprof -top -nodecount=25 /tmp/evidence/dx_cpu.pprof > /tmp/evidence/dx_cpu_top.txt 2>&1 || true
kill $PF 2>/dev/null || true
echo "=== dx CPU top ==="; head -30 /tmp/evidence/dx_cpu_top.txt
echo "=== verdict latency ==="
grep -E \
"dx_(time_to_verdict|bench_query_duration)_seconds_(sum|count)" \
/tmp/evidence/dx_metrics.txt || true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/e2e_log4shell_soc.yaml around lines 102 - 120, The
“Profile dx in real life (pprof + metrics)” step is not failure-safe when prior
setup fails, so it can’t write artifacts or clearly indicate it was skipped. In
the workflow job, update this step to create /tmp/evidence before any writes and
to explicitly detect missing prerequisites like the dx-daemon pod or a failed
port-forward. Use the existing shell block in the profiling step to emit a clear
skip message and exit successfully when those prerequisites are absent, while
keeping the profiling and metric collection logic intact when they are present.


- name: Upload evidence + profiles
if: always()
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: e2e-log4shell-evidence
path: /tmp/evidence/
retention-days: 14
6 changes: 6 additions & 0 deletions .github/workflows/filename_linter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ jobs:
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
with:
# Fork carve-out: private/cockpit/ is LEGITIMATE fork config for the
# pixie-cloud deployment. It predates upstream's filename_linter and
# was deleted upstream by the cert-manager migration (#2391); restoring
# it at its original path re-trips this guard, so negative-glob it while
# keeping the "no private/* leaks" intent for everything else.
filters: |
private:
- '**/*private*/**'
- '**/*private*'
- '!private/cockpit/**'
- name: Fail on private
if: ${{ steps.changes.outputs.private == 'true' }}
run: echo "This repo disallows dirnames or filenames with 'private' in it." && exit 1
5 changes: 5 additions & 0 deletions .sops.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
# az login -t 1e8a0c86-2410-4f48-91c3-dc1d164680ca
creation_rules:
- path_regex: terraform/credentials/cockpit
azure_keyvault: https://kv-pixie-cloud.vault.azure.net/keys/sops-key
9 changes: 9 additions & 0 deletions private/cockpit/artifact_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pl-artifact-config
data:
PL_ARTIFACT_MANIFEST_URL: https://k8sstormcenter.github.io/pixie/artifacts/manifest.json
PL_ARTIFACT_BUCKET: ""
PL_SA_KEY_PATH: ""
24 changes: 24 additions & 0 deletions private/cockpit/auth_deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-server
labels:
db: pgsql
spec:
template:
spec:
containers:
- name: auth-server
env:
- name: PL_AUTH0_CLIENT_ID
valueFrom:
secretKeyRef:
name: cloud-auth0-secrets
key: auth0-client-id
optional: true
Comment on lines +14 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the client ID lookup mandatory too.

PL_AUTH0_CLIENT_ID and PL_AUTH0_CLIENT_SECRET come from the same cloud-auth0-secrets object. Leaving only the ID optional hides a broken secret and turns it into a runtime auth failure instead of a clear deployment error.

💡 Proposed fix
         - name: PL_AUTH0_CLIENT_ID
           valueFrom:
             secretKeyRef:
               name: cloud-auth0-secrets
               key: auth0-client-id
-              optional: true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: PL_AUTH0_CLIENT_ID
valueFrom:
secretKeyRef:
name: cloud-auth0-secrets
key: auth0-client-id
optional: true
- name: PL_AUTH0_CLIENT_ID
valueFrom:
secretKeyRef:
name: cloud-auth0-secrets
key: auth0-client-id
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cockpit/auth_deployment.yaml` around lines 14 - 19, Make the
PL_AUTH0_CLIENT_ID secret lookup mandatory as well, since it comes from the same
cloud-auth0-secrets object as PL_AUTH0_CLIENT_SECRET. Update the secretKeyRef
for PL_AUTH0_CLIENT_ID in the auth deployment manifest to remove the optional
lookup, matching the behavior already used for the client secret so missing or
broken secrets fail at deployment time.

- name: PL_AUTH0_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: cloud-auth0-secrets
key: auth0-client-secret
79 changes: 79 additions & 0 deletions private/cockpit/cloud_ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cloud-ingress
namespace: plc
annotations:
external-dns.alpha.kubernetes.io/hostname: >-
test.austrianopencloudcommunity.org,work.test.austrianopencloudcommunity.org
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- test.austrianopencloudcommunity.org
- work.test.austrianopencloudcommunity.org
secretName: cloud-proxy-tls-certs
rules:
- host: test.austrianopencloudcommunity.org
http:
paths:
- path: /px.services
pathType: Prefix
backend:
service:
name: vzconn-service
port:
number: 51600
- path: /px.cloudapi
pathType: Prefix
backend:
service:
name: api-service
port:
number: 51200
- path: /px.api
pathType: Prefix
backend:
service:
name: cloud-proxy-service
port:
number: 4444
- path: /
pathType: Prefix
backend:
service:
name: cloud-proxy-service
port:
number: 443
- host: work.test.austrianopencloudcommunity.org
http:
paths:
- path: /px.services
pathType: Prefix
backend:
service:
name: vzconn-service
port:
number: 51600
- path: /px.cloudapi
pathType: Prefix
backend:
service:
name: api-service
port:
number: 51200
- path: /px.api
pathType: Prefix
backend:
service:
name: cloud-proxy-service
port:
number: 4444
- path: /
pathType: Prefix
backend:
service:
name: cloud-proxy-service
port:
number: 443
8 changes: 8 additions & 0 deletions private/cockpit/domain_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pl-domain-config
data:
PL_DOMAIN_NAME: test.austrianopencloudcommunity.org

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Don't hard-code a second source of truth for the public domain.

The cert/Auth0 layer is parameterized by cloud_domain, but this ConfigMap bakes in test.austrianopencloudcommunity.org. As soon as those values diverge, workloads will advertise URLs and callbacks that no longer match ingress or TLS. Feed PL_DOMAIN_NAME from the same domain input instead of a literal.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cockpit/domain_config.yaml` at line 7, PL_DOMAIN_NAME is hard-coded to a
specific public domain, creating a second source of truth that can drift from
the configured cloud_domain. Update the domain config so PL_DOMAIN_NAME is
derived from the same domain input used by the cert/Auth0 layer rather than a
literal, and keep the value wired through the existing configuration path that
populates this ConfigMap.

PASSTHROUGH_PROXY_PORT: ""
45 changes: 45 additions & 0 deletions private/cockpit/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: plc
replicas:
- name: api-server
count: 1
- name: auth-server
count: 1
- name: profile-server
count: 1
- name: cloud-proxy
count: 1
- name: project-manager-server
count: 1
- name: vzmgr-server
count: 1
- name: scriptmgr-server
count: 1
resources:
- ../../k8s/cloud/base
- plugin_db_updater_job.yaml
- oauth_config.yaml
components:
- ../../k8s/cloud/overlays/exposed_services_traefik
labels:
- includeSelectors: true
pairs:
app: pl-cloud
patches:
- path: artifact_config.yaml
- path: auth_deployment.yaml
- path: domain_config.yaml
- path: script_bundles_config.yaml
- path: proxy_envoy.yaml
- path: cloud_ingress.yaml
target:
kind: Ingress
name: cloud-ingress
- path: servers_transport.yaml
target:
group: traefik.io
version: v1alpha1
kind: ServersTransport
name: cloud-backend-transport
10 changes: 10 additions & 0 deletions private/cockpit/oauth_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pl-oauth-config
data:
PL_OAUTH_PROVIDER: auth0
PL_AUTH_URI: dev-ylinrwd1tckmhm03.us.auth0.com
PL_AUTH_CLIENT_ID: rDOrqnuIaTsXiya5I41b1FkNzXOQfWbW
PL_AUTH_EMAIL_PASSWORD_CONN: Username-Password-Authentication
Loading
Loading