mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
core: harden npm install against supply-chain attacks (#22245)
* core: add .npmrc baseline to block dependency lifecycle scripts Set ignore-scripts=true at the repo root, plus engine-strict, save-exact, audit, and prefer-offline. This neutralizes the dominant npm supply-chain attack vector — postinstall scripts in transitive dependencies — at the cost of requiring an explicit rebuild for the handful of packages that legitimately need install scripts (esbuild, chromedriver, tree-sitter, tree-sitter-json). The next commit wires that rebuild into the Makefile. Co-Authored-By: Playpen Agent <279763771+playpen-agent@users.noreply.github.com> * core: route node installs through make to retire website preinstall hook Make docs-install depend on a new root-node-install so the root deps are guaranteed before the website install runs, removing the need for the website/preinstall lifecycle script. Rebuild the small audited list of trusted packages (esbuild, chromedriver, tree-sitter, tree-sitter-json) after the web install so ignore-scripts=true remains the only path that needs maintenance. web/README documents the new workflow. Co-Authored-By: Playpen Agent <279763771+playpen-agent@users.noreply.github.com> * Clean up install scripts. * Track .npmrc in CODEOWNERS --------- Co-authored-by: Playpen Agent <279763771+playpen-agent@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
# Block lifecycle scripts (preinstall/install/postinstall/prepare) from dependencies.
|
||||||
|
# This neutralizes the dominant npm supply-chain attack vector.
|
||||||
|
#
|
||||||
|
# Packages that legitimately need a build step (e.g. esbuild, chromedriver, tree-sitter)
|
||||||
|
# must be rebuilt explicitly:
|
||||||
|
#
|
||||||
|
# npm rebuild --foreground-scripts esbuild chromedriver tree-sitter tree-sitter-json
|
||||||
|
ignore-scripts=true
|
||||||
|
|
||||||
|
# Fail fast if the active Node/npm doesn't match the "engines" field.
|
||||||
|
engine-strict=true
|
||||||
|
|
||||||
|
# Pin exact versions so `npm install <pkg>` writes "1.2.3" not "^1.2.3".
|
||||||
|
save-exact=true
|
||||||
|
|
||||||
|
# Surface CVE warnings during install; doesn't block.
|
||||||
|
audit=true
|
||||||
|
|
||||||
|
# Suppress funding banners.
|
||||||
|
fund=false
|
||||||
@@ -34,6 +34,7 @@ packages/django-channels-postgres @goauthentik/backend
|
|||||||
packages/django-postgres-cache @goauthentik/backend
|
packages/django-postgres-cache @goauthentik/backend
|
||||||
packages/django-dramatiq-postgres @goauthentik/backend
|
packages/django-dramatiq-postgres @goauthentik/backend
|
||||||
# Web packages
|
# Web packages
|
||||||
|
.npmrc @goauthentik/frontend
|
||||||
tsconfig.json @goauthentik/frontend
|
tsconfig.json @goauthentik/frontend
|
||||||
package.json @goauthentik/frontend
|
package.json @goauthentik/frontend
|
||||||
package-lock.json @goauthentik/frontend
|
package-lock.json @goauthentik/frontend
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ core-i18n-extract:
|
|||||||
--ignore website \
|
--ignore website \
|
||||||
-l en
|
-l en
|
||||||
|
|
||||||
install: node-install docs-install core-install ## Install all requires dependencies for `node`, `docs` and `core`
|
install: node-install web-install core-install ## Install all requires dependencies for `node`, `web` and `core`
|
||||||
|
|
||||||
dev-drop-db:
|
dev-drop-db:
|
||||||
$(eval pg_user := $(shell $(UV) run python -m authentik.lib.config postgresql.user 2>/dev/null))
|
$(eval pg_user := $(shell $(UV) run python -m authentik.lib.config postgresql.user 2>/dev/null))
|
||||||
@@ -228,14 +228,26 @@ gen-dev-config: ## Generate a local development config file
|
|||||||
## Node.js
|
## Node.js
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
|
# Packages whose install/postinstall scripts are required for correct
|
||||||
|
# operation (binary downloads, native bindings). The root .npmrc sets
|
||||||
|
# `ignore-scripts=true` to block dependency lifecycle scripts by default;
|
||||||
|
# this list is rebuilt explicitly with scripts re-enabled. Audit any
|
||||||
|
# additions: each entry runs arbitrary code at install time.
|
||||||
|
TRUSTED_INSTALL_SCRIPTS := esbuild chromedriver tree-sitter tree-sitter-json
|
||||||
|
|
||||||
node-install: ## Install the necessary libraries to build Node.js packages
|
node-install: ## Install the necessary libraries to build Node.js packages
|
||||||
npm ci
|
npm ci
|
||||||
npm ci --prefix web
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
## Web
|
## Web
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
|
web-install: ## Install the necessary libraries to build the Authentik UI
|
||||||
|
npm ci --prefix web
|
||||||
|
|
||||||
|
web-postinstall: ## Trigger postinstall scripts for packages with native bindings or binary downloads, which are blocked by default for security reasons.
|
||||||
|
npm rebuild --prefix web --ignore-scripts=false --foreground-scripts $(TRUSTED_INSTALL_SCRIPTS)
|
||||||
|
|
||||||
web-build: node-install ## Build the Authentik UI
|
web-build: node-install ## Build the Authentik UI
|
||||||
npm run --prefix web build
|
npm run --prefix web build
|
||||||
|
|
||||||
@@ -268,7 +280,7 @@ web-i18n-extract:
|
|||||||
|
|
||||||
docs: docs-lint-fix docs-build ## Automatically fix formatting issues in the Authentik docs source code, lint the code, and compile it
|
docs: docs-lint-fix docs-build ## Automatically fix formatting issues in the Authentik docs source code, lint the code, and compile it
|
||||||
|
|
||||||
docs-install:
|
docs-install: node-install
|
||||||
npm ci --prefix website
|
npm ci --prefix website
|
||||||
|
|
||||||
docs-lint-fix: lint-spellcheck
|
docs-lint-fix: lint-spellcheck
|
||||||
|
|||||||
@@ -3,6 +3,27 @@
|
|||||||
This is the default UI for the authentik server. The documentation is going to be a little sparse
|
This is the default UI for the authentik server. The documentation is going to be a little sparse
|
||||||
for awhile, but at least let's get started.
|
for awhile, but at least let's get started.
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
Install dependencies from the repo root with `make node-install` (or `make install` for the full
|
||||||
|
Python + web + docs bootstrap). This wraps `npm ci` and explicitly rebuilds the small set of
|
||||||
|
packages whose install scripts are required for the toolchain to function — currently `esbuild`,
|
||||||
|
`chromedriver`, `tree-sitter`, and `tree-sitter-json`.
|
||||||
|
|
||||||
|
The repo-root `.npmrc` sets `ignore-scripts=true` to neutralize the dominant npm supply-chain
|
||||||
|
attack vector. As a side effect, running `npm ci` directly in this directory will install
|
||||||
|
dependencies but skip those rebuilds, leaving `esbuild` and `chromedriver` in a non-functional
|
||||||
|
state. If you bypass `make`, run the rebuild step yourself:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm rebuild --ignore-scripts=false --foreground-scripts \
|
||||||
|
esbuild chromedriver tree-sitter tree-sitter-json
|
||||||
|
```
|
||||||
|
|
||||||
|
New dependencies that ship install scripts must be audited and added to `TRUSTED_INSTALL_SCRIPTS`
|
||||||
|
in the repo-root `Makefile`. Each entry is arbitrary code that runs at install time, so the list
|
||||||
|
is intentionally small.
|
||||||
|
|
||||||
# The Theory of the authentik UI
|
# The Theory of the authentik UI
|
||||||
|
|
||||||
In Peter Naur's 1985 essay [Programming as Theory
|
In Peter Naur's 1985 essay [Programming as Theory
|
||||||
|
|||||||
Generated
-1
@@ -7,7 +7,6 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "@goauthentik/docs",
|
"name": "@goauthentik/docs",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"vendored/*",
|
"vendored/*",
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
"build:integrations": "npm run build -w integrations",
|
"build:integrations": "npm run build -w integrations",
|
||||||
"check-types": "tsc -b",
|
"check-types": "tsc -b",
|
||||||
"docusaurus": "docusaurus",
|
"docusaurus": "docusaurus",
|
||||||
"preinstall": "npm ci --prefix ..",
|
|
||||||
"lint": "eslint --fix .",
|
"lint": "eslint --fix .",
|
||||||
"lint:lockfile": "echo 'Skipping lockfile linting'",
|
"lint:lockfile": "echo 'Skipping lockfile linting'",
|
||||||
"lint-check": "eslint --max-warnings 0 .",
|
"lint-check": "eslint --max-warnings 0 .",
|
||||||
"prettier": "prettier --write .",
|
"prettier": "prettier --write .",
|
||||||
"prettier-check": "prettier --check .",
|
"prettier-check": "npm run prettier-prepare && prettier --check .",
|
||||||
|
"prettier-prepare": "npm ci --prefix ../packages/prettier-config",
|
||||||
"start": "npm start -w docs",
|
"start": "npm start -w docs",
|
||||||
"test": "node --test"
|
"test": "node --test"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user