Skip to content

Commit 75df790

Browse files
committed
Setup public infrastructure for preinstalling ambient gatekeepers
1 parent bf7f762 commit 75df790

3 files changed

Lines changed: 41 additions & 0 deletions

File tree

scripts/release-manifest.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,23 @@ test("worker entries carry the deploy contract", () => {
157157
namespace_id: "$KV_CONTEXT_COLLECTIONS_ID" });
158158
assert.deepEqual(context.inputs, []);
159159

160+
// Ambient gatekeepers are preinstalled on every core deploy; preinstalls must take no
161+
// secret inputs (nobody is around to supply them). Both also declare an account-level agent
162+
// singleton, so both are install-once.
163+
assert.equal(context.preinstall, true);
164+
assert.equal(context.singleton, true);
165+
assert.equal(workers["gatekeeper-scheduler"].preinstall, true);
166+
assert.equal(workers["gatekeeper-scheduler"].singleton, true);
167+
assert.deepEqual(workers["gatekeeper-scheduler"].inputs, []);
168+
assert.equal(google.preinstall, undefined);
169+
assert.equal(google.singleton, undefined);
170+
for (const [name, entry] of Object.entries(workers)) {
171+
if (entry.preinstall) {
172+
assert.ok(entry.installable, `${name}: preinstall requires installable`);
173+
assert.deepEqual(entry.inputs, [], `${name}: preinstall requires no inputs`);
174+
}
175+
}
176+
160177
// Module blobs are content-addressed.
161178
for (const [name, entry] of Object.entries(workers)) {
162179
assert.ok(entry.modules.some((m) => m.name === entry.mainModule),

scripts/release/manifest-lib.mjs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ const NO_DEFAULT_CRED_INPUTS = new Set([
5252
// instances don't have. The bundle still ships in the release so the entry stays auditable.
5353
const NOT_INSTALLABLE = new Set(["gatekeeper-email"]);
5454

55+
// Ambient gatekeepers the deploy service installs on every fresh core deploy, server-side with
56+
// no user interaction. Members must take no inputs of any kind (enforced below): a preinstall
57+
// has nobody to ask.
58+
const PREINSTALL = new Set(["gatekeeper-context", "gatekeeper-scheduler"]);
59+
60+
// Gatekeepers that may be installed at most once per instance; the deploy service enforces this
61+
// at install time. The giveaway is the account declaring an agent singleton
62+
// (`AccountDescription.singleton` — context's `ContextLibrary`, scheduler's `ScheduleSession`):
63+
// the Workshop auto-provisions those accounts and folds the singleton into every workspace as an
64+
// ambient gatekeeper, so a second install would hand every user a duplicate ambient capsule.
65+
// Independent of PREINSTALL in principle; the two sets coincide today only because every ambient
66+
// gatekeeper we ship is also preinstalled.
67+
const SINGLETON = new Set(["gatekeeper-context", "gatekeeper-scheduler"]);
68+
5569
export const DEFAULT_CRED_INPUTS = [
5670
{
5771
name: "CLIENT_ID",
@@ -205,12 +219,18 @@ export function buildWorkerEntry({ pkgName, config, mainModule, modules, deployI
205219
bindings.push({ type: "secret_text", name: input.name, text: `$SECRET(${input.name})` });
206220
}
207221
}
222+
if (PREINSTALL.has(pkgName) && inputs.length > 0) {
223+
throw new Error(`${pkgName} is preinstalled but declares input(s); preinstalls run ` +
224+
`with no user interaction, so this release would be broken`);
225+
}
208226
}
209227

210228
return {
211229
kind,
212230
...(kind === "gatekeeper" ? { shortName: shortName(pkgName) } : {}),
213231
installable,
232+
...(PREINSTALL.has(pkgName) ? { preinstall: true } : {}),
233+
...(SINGLETON.has(pkgName) ? { singleton: true } : {}),
214234
mainModule,
215235
modules: modules.map(({ name, type, sha256, size }) => ({
216236
name, type, sha256, size, r2Key: moduleR2Key(sha256),

scripts/testdata/golden-manifest.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,9 @@
188188
"invocation_logs": false
189189
}
190190
},
191+
"preinstall": true,
191192
"shortName": "context",
193+
"singleton": true,
192194
"vars": {
193195
"BASE_URL": "$PUBLIC_BASE_URL/gatekeeper/context"
194196
}
@@ -697,7 +699,9 @@
697699
"invocation_logs": false
698700
}
699701
},
702+
"preinstall": true,
700703
"shortName": "scheduler",
704+
"singleton": true,
701705
"vars": {
702706
"BASE_URL": "$PUBLIC_BASE_URL/gatekeeper/scheduler"
703707
}

0 commit comments

Comments
 (0)