feat(components): <zl-gate> atom, null-safe invisible atoms, mock gate verification - #159
Closed
peintnermax wants to merge 4 commits into
Closed
feat(components): <zl-gate> atom, null-safe invisible atoms, mock gate verification#159peintnermax wants to merge 4 commits into
<zl-gate> atom, null-safe invisible atoms, mock gate verification#159peintnermax wants to merge 4 commits into
Conversation
Formalizes the captcha gate contract ADR 013 deferred, and designs a second bot-detection mechanism for apps behind an edge platform: - #1 in-flow captcha gate: built-in Altcha (self-hosted PoW) plus bring-your-own third-party providers (Turnstile/hCaptcha/reCAPTCHA); public site_key in the client-visible gate config, secret server-side; verified through the existing auth_attempts challenge/verify path. - #2 edge/platform signal: the SDK proxy stamps the platform verdict (Vercel BotID, Cloudflare managed challenge) as an authenticated inline X-Zitadel-Risk-Signal header, trusted via the origin-scoped sk_proj_ secret; the risk evaluator uses it to suppress or inject the gate. Also revises bot-detection.md (status -> ADR 016, new platform/edge signals section, example JSON corrected to the {kind, provider, config} contract) and adds the ADR index row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Member
|
replaced by #562 |
This was referenced Jul 22, 2026
fforootd
added a commit
that referenced
this pull request
Jul 29, 2026
## Summary <!-- Briefly describe what changed and why. --> - Clears all six open Dependabot alerts (5 high, 1 medium — all npm, all in `pnpm-lock.yaml`). Two are catalog entries and move in `pnpm-workspace.yaml`; the other four are transitive and land as range-scoped `pnpm.overrides`, matching the entries already there. - `liquidjs` 10.27.0 → 10.27.2 — `pop` filter bypassed `memoryLimit` accounting (CVE-2026-55575, #182). - `react-server-dom-webpack` 19.2.5 → 19.2.8 — DoS in Server Functions (CVE-2026-44907, #184); the old version is deprecated on npm. **`react`/`react-dom` move to 19.2.8 with it**: 19.2.8 peers on `^19.2.8`, and React ships the RSC packages in lockstep. Without this, `apps/docs` installs with an unmet peer (see Notes). No published-contract impact — only the private `@zitadel/ui-react` uses `catalog:` for its React peers; `sdk-react`/`sdk-next` publish `>=18`. - `brace-expansion` → 1.1.17 / 2.1.3 / 5.0.8 — unbounded expansion OOM (CVE-2026-14257, #185). The existing override pinned 5.0.7, which the new advisory covers, so the bounds move rather than gaining a new entry; the 1.x and 2.x backports landed 2026-07-28/29. - `postcss` → `^8.5.18` — `sourceMappingURL` path traversal (#183, and #181 for the earlier range). Collapses the 8.4.31 copy pinned by `next@16.2.12` and the 8.5.15 copy from the build tooling into a single 8.5.25. - `@hono/node-server` → `^2.0.12` — `serve-static` path traversal on Windows (#159). The vulnerable 1.19.17 comes from `@modelcontextprotocol/sdk` (via `@fumapress/ai` in `apps/docs`) and the advisory has no 1.x patch, so the SDK is raised to `^1.30.0` alongside — 1.30.0 widened its range to `^1.19.9 || ^2.0.5`, which keeps the 2.x pin inside a declared range instead of forcing one. Supersedes #639, which covered the first two but left `react`/`react-dom` at 19.2.5. ## Validation <!-- List exact commands run. If validation was not run, say so explicitly. --> - `corepack pnpm install --lockfile-only` — resolves clean. Lock churn is confined to the affected trees (postcss family, brace-expansion, `@modelcontextprotocol/sdk`, nanoid); nothing else moved. - Peer check: no new warnings. The remaining ones (`nuxt`/`@nuxt/devtools` vs vite 8, `@angular/build` vs vitest 4) are pre-existing on `main`. - `corepack pnpm install && corepack pnpm exec moon run :build :typecheck :test` — 80 tasks, exit 0. ## Release notes / changeset <!-- State one outcome from the .changeset/README.md decision table (.changeset/README.md#decision-table): - No changeset required — no shipped behavior changed. - Changeset: .changeset/<slug>.md — <summary> (list @zitadel/server for server changes) - Empty changeset (rare) — <why a publishable path changed but nothing ships> --> - Changeset: `.changeset/security-dependency-updates.md` — patch for `@zitadel/components` and `@zitadel/config`, which ship `liquidjs` as a runtime dependency. The rest of this PR is build-time or `apps/docs`-only and ships nothing. ## Notes <!-- Add reviewer context, follow-ups, risks, or "None". --> - The peer break #639 would have introduced, reproduced before adding the `react`/`react-dom` bump: ``` apps/docs └─┬ react-server-dom-webpack 19.2.8 ├── ✕ unmet peer react@^19.2.8: found 19.2.5 └── ✕ unmet peer react-dom@^19.2.8: found 19.2.5 ``` - `apps/demo-next` (`react: ^19.0.0`) and `packages/sdk-next` (`>=18`) are not catalog-managed and stay on 19.2.5 — deliberate, since those mirror a consumer app's own manifest. - Overrides go stale silently: a bound like `brace-expansion@>=3.0.0 <5.0.7` stops matching once 5.0.7 is itself the vulnerable version. Worth a look whenever an alert reappears for a package that already has an entry. - Unrelated to this PR, but noticed while checking #639's red run: its `cli:test` failure was the `release-artifacts.test.ts` assertion loosened on `main` in 4c3a3ce (#642) a day later, not the dependency bump. - There is no `.github/dependabot.yml` in the repo, so only security updates open PRs — no scheduled version updates. The catalog has drifted accordingly (72 of 104 entries behind latest: 15 patch, 41 minor, 16 major). Not addressed here.
fforootd
added a commit
that referenced
this pull request
Aug 2, 2026
… ADRs (#714) ## Summary The two deliberately-parked P2 items from the Wicklore remediation plan, written as **Proposed** ADRs for team alignment — per the plan's rule that these get no implementation before acceptance (built-ahead-of-alignment is how PR #56/#159 rotted): - **ADR 044 — Scaffold Embedding Posture Defaults**: scaffolded auth/profile pages derive their surface from the fresh-vs-pre-existing hinge that setup already records (`scaffolded_framework`, ADR 042): fresh scaffolds keep `variant="page"`, pre-existing apps get `variant="widget"` in a layout-neutral wrapper so the card stops fighting the host app's shell. Posture stays a page edit (no config knob), doctor restores it from the manifest. Open questions flagged: an explicit `--surface` override, and per-page posture recording. - **ADR 045 — Copy Overlays as Branding Revisions**: audience copy (`businessLocales`) is branding-shaped data living in code — per-app-build, multiplied across eight SDK/template integration points. Proposal: branding revisions carry per-language copy resolved with the flow response; `--use-case business` seeds a revision instead of wiring template props; wording edits follow eject→edit→apply and become runtime-effective. **Fenced behind the templates-track milestone** — direction alignment only; the in-flight per-SDK parity wiring stays the interim mechanism and is explicitly named as transitional. ## Validation - `node scripts/check-adrs-index.mjs` — 45 records ok. - Docs-only; no changeset. ## Notes Stacked on #713 (the index check enforces contiguous ADR numbers, so this branch carries 043) — the diff collapses to the two proposals once #713 merges.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the frontend side of ADR 016 — the in-flow captcha gate contract.
<zl-gate>atomNew invisible Lit component that handles gate proof-of-work. Reads gate config from step attributes, dispatches on
kind+provider, solves the challenge, and emitszl-gate-result. The orchestrator collects proofs into agateProofsmap and includes them asgate_proofsin the submit body.Supported providers: Altcha (built-in PoW), Turnstile, hCaptcha, reCAPTCHA. Third-party widgets mount in light DOM to avoid shadow-DOM iframe issues.
Null-safe invisible atoms
Both invisible auto-acting atoms (
<zl-gate>,<zl-passkey>) now follow the same pattern:{% if %}guards neededfirstUpdated()instead ofconnectedCallback()(Lit reflects attributes afterconnectedCallback, so config/options would be null)This removes the
{% if challenge and challenge.method == "passkey" %}boilerplate from all three Liquid templates. Custom branding authors no longer need to know about invisible atoms.mandatory-gates→required-atomsrenameThe patcher injects missing fields, gates, and submit buttons — not just gates. Renamed to reflect its actual scope:
mandatory-gates.ts→required-atoms.ts{% mandatory_gates %}→{% required_atoms %}patchRequiredAtoms,REQUIRED_ATOMS_MARKER,requiredAtomsMarkerCommentUpdated across all templates, specs, orchestrator imports, barrel exports, ADR 016, and 5 design docs.
Mock server gate verification
packages/api-mock/src/altcha.ts—generateAltchaChallenge()+verifyAltchaProof()usingcrypto.subtlepackages/api-mock/src/handlers.ts— tracks issued challenges per gate name, verifies proofs on submit (opt-in viaverifyGates: true), logs✅/❌resultspackages/api-mock/src/fixtures/login.ts— identifier step includes an Altcha gate (bot_check)server.ts) enables verification; unit tests disable it (default)ADR 016 updates
Proposed→Accepted<zl-captcha>→<zl-gate>(generic name for future gate kinds)gate_proofsvalues: string → object ({ number, salt }for Altcha,{ token }for vendors)mandatory-gates→required-atomsChanged files
components/atomszl-gate.ts(new),zl-passkey.ts(null-safe +firstUpdated)components/orchestratorrequired-atoms.ts(renamed),required-atoms.spec.ts,liquid.ts,liquid.spec.ts,zitadel-login.ts,zitadel-login.spec.ts,index.tscomponents/templatesauth-form.liquid.ts,passkey-upsell.liquid.ts,signed-in.liquid.tscomponentssrc/index.ts,src/manifests.ts,src/manifests.spec.tsapi-mockaltcha.ts(new),handlers.ts,server.ts,fixtures/login.tsdocsadrs/016-captcha-gate-and-bot-signals.md,design/branding/*.md(5 files)Test results