fix(discord): report runtime agent binding denial
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
Jarvis
2026-07-13 03:43:50 -05:00
parent 80fc236cb5
commit 533e970259
2 changed files with 30 additions and 1 deletions

View File

@@ -668,7 +668,18 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
); );
const actorId = binding && resolveDiscordInteractionActorId(binding, ingress.userId); const actorId = binding && resolveDiscordInteractionActorId(binding, ingress.userId);
const agentName = process.env['MOSAIC_AGENT_NAME']?.trim(); const agentName = process.env['MOSAIC_AGENT_NAME']?.trim();
if (!actorId || !agentName || binding.instanceId !== agentName) return; if (!actorId || !agentName || binding.instanceId !== agentName) {
this.logger.warn(
`Rejected Discord approval without a matching runtime agent from ${client.id}`,
);
client.emit('discord:approval', {
correlationId: ingress.correlationId,
success: false,
approvalId: undefined,
expiresAt: undefined,
});
return;
}
const providerId = actionParts[1]!; const providerId = actionParts[1]!;
const sessionId = actionParts[2]!; const sessionId = actionParts[2]!;
const approval = await this.commandAuthorization.createRuntimeTerminationApproval({ const approval = await this.commandAuthorization.createRuntimeTerminationApproval({

View File

@@ -271,6 +271,24 @@ describe('Discord ingress security', () => {
]); ]);
}); });
it('rejects approval when the binding targets a different runtime agent', async () => {
configureDiscordEnv();
process.env['MOSAIC_AGENT_NAME'] = 'Other';
const { gateway, client } = discordGateway('admin');
await gateway.handleDiscordApproval(
client as never,
ingressEnvelope('/approve fleet runtime-1', 'mismatched-agent-approve'),
);
expect(client.emit).toHaveBeenCalledWith('discord:approval', {
correlationId: 'correlation-001',
success: false,
approvalId: undefined,
expiresAt: undefined,
});
});
it('rejects unpaired and non-admin Discord users for approval and stop', async () => { it('rejects unpaired and non-admin Discord users for approval and stop', async () => {
configureDiscordEnv(); configureDiscordEnv();
const { gateway, client } = discordGateway('member'); const { gateway, client } = discordGateway('member');