diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..a44e24ed90 --- /dev/null +++ b/.npmrc @@ -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 ` 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 diff --git a/CODEOWNERS b/CODEOWNERS index 0e2afaa2b5..355eb3a11e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -34,6 +34,7 @@ packages/django-channels-postgres @goauthentik/backend packages/django-postgres-cache @goauthentik/backend packages/django-dramatiq-postgres @goauthentik/backend # Web packages +.npmrc @goauthentik/frontend tsconfig.json @goauthentik/frontend package.json @goauthentik/frontend package-lock.json @goauthentik/frontend diff --git a/Makefile b/Makefile index 64afe4ea34..5b82323438 100644 --- a/Makefile +++ b/Makefile @@ -125,7 +125,7 @@ core-i18n-extract: --ignore website \ -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: $(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 ######################### +# 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 npm ci - npm ci --prefix 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 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-install: +docs-install: node-install npm ci --prefix website docs-lint-fix: lint-spellcheck diff --git a/web/README.md b/web/README.md index 974401184e..dd8322cd83 100644 --- a/web/README.md +++ b/web/README.md @@ -3,6 +3,27 @@ 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. +# 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 In Peter Naur's 1985 essay [Programming as Theory diff --git a/website/package-lock.json b/website/package-lock.json index 83e525ae0f..5c29b2cf00 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "@goauthentik/docs", "version": "0.0.0", - "hasInstallScript": true, "license": "MIT", "workspaces": [ "vendored/*", diff --git a/website/package.json b/website/package.json index 38c30ae8b9..f6e27e727c 100644 --- a/website/package.json +++ b/website/package.json @@ -9,12 +9,12 @@ "build:integrations": "npm run build -w integrations", "check-types": "tsc -b", "docusaurus": "docusaurus", - "preinstall": "npm ci --prefix ..", "lint": "eslint --fix .", "lint:lockfile": "echo 'Skipping lockfile linting'", "lint-check": "eslint --max-warnings 0 .", "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", "test": "node --test" },