Skip to content

Commit e9f25f4

Browse files
corneliusludmannCornelius Ludmannona-agentgeropl
authored
Replace npx with pinned npm-tools and add security hardening (#21166)
* [dev] disable npm lifecycle scripts and npx * Add npm-tools * update npm-tools * dev/image/Dockerfile * update Co-authored-by: Ona <no-reply@ona.com> * Bump leeay version to 0.10.6 Co-authored-by: Ona <no-reply@ona.com> * Fix npx removal to also delete the target script The symlink at /root/.nvm/.../bin/npx points to npx-cli.js. Remove both to ensure npx is fully disabled. Co-authored-by: Ona <no-reply@ona.com> * Remove gce-github-runner usage from all workflows Replace self-hosted GCE runner pattern with GitHub-hosted ubuntu-latest runners across all workflows. This removes the three-phase pattern (create-runner, use-runner, delete-runner) and simplifies workflow execution. Changes: - Remove create-runner and delete-runner jobs from all workflows - Replace runs-on: ${{ needs.create-runner.outputs.label }} with runs-on: ubuntu-latest - Remove create-runner from job dependencies - Preserve all other job dependencies and concurrency controls Affected workflows: - build.yml (8 jobs) - workspace-integration-tests.yml (4 jobs) - ide-integration-tests.yml (4 jobs) - preview-env-check-regressions.yml (4 jobs) - preview-env-gc.yml (2 jobs) - jetbrains-auto-update-template.yml (1 job) - jetbrains-integration-test.yml (1 job) - code-nightly.yml (1 job) - preview-env-delete.yml (1 job) Co-authored-by: Ona <no-reply@ona.com> * [dev] use ubuntu-latest-16-cores for builds * Fix container permissions for GitHub-hosted runners Add 'options: --user root' to all container configurations to resolve EACCES permission errors when GitHub Actions tries to write to internal directories. GitHub-hosted runners require containers to run as root to allow the Actions runtime to write to /__w/_temp/_runner_file_commands/ and other internal paths. Affected workflows: - build.yml (3 container jobs) - workspace-integration-tests.yml (2 container jobs) - ide-integration-tests.yml (2 container jobs) - preview-env-check-regressions.yml (1 container job) - preview-env-gc.yml (1 container job) - jetbrains-auto-update-template.yml (1 container job) - jetbrains-integration-test.yml (1 container job) - code-nightly.yml (1 container job) Co-authored-by: Ona <no-reply@ona.com> * Fix dev/image build by adding leeway dependency for npm-tools Create leeway generic build for dev/npm-tools and use it as a dependency in dev/image:docker build. This resolves the build error where npm-tools files were not accessible during Docker build. Changes: - Add dev/npm-tools/BUILD.yaml with generic package containing package.json and package-lock.json - Add dev/npm-tools:pkg as dependency in dev/image/BUILD.yaml - Update Dockerfile to use COPY from leeway dependency path (dev-npm-tools--pkg/) This follows the established pattern used in other builds like install/installer where dependencies are copied from leeway-generated paths. Co-authored-by: Ona <no-reply@ona.com> * Fix npm-tools installation permissions in dev/image Add chown command to fix EACCES permission error when installing npm-tools. The COPY command creates files owned by root, but npm ci runs as gitpod user and needs write access to create node_modules. Changes: - Add 'sudo chown -R gitpod:gitpod /opt/npm-tools' before npm ci - This ensures the gitpod user can write to /opt/npm-tools/node_modules/ Error fixed: npm error code EACCES npm error syscall mkdir npm error path /opt/npm-tools/node_modules npm error errno -13 Co-authored-by: Ona <no-reply@ona.com> * [dev] Split builds into branch and main Co-authored-by: Ona <no-reply@ona.com> --------- Co-authored-by: Cornelius Ludmann <cornelius@ona.com> Co-authored-by: Ona <no-reply@ona.com> Co-authored-by: Gero Posmyk-Leinemann <gero@gitpod.io>
1 parent f650690 commit e9f25f4

24 files changed

+4388
-263
lines changed

.devcontainer/Dockerfile

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ ARG TARGETOS
9393

9494
# Install dependencies
9595
USER root
96-
ARG LEEWAY_VERSION=0.10.4
96+
ARG LEEWAY_VERSION=0.10.6
9797
ENV LEEWAY_MAX_PROVENANCE_BUNDLE_SIZE=8388608
9898
ENV LEEWAY_WORKSPACE_ROOT=/workspace/gitpod
9999
ENV LEEWAY_REMOTE_CACHE_BUCKET=leeway-cache-dev-3ac8ef5
@@ -334,8 +334,32 @@ ENV HOME=/root
334334
RUN curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash \
335335
&& bash -c ". $HOME/.nvm/nvm.sh \
336336
&& nvm install v${NODE_VERSION} \
337-
&& nvm alias default v${NODE_VERSION} \
338-
&& npm install -g typescript yarn pnpm node-gyp @anthropic-ai/claude-code"
337+
&& nvm alias default v${NODE_VERSION}"
338+
339+
# Disable npm/yarn lifecycle scripts by default (security hardening)
340+
# To allow specific packages, use: npm rebuild <package> or yarn rebuild <package>
341+
RUN npm config set ignore-scripts true --location=global && \
342+
npm config set ignore-scripts true --location=user && \
343+
echo 'ignore-scripts true' >> ~/.yarnrc
344+
345+
# Disable npx (security hardening - prevents arbitrary package execution)
346+
# Remove npx from NVM and replace with stub that prints warning
347+
RUN rm -f /usr/bin/npx /usr/local/bin/npx && \
348+
rm -f /root/.nvm/versions/node/v${NODE_VERSION}/bin/npx && \
349+
rm -f /root/.nvm/versions/node/v${NODE_VERSION}/lib/node_modules/npm/bin/npx-cli.js && \
350+
echo '#!/bin/sh' > /usr/local/bin/npx && \
351+
echo 'echo "npx is disabled for security reasons. Use explicit package installation instead." >&2' >> /usr/local/bin/npx && \
352+
echo 'exit 1' >> /usr/local/bin/npx && \
353+
chmod +x /usr/local/bin/npx
354+
355+
# Install npm-tools with locked dependencies
356+
COPY dev/npm-tools/package.json dev/npm-tools/package-lock.json /opt/npm-tools/
357+
RUN cd /opt/npm-tools && \
358+
npm ci && \
359+
for bin in /opt/npm-tools/node_modules/.bin/*; do \
360+
ln -sf "$bin" /usr/local/bin/$(basename "$bin"); \
361+
done && \
362+
rm -rf ~/.npm/_cacache
339363

340364
ENV PATH=$PATH:/root/.aws-iam:/root/.terraform:/workspace/bin
341365

.github/workflows/branch-build.yml

Lines changed: 593 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/build.yml

Lines changed: 27 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ permissions:
66
actions: write # This is required for trigger another action which is used by JetBrains integrateion tests
77
packages: read
88
on:
9-
pull_request:
10-
types: [ opened, edited ]
119
push:
10+
branches:
11+
- main
1212
workflow_dispatch:
1313
inputs:
1414
recreate_vm:
@@ -29,19 +29,10 @@ on:
2929
- cron: '0 0 * * *'
3030

3131
jobs:
32-
create-runner:
33-
uses: gitpod-io/gce-github-runner/.github/workflows/create-vm.yml@main
34-
secrets:
35-
runner_token: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_TOKEN }}
36-
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
37-
concurrency:
38-
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-create-runner
39-
cancel-in-progress: false
40-
4132
configuration:
4233
name: Configure job parameters
43-
runs-on: ${{ needs.create-runner.outputs.label }}
44-
needs: [ create-runner ]
34+
runs-on: ubuntu-latest
35+
environment: main-build
4536
concurrency:
4637
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-configuration
4738
cancel-in-progress: true
@@ -112,13 +103,15 @@ jobs:
112103
(needs.configuration.outputs.pr_no_diff_skip != 'true') &&
113104
(needs.configuration.outputs.preview_enable == 'true') &&
114105
(needs.configuration.outputs.is_scheduled_run != 'true')
115-
needs: [ configuration, create-runner ]
106+
needs: [ configuration ]
107+
environment: main-build
116108
concurrency:
117109
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-build-previewctl
118110
cancel-in-progress: ${{ needs.configuration.outputs.is_main_branch == 'false' }}
119-
runs-on: ${{ needs.create-runner.outputs.label }}
111+
runs-on: ubuntu-latest-16-cores
120112
container:
121113
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.33389
114+
options: --user root
122115
steps:
123116
- uses: actions/checkout@v4
124117
- name: Setup Environment
@@ -135,13 +128,14 @@ jobs:
135128
run: |
136129
leeway build dev/preview/previewctl:cli --cache remote
137130
infrastructure:
138-
needs: [ configuration, build-previewctl, create-runner ]
131+
needs: [ configuration, build-previewctl ]
132+
environment: main-build
139133
if: |
140134
(needs.configuration.outputs.pr_no_diff_skip != 'true') &&
141135
(needs.configuration.outputs.preview_enable == 'true') &&
142136
(needs.configuration.outputs.is_main_branch != 'true') &&
143137
(needs.configuration.outputs.is_scheduled_run != 'true')
144-
runs-on: ${{ needs.create-runner.outputs.label }}
138+
runs-on: ubuntu-latest
145139
concurrency:
146140
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-infrastructure
147141
cancel-in-progress: true
@@ -166,8 +160,9 @@ jobs:
166160

167161
build-gitpod:
168162
name: Build Gitpod
169-
needs: [ configuration, create-runner ]
170-
runs-on: ${{ needs.create-runner.outputs.label }}
163+
needs: [ configuration ]
164+
environment: main-build
165+
runs-on: ubuntu-latest-16-cores
171166
outputs:
172167
affected_packages: ${{ steps.check_vulnerabilities.outputs.affected_packages }}
173168
concurrency:
@@ -189,6 +184,7 @@ jobs:
189184
- 6379:6379
190185
container:
191186
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.33389
187+
options: --user root
192188
env:
193189
DB_HOST: "mysql"
194190
DB_PORT: "23306"
@@ -399,8 +395,9 @@ jobs:
399395
name: vulnerability-reports
400396
path: ${{ steps.scan.outputs.leeway_vulnerability_reports_dir }}
401397
install-app:
402-
runs-on: ${{ needs.create-runner.outputs.label }}
403-
needs: [ configuration, build-gitpod, create-runner ]
398+
runs-on: ubuntu-latest
399+
needs: [ configuration, build-gitpod ]
400+
environment: main-build
404401
if: ${{ needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true' }}
405402
strategy:
406403
fail-fast: false
@@ -439,9 +436,9 @@ jobs:
439436
- build-previewctl
440437
- build-gitpod
441438
- infrastructure
442-
- create-runner
439+
environment: main-build
443440
if: needs.configuration.outputs.is_scheduled_run != 'true'
444-
runs-on: ${{ needs.create-runner.outputs.label }}
441+
runs-on: ubuntu-latest
445442
concurrency:
446443
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-install
447444
cancel-in-progress: ${{ needs.configuration.outputs.is_main_branch == 'false' }}
@@ -489,8 +486,9 @@ jobs:
489486
490487
monitoring:
491488
name: "Install Monitoring Satellite"
492-
needs: [ infrastructure, build-previewctl, create-runner ]
493-
runs-on: ${{ needs.create-runner.outputs.label }}
489+
needs: [ infrastructure, build-previewctl ]
490+
environment: main-build
491+
runs-on: ubuntu-latest
494492
if: needs.configuration.outputs.with_monitoring == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
495493
concurrency:
496494
group: ${{ github.ref == 'refs/heads/main' && github.run_id || github.sha }}-monitoring
@@ -518,10 +516,11 @@ jobs:
518516
- build-gitpod
519517
- infrastructure
520518
- install
521-
- create-runner
522-
runs-on: ${{ needs.create-runner.outputs.label }}
519+
environment: main-build
520+
runs-on: ubuntu-latest
523521
container:
524522
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.33389
523+
options: --user root
525524
if: needs.configuration.outputs.with_integration_tests != '' && needs.configuration.outputs.is_scheduled_run != 'true'
526525
concurrency:
527526
group: ${{ needs.configuration.outputs.preview_name }}-integration-test
@@ -551,7 +550,6 @@ jobs:
551550
needs:
552551
- configuration
553552
- build-gitpod
554-
- create-runner
555553
if: needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
556554
uses: ./.github/workflows/workspace-integration-tests.yml
557555
with:
@@ -563,7 +561,6 @@ jobs:
563561
needs:
564562
- configuration
565563
- build-gitpod
566-
- create-runner
567564
if: needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
568565
uses: ./.github/workflows/code-updates.yml
569566
secrets: inherit
@@ -573,7 +570,6 @@ jobs:
573570
needs:
574571
- configuration
575572
- build-gitpod
576-
- create-runner
577573
if: needs.configuration.outputs.is_main_branch == 'true' && needs.configuration.outputs.is_scheduled_run != 'true'
578574
uses: ./.github/workflows/jetbrains-updates.yml
579575
secrets: inherit
@@ -587,6 +583,7 @@ jobs:
587583
- workspace-integration-tests-main
588584
- ide-code-updates
589585
- ide-jb-updates
586+
environment: main-build
590587
runs-on: ubuntu-latest
591588
steps:
592589
- name: Slack Notification
@@ -598,23 +595,3 @@ jobs:
598595
SLACK_COLOR: "danger"
599596
SLACK_MESSAGE: "⚠️ Security Alert: Daily vulnerability scan detected critical vulnerabilities in the following packages:\n${{ needs.build-gitpod.outputs.affected_packages }}"
600597
SLACK_FOOTER: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Workflow Logs>"
601-
602-
delete-runner:
603-
if: always()
604-
needs:
605-
- create-runner
606-
- configuration
607-
- build-previewctl
608-
- infrastructure
609-
- build-gitpod
610-
- install-app
611-
- install
612-
- monitoring
613-
- integration-test
614-
- notify-scheduled-failure
615-
uses: gitpod-io/gce-github-runner/.github/workflows/delete-vm.yml@main
616-
secrets:
617-
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
618-
with:
619-
runner-label: ${{ needs.create-runner.outputs.label }}
620-
machine-zone: ${{ needs.create-runner.outputs.machine-zone }}

.github/workflows/code-build.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ jobs:
1515
run: |
1616
curl -fsSL https://github.com/csweichel/oci-tool/releases/download/v0.2.1/oci-tool_0.2.1_linux_amd64.tar.gz | tar xz -C /usr/local/bin
1717
chmod +x /usr/local/bin/oci-tool
18-
cd ./components/ide/gha-update-image/
18+
cd ./dev/npm-tools && npm ci
19+
echo "$PWD/node_modules/.bin" >> $GITHUB_PATH
20+
cd $GITHUB_WORKSPACE/components/ide/gha-update-image/
1921
yarn
20-
npm i -g bun
2122
- name: Check for updates
2223
id: updates
2324
run: |

.github/workflows/code-nightly.yml

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,11 @@ on:
88
- cron: "0 0 * * *"
99

1010
jobs:
11-
create-runner:
12-
uses: gitpod-io/gce-github-runner/.github/workflows/create-vm.yml@main
13-
secrets:
14-
runner_token: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_TOKEN }}
15-
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
16-
1711
build:
18-
runs-on: ${{ needs.create-runner.outputs.label }}
19-
needs: [create-runner]
12+
runs-on: ubuntu-latest
2013
container:
2114
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.33389
15+
options: --user root
2216
steps:
2317
- uses: actions/checkout@v4
2418
- uses: ./.github/actions/setup-environment
@@ -56,15 +50,3 @@ jobs:
5650
SLACK_WEBHOOK: ${{ secrets.IDE_SLACK_WEBHOOK }}
5751
SLACK_COLOR: ${{ job.status }}
5852
SLACK_FOOTER: "<https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|Workflow logs>"
59-
60-
delete-runner:
61-
if: always()
62-
needs:
63-
- create-runner
64-
- build
65-
uses: gitpod-io/gce-github-runner/.github/workflows/delete-vm.yml@main
66-
secrets:
67-
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
68-
with:
69-
runner-label: ${{ needs.create-runner.outputs.label }}
70-
machine-zone: ${{ needs.create-runner.outputs.machine-zone }}

.github/workflows/code-updates.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ jobs:
1212
run: |
1313
curl -fsSL https://github.com/csweichel/oci-tool/releases/download/v0.2.1/oci-tool_0.2.1_linux_amd64.tar.gz | tar xz -C /usr/local/bin
1414
chmod +x /usr/local/bin/oci-tool
15-
cd ./components/ide/gha-update-image/
15+
cd ./dev/npm-tools && npm ci
16+
echo "$PWD/node_modules/.bin" >> $GITHUB_PATH
17+
cd $GITHUB_WORKSPACE/components/ide/gha-update-image/
1618
yarn
17-
npm i -g bun
1819
- name: Check for updates
1920
id: updates
2021
run: |

.github/workflows/ide-integration-tests.yml

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,12 @@ on:
3232
- cron: "0 3 * * *"
3333

3434
jobs:
35-
create-runner:
36-
uses: gitpod-io/gce-github-runner/.github/workflows/create-vm.yml@main
37-
secrets:
38-
runner_token: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_TOKEN }}
39-
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
40-
4135
configuration:
4236
name: Configuration
43-
runs-on: ${{ needs.create-runner.outputs.label }}
44-
needs: [create-runner]
37+
runs-on: ubuntu-latest
4538
container:
4639
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.33389
40+
options: --user root
4741
outputs:
4842
name: ${{ steps.configuration.outputs.name }}
4943
version: ${{ steps.configuration.outputs.version }}
@@ -96,8 +90,8 @@ jobs:
9690

9791
infrastructure:
9892
name: Create preview environment infrastructure
99-
needs: [configuration, create-runner]
100-
runs-on: ${{ needs.create-runner.outputs.label }}
93+
needs: [configuration]
94+
runs-on: ubuntu-latest
10195
concurrency:
10296
group: ${{ needs.configuration.outputs.name }}-infrastructure
10397
steps:
@@ -128,10 +122,11 @@ jobs:
128122

129123
check:
130124
name: Check for regressions
131-
needs: [configuration, infrastructure, create-runner]
132-
runs-on: ${{ needs.create-runner.outputs.label }}
125+
needs: [configuration, infrastructure]
126+
runs-on: ubuntu-latest
133127
container:
134128
image: eu.gcr.io/gitpod-core-dev/dev/dev-environment:main-gha.33389
129+
options: --user root
135130
volumes:
136131
- /var/tmp:/var/tmp
137132
- /tmp:/tmp
@@ -216,9 +211,9 @@ jobs:
216211

217212
delete:
218213
name: Delete preview environment
219-
needs: [configuration, infrastructure, check, create-runner]
214+
needs: [configuration, infrastructure, check]
220215
if: github.event.inputs.skip_delete != 'true' && always()
221-
runs-on: ${{ needs.create-runner.outputs.label }}
216+
runs-on: ubuntu-latest
222217
steps:
223218
- uses: actions/checkout@v4
224219
- name: Setup Environment
@@ -231,18 +226,3 @@ jobs:
231226
uses: ./.github/actions/delete-preview
232227
with:
233228
name: ${{ needs.configuration.outputs.name }}
234-
235-
delete-runner:
236-
if: always()
237-
needs:
238-
- create-runner
239-
- configuration
240-
- infrastructure
241-
- check
242-
- delete
243-
uses: gitpod-io/gce-github-runner/.github/workflows/delete-vm.yml@main
244-
secrets:
245-
gcp_credentials: ${{ secrets.SELF_HOSTED_GITHUB_RUNNER_GCP_CREDENTIALS }}
246-
with:
247-
runner-label: ${{ needs.create-runner.outputs.label }}
248-
machine-zone: ${{ needs.create-runner.outputs.machine-zone }}

0 commit comments

Comments
 (0)