Require signed agent releases (Refs #64)

This commit is contained in:
2026-10-09 20:36:18 -04:00
parent df0d395138
commit 6f71822d41
24 changed files with 984 additions and 107 deletions
+25 -11
View File
@@ -1,17 +1,31 @@
import { error } from '@sveltejs/kit';
import { agentReleaseAsset } from '$lib/server/hosts/releases.js';
export async function GET({ params }: { params: { file: string } }) {
if (!['ec-agent.py', 'ec-agent-update.py', 'manifest.json'].includes(params.file))
if (
!['ec-agent.py', 'ec-agent-update.py', 'manifest.json', 'manifest.json.sig'].includes(
params.file
)
)
error(404, 'Release asset not found.');
return new Response(
await agentReleaseAsset(
params.file as 'ec-agent.py' | 'ec-agent-update.py' | 'manifest.json'
),
{
headers: {
'Content-Type': params.file.endsWith('.json') ? 'application/json' : 'text/plain',
'Cache-Control': 'no-cache'
}
let content: string;
try {
content = await agentReleaseAsset(
params.file as
'ec-agent.py' | 'ec-agent-update.py' | 'manifest.json' | 'manifest.json.sig'
);
} catch (cause) {
if ((cause as NodeJS.ErrnoException).code === 'ENOENT')
error(404, 'Release asset not found.');
throw cause;
}
return new Response(content, {
headers: {
'Content-Type': params.file.endsWith('.sig')
? 'application/pgp-signature'
: params.file.endsWith('.json')
? 'application/json'
: 'text/plain',
'Cache-Control': 'no-cache'
}
);
});
}
+6
View File
@@ -608,6 +608,12 @@
>
</div>
{#if enrollment}<p>Expires {$timeFormat.dateTime(enrollment.expiresAt)}</p>
<p>
Use a reviewed <code>electric-cherry-install.sh</code> from your
release publisher and provision its public signing key at
<code>/etc/electric-cherry/release-signing.gpg</code>. Obtain both
through a trusted channel independent of this controller.
</p>
<pre>{enrollment.command}</pre>{/if}{:else}<p>
Administrators manage enrollment and agent credentials.
</p>{/if}