diff --git a/apps/gateway/src/commands/command-authorization.service.ts b/apps/gateway/src/commands/command-authorization.service.ts index 819813f..a9f829e 100644 --- a/apps/gateway/src/commands/command-authorization.service.ts +++ b/apps/gateway/src/commands/command-authorization.service.ts @@ -134,6 +134,8 @@ export class CommandAuthorizationService { if ( !this.isRuntimeTerminationApproval(approval) || approval.actionDigest !== this.runtimeActionDigest(action) || + approval.actorId !== action.actorId || + approval.tenantId !== action.tenantId || !this.isUnexpired(approval.expiresAt) ) { return false; @@ -194,19 +196,27 @@ export class CommandAuthorizationService { } private hasRuntimeTerminationAction(action: RuntimeTerminationApprovalAction): boolean { - return [action.providerId, action.sessionId, action.agentName].every( - (value: string): boolean => value.trim().length > 0, - ); + return [ + action.providerId, + action.sessionId, + action.actorId, + action.tenantId, + action.channelId, + action.correlationId, + action.agentName, + ].every((value: string): boolean => value.trim().length > 0); } private runtimeActionDigest(action: RuntimeTerminationApprovalAction): string { return createHash('sha256') .update( JSON.stringify({ - // Exact action identity is transport-neutral. Discord actor/correlation - // remain immutable audit metadata on the record, not its consume key. providerId: action.providerId, sessionId: action.sessionId, + actorId: action.actorId, + tenantId: action.tenantId, + channelId: action.channelId, + correlationId: action.correlationId, agentName: action.agentName, }), )