feat(federation): admin controller + mosaic CLI federation commands (FED-M2-08)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful

Implements the two halves of FED-M2-08:

Gateway (apps/gateway/src/federation/):
- federation-admin.dto.ts: CreatePeerKeypairDto, StorePeerCertDto,
  GenerateEnrollmentTokenDto, RevokeGrantBodyDto
- federation.controller.ts: FederationController under
  /api/admin/federation with AdminGuard on all routes.
  Grant CRUD (create, list, get, revoke) delegating to GrantsService.
  Token generation delegating to EnrollmentService + returning enrollmentUrl.
  Peer listing via direct DB query.
  Peer keypair generation via webcrypto + @peculiar/x509 CSR generation.
  Peer cert storage with X509Certificate serial/notAfter extraction.
- federation.module.ts: register FederationController

CLI (packages/mosaic/src/commands/federation.ts):
- mosaic federation (alias: fed) command group
- grant create/list/show/revoke/token subcommands
- peer list/add subcommands (add runs full enrollment flow)
- Admin token resolved from -t flag or meta.json adminToken
- packages/mosaic/src/cli.ts: register registerFederationCommand

Tests (apps/gateway/src/federation/__tests__/federation.controller.spec.ts):
- listGrants, createGrant, generateToken, listPeers coverage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jarvis
2026-04-21 23:32:14 -05:00
parent 0bfaa56e9e
commit 8eff67a2bf
6 changed files with 934 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ import { registerUninstallCommand } from './commands/uninstall.js';
// prdy is registered via launch.ts
import { registerLaunchCommands } from './commands/launch.js';
import { registerAuthCommand } from './commands/auth.js';
import { registerFederationCommand } from './commands/federation.js';
import { registerGatewayCommand } from './commands/gateway.js';
import {
backgroundUpdateCheck,
@@ -336,6 +337,10 @@ registerAuthCommand(program);
registerGatewayCommand(program);
// ─── federation ───────────────────────────────────────────────────────
registerFederationCommand(program);
// ─── agent ─────────────────────────────────────────────────────────────
registerAgentCommand(program);