From 461517c25fb38c62f6e7232c89efd032bc84f471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Thu, 13 Aug 2026 19:16:15 +0800 Subject: [PATCH] feat(hololake): render bounded release front door config --- ...E-JD-RELEASE-PUBLIC-PATH-20260813-004.json | 45 ++++++++++++++++ .../hololake-native-desktop/foundation.json | 1 + .../scripts/foundation.test.mjs | 1 + .../scripts/release-front-door.test.mjs | 22 ++++++++ .../server/release-broadcast/README.md | 8 +++ .../release-broadcast/render-front-door.mjs | 54 +++++++++++++++++++ 6 files changed, 131 insertions(+) create mode 100644 product-source/hololake-native-desktop/deployment/receipts/GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-004.json create mode 100644 product-source/hololake-native-desktop/scripts/release-front-door.test.mjs create mode 100755 product-source/hololake-native-desktop/server/release-broadcast/render-front-door.mjs diff --git a/product-source/hololake-native-desktop/deployment/receipts/GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-004.json b/product-source/hololake-native-desktop/deployment/receipts/GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-004.json new file mode 100644 index 0000000..3e6a316 --- /dev/null +++ b/product-source/hololake-native-desktop/deployment/receipts/GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-004.json @@ -0,0 +1,45 @@ +{ + "schema": "hololake.jd-release-public-path-acceptance-receipt/v1", + "receiptId": "GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-004", + "observedAt": "2026-08-13T19:13:32+08:00", + "state": "JD_LOOPBACK_PUBLIC_NAMESPACE_READY_FRONT_DOOR_NOT_DEPLOYED", + "target": "JD-FD-PRIMARY", + "sourceCommit": "9006075310729cb7c266decff529066053969f18", + "immutableSourcePath": "/opt/guanghu/hololake-release-broadcast-candidate/9006075310729cb7c266decff529066053969f18", + "serverOwnedReceipt": "/var/lib/guanghu/architecture-provision/receipts/GH-HOLOLAKE-JD-RELEASE-PUBLIC-PATH-20260813-001.json", + "serverOwnedReceiptSha256": "923564c7f624921bcab247e9e27fc007953bbd6c06733356be1bdd9420f5ef1d", + "liveReadback": { + "serviceActive": true, + "serviceEnabled": true, + "listener": "127.0.0.1:3940", + "publicPathPrefix": "/hololake/releases", + "releaseEndpointPath": "/hololake/releases/latest.json", + "legacyLatestStatus": 204, + "publicLatestStatus": 204, + "broadcastState": "EMPTY_FAIL_CLOSED", + "updateAvailable": false, + "stateFileCount": 0, + "automaticUpload": false, + "automaticActivation": false, + "automaticRestart": false, + "existingDiscoveryServiceActive": true, + "existingLivingControllerActive": true, + "existingMotherBrainActive": true + }, + "publicObservation": { + "url": "https://guanghulab.com/hololake/releases/latest.json", + "httpStatus": 200, + "contentType": "text/html", + "matchesReleaseProtocol": false, + "inference": "BS_GZ_006_HOMEPAGE_FALLBACK_NO_HOLOLAKE_PROXY" + }, + "productionBoundary": { + "frontDoorLoopbackPortAssigned": false, + "frontDoorProxyDeployed": false, + "publicHttpsReleaseEndpointProvisioned": false, + "updaterPublicKeyProvisioned": false, + "desktopReleaseTrustProvisioned": false, + "publicDistributionReady": false, + "repositoryPublicationClaimed": false + } +} diff --git a/product-source/hololake-native-desktop/foundation.json b/product-source/hololake-native-desktop/foundation.json index 0d78006..57c6e89 100644 --- a/product-source/hololake-native-desktop/foundation.json +++ b/product-source/hololake-native-desktop/foundation.json @@ -26,6 +26,7 @@ "release_public_route_contract": "server/release-broadcast/public-route.json", "release_public_path_prefix": "/hololake/releases", "release_public_route_deployed": false, + "release_front_door_bounded_config_renderer_implemented": true, "release_broadcast_explicit_operator_activation_implemented": true, "release_broadcast_activation_requires_exact_human_approval": true, "release_broadcast_activation_requires_repeated_expected_facts": true, diff --git a/product-source/hololake-native-desktop/scripts/foundation.test.mjs b/product-source/hololake-native-desktop/scripts/foundation.test.mjs index 95ac8ab..5f6d46d 100644 --- a/product-source/hololake-native-desktop/scripts/foundation.test.mjs +++ b/product-source/hololake-native-desktop/scripts/foundation.test.mjs @@ -63,6 +63,7 @@ test('release activation remains explicitly human controlled', () => { assert.equal(publicRoute.proxyRequestUriPolicy, 'PRESERVE_FULL_PUBLIC_PATH') assert.equal(publicRoute.frontDoorLoopbackPort, null) assert.equal(publicRoute.deployed, false) + assert.equal(foundation.release_front_door_bounded_config_renderer_implemented, true) assert.equal(foundation.release_pipeline_automatic_upload_allowed, false) assert.equal( foundation.release_production_activation_state, diff --git a/product-source/hololake-native-desktop/scripts/release-front-door.test.mjs b/product-source/hololake-native-desktop/scripts/release-front-door.test.mjs new file mode 100644 index 0000000..8e1b295 --- /dev/null +++ b/product-source/hololake-native-desktop/scripts/release-front-door.test.mjs @@ -0,0 +1,22 @@ +import assert from 'node:assert/strict' +import test from 'node:test' + +import { renderFrontDoorSnippet } from '../server/release-broadcast/render-front-door.mjs' + +test('front-door renderer refuses an unassigned or privileged loopback port', () => { + assert.throws(() => renderFrontDoorSnippet(null), /PORT_REQUIRED/) + assert.throws(() => renderFrontDoorSnippet(443), /PORT_REQUIRED|PORT_INVALID/) + assert.throws(() => renderFrontDoorSnippet('not-a-port'), /PORT_REQUIRED/) +}) + +test('rendered proxy preserves the public path and strips request authority', () => { + const snippet = renderFrontDoorSnippet(23940) + assert.match(snippet, /location \^~ \/hololake\/releases\//) + assert.match(snippet, /proxy_pass http:\/\/127\.0\.0\.1:23940;/) + assert.doesNotMatch(snippet, /proxy_pass http:\/\/127\.0\.0\.1:23940\//) + assert.match(snippet, /limit_except GET HEAD \{ deny all; \}/) + assert.match(snippet, /proxy_pass_request_body off;/) + assert.match(snippet, /proxy_set_header Authorization "";/) + assert.match(snippet, /proxy_set_header Cookie "";/) + assert.match(snippet, /proxy_set_header X-Forwarded-For "";/) +}) diff --git a/product-source/hololake-native-desktop/server/release-broadcast/README.md b/product-source/hololake-native-desktop/server/release-broadcast/README.md index 036bf93..f346593 100644 --- a/product-source/hololake-native-desktop/server/release-broadcast/README.md +++ b/product-source/hololake-native-desktop/server/release-broadcast/README.md @@ -23,6 +23,14 @@ preserve the full request URI. Its loopback tunnel port remains deliberately unassigned until the BS-GZ-006 route owner returns the live, non-conflicting topology. +Once that port is returned and independently verified, `render-front-door.mjs +--loopback-port PORT` renders the bounded Nginx location. It refuses an omitted +port, preserves the full public request path by leaving `proxy_pass` without a +URI suffix, accepts only GET and HEAD, forwards no request body, and strips +authorization, cookies, and client forwarding headers. Rendering is not +deployment; Nginx validation, transactional install, public certificate/readback, +and a separate server receipt remain required. + `operator.mjs` supplies the separate, root-operated verification and activation boundary. `verify` reconstructs a private candidate tree and accepts it only when the broadcast, pipeline receipt, package bytes, Developer ID receipt, Apple diff --git a/product-source/hololake-native-desktop/server/release-broadcast/render-front-door.mjs b/product-source/hololake-native-desktop/server/release-broadcast/render-front-door.mjs new file mode 100755 index 0000000..98a33bd --- /dev/null +++ b/product-source/hololake-native-desktop/server/release-broadcast/render-front-door.mjs @@ -0,0 +1,54 @@ +#!/usr/bin/env node + +const PORT_PATTERN = /^(?:[1-9]\d{3,4})$/ + +const fail = (code) => { + throw new Error(code) +} + +export function renderFrontDoorSnippet(portValue) { + const text = String(portValue ?? '') + if (!PORT_PATTERN.test(text)) fail('HOLOLAKE_RELEASE_FRONT_DOOR_PORT_REQUIRED') + const port = Number(text) + if (!Number.isInteger(port) || port < 1024 || port > 65535) fail('HOLOLAKE_RELEASE_FRONT_DOOR_PORT_INVALID') + return `location = /hololake/releases { + return 308 /hololake/releases/; +} + +location ^~ /hololake/releases/ { + limit_except GET HEAD { deny all; } + client_max_body_size 0; + proxy_pass http://127.0.0.1:${port}; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header Connection ""; + proxy_set_header Authorization ""; + proxy_set_header Cookie ""; + proxy_set_header X-Forwarded-For ""; + proxy_set_header X-Forwarded-Host ""; + proxy_set_header X-Forwarded-Proto ""; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_connect_timeout 2s; + proxy_send_timeout 10s; + proxy_read_timeout 60s; +} +` +} + +export function main(argv = process.argv.slice(2)) { + const portIndex = argv.indexOf('--loopback-port') + if (portIndex < 0 || portIndex + 1 >= argv.length || argv.length !== 2) { + fail('HOLOLAKE_RELEASE_FRONT_DOOR_USAGE:--loopback-port PORT') + } + process.stdout.write(renderFrontDoorSnippet(argv[portIndex + 1])) +} + +if (process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href) { + try { + main() + } catch (error) { + process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`) + process.exitCode = 1 + } +}