feat(sdk): allow new signing key (#2088)

This commit is contained in:
jubnl
2026-08-28 00:56:44 +02:00
committed by GitHub
parent 922f37ab52
commit d8fd2deb12
22 changed files with 915 additions and 71 deletions
+10 -4
View File
@@ -354,6 +354,7 @@ const signingDowngrade: NetworkCheck = {
// signed, an unsigned update — or one signed with a different key — is REFUSED on every
// instance that already has it. Merging that would not just fail; it would strand every
// existing user on the version they have.
const keyChanged = !!c.entry.authorPublicKey && c.entry.authorPublicKey !== published.authorPublicKey;
const problems: string[] = [];
if (!c.entry.authorPublicKey) {
problems.push(
@@ -361,19 +362,24 @@ const signingDowngrade: NetworkCheck = {
' TREK refuses an unsigned update to a signed plugin — it would break the update for every existing install.\n' +
' Sign it: pass --sign (your key should be at ~/.trek-plugin/signing.key).',
);
} else if (c.entry.authorPublicKey !== published.authorPublicKey) {
} else if (keyChanged && !c.allowKeyChange) {
problems.push(
'• this entry changes authorPublicKey. TREK refuses a key rotation until an admin re-trusts the plugin.\n' +
' Sign with your ORIGINAL key, or ask a maintainer for the allow-key-change label.',
' Sign with your ORIGINAL key — or, if the rotation is deliberate, re-run with --allow-key-change\n' +
' and ask a maintainer for the allow-key-change label.',
);
} else {
// Every version must stay signed, not just the newest — TREK verifies whichever version it
// installs, so an unsigned older block is a landmine for a pinned install.
// installs, so an unsigned older block is a landmine for a pinned install. Under a declared
// rotation this bites twice over: every version must be RE-signed with the new key.
for (const v of c.entry.versions) {
if (!v.signature) problems.push(`• ${v.version} has no signature, but this is a signed plugin — TREK will refuse to install it`);
}
}
return problems.length ? fail(`${problems.length} problem(s)`, problems.join('\n')) : pass('signed with the published key');
if (problems.length) return fail(`${problems.length} problem(s)`, problems.join('\n'));
return keyChanged
? pass('key rotation declared — merging needs a maintainer\'s allow-key-change label, and every admin must re-trust the new key')
: pass('signed with the published key');
},
};
+6
View File
@@ -114,6 +114,12 @@ export interface CheckContext {
registry?: string;
/** Check every version in the entry, not just the newest. Mirrors `preflight --all`. */
allVersions?: boolean;
/**
* The author declared a deliberate key rotation (`--allow-key-change`). The signing-downgrade
* guard then accepts a changed `authorPublicKey` — every version still has to be signed — and
* says what the rotation costs instead of refusing it. Never set by default.
*/
allowKeyChange?: boolean;
}
/** The shape `entry.ts` builds and TREK-Plugins stores at registry/plugins/<id>.json. */