fix(#276): Add comprehensive audit logging for incoming connections

Implemented comprehensive audit logging for all incoming federation
connection attempts to provide visibility and security monitoring.

Changes:
- Added logIncomingConnectionAttempt() to FederationAuditService
- Added logIncomingConnectionCreated() to FederationAuditService
- Added logIncomingConnectionRejected() to FederationAuditService
- Injected FederationAuditService into ConnectionService
- Updated handleIncomingConnectionRequest() to log all connection events

Audit logging captures:
- All incoming connection attempts with remote instance details
- Successful connection creations with connection ID
- Rejected connections with failure reason and error details
- Workspace ID for all events (security compliance)
- All events marked as securityEvent: true

Testing:
- Added 3 new tests for audit logging verification
- All 24 connection service tests passing
- Quality gates: lint, typecheck, build all passing

Security Impact:
- Provides visibility into all incoming connection attempts
- Enables security monitoring and threat detection
- Audit trail for compliance requirements
- Foundation for future authorization controls

Note: This implements Phase 1 (audit logging) of issue #276.
Full authorization (allowlist/denylist, admin approval) will be
implemented in a follow-up issue requiring schema changes.

Fixes #276

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
This commit is contained in:
2026-02-03 20:24:46 -06:00
co-authored by Claude Sonnet 4.5
parent 7d9c102c6d
commit 744290a438
4 changed files with 304 additions and 1 deletions
+65
View File
@@ -142,4 +142,69 @@ export class FederationAuditService {
securityEvent: true,
});
}
/**
* Log incoming connection attempt
* Logged for all incoming connection requests (security monitoring)
*/
logIncomingConnectionAttempt(data: {
workspaceId: string;
remoteInstanceId: string;
remoteUrl: string;
timestamp: number;
}): void {
this.logger.log({
event: "FEDERATION_INCOMING_CONNECTION_ATTEMPT",
workspaceId: data.workspaceId,
remoteInstanceId: data.remoteInstanceId,
remoteUrl: data.remoteUrl,
requestTimestamp: new Date(data.timestamp).toISOString(),
timestamp: new Date().toISOString(),
securityEvent: true,
});
}
/**
* Log incoming connection created
* Logged when an incoming connection is successfully created
*/
logIncomingConnectionCreated(data: {
workspaceId: string;
connectionId: string;
remoteInstanceId: string;
remoteUrl: string;
}): void {
this.logger.log({
event: "FEDERATION_INCOMING_CONNECTION_CREATED",
workspaceId: data.workspaceId,
connectionId: data.connectionId,
remoteInstanceId: data.remoteInstanceId,
remoteUrl: data.remoteUrl,
timestamp: new Date().toISOString(),
securityEvent: true,
});
}
/**
* Log incoming connection rejected
* Logged when an incoming connection is rejected (security event)
*/
logIncomingConnectionRejected(data: {
workspaceId: string;
remoteInstanceId: string;
remoteUrl?: string;
reason: string;
error?: string;
}): void {
this.logger.warn({
event: "FEDERATION_INCOMING_CONNECTION_REJECTED",
workspaceId: data.workspaceId,
remoteInstanceId: data.remoteInstanceId,
remoteUrl: data.remoteUrl,
reason: data.reason,
error: data.error,
timestamp: new Date().toISOString(),
securityEvent: true,
});
}
}