Implements FED-M2-10: E2E HTTP test for the federation peer add enrollment flow
Covers MILESTONES.md acceptance criterion #6: peer add <url> on Server A yields an active peer record with a valid cert + key
Simulates two gateways against a single NestJS/Fastify app using Test.createTestingModule with FederationModule imported and AdminGuard overridden to allow all requests
What is tested
The test executes the full peer add enrollment flow in five steps:
Server B setup — create a grant + enrollment token via GrantsService/EnrollmentService directly
Server A keypair — POST /api/admin/federation/peers/keypair asserts 201 with peerId and csrPem
Enrollment — POST /api/federation/enrollment/:token with CSR asserts 200 with certPem and certChainPem
Store cert — PATCH /api/admin/federation/peers/:peerId/cert asserts 200
DB assertion — verifies state='active', cert present, certSerial non-empty, clientKeyPem is sealed ciphertext, certNotAfter is in the future
## Summary
- Implements FED-M2-10: E2E HTTP test for the federation `peer add` enrollment flow
- Covers MILESTONES.md acceptance criterion **#6**: `peer add <url>` on Server A yields an `active` peer record with a valid cert + key
- Simulates two gateways against a single NestJS/Fastify app using `Test.createTestingModule` with `FederationModule` imported and `AdminGuard` overridden to allow all requests
## What is tested
The test executes the full `peer add` enrollment flow in five steps:
1. **Server B setup** — create a grant + enrollment token via `GrantsService`/`EnrollmentService` directly
2. **Server A keypair** — `POST /api/admin/federation/peers/keypair` asserts 201 with peerId and csrPem
3. **Enrollment** — `POST /api/federation/enrollment/:token` with CSR asserts 200 with certPem and certChainPem
4. **Store cert** — `PATCH /api/admin/federation/peers/:peerId/cert` asserts 200
5. **DB assertion** — verifies state='active', cert present, certSerial non-empty, clientKeyPem is sealed ciphertext, certNotAfter is in the future
## Gate env vars
```
FEDERATED_INTEGRATION=1
STEP_CA_AVAILABLE=1
STEP_CA_URL=https://localhost:9000
STEP_CA_PROVISIONER_KEY_JSON=...
STEP_CA_ROOT_CERT_PATH=/tmp/step-ca-root.crt
```
## How to run
```bash
docker compose -f docker-compose.federated.yml --profile federated up -d
FEDERATED_INTEGRATION=1 STEP_CA_AVAILABLE=1 \
STEP_CA_URL=https://localhost:9000 \
STEP_CA_PROVISIONER_KEY_JSON="$(docker exec $(docker ps -qf name=step-ca) cat /home/step/secrets/mosaic-fed.json)" \
STEP_CA_ROOT_CERT_PATH=/tmp/step-ca-root.crt \
pnpm --filter @mosaicstack/gateway test \
src/__tests__/integration/federation-m2-e2e.integration.test.ts
```
## Quality gates
All passed locally:
- typecheck — clean (turbo cache miss, fresh execution for gateway)
- lint — clean (turbo cache miss, fresh execution for gateway)
- format:check — all files properly formatted (prettier)
- Test skips correctly when env vars not set
Closes #461
Tests MILESTONES.md acceptance criterion #6: peer add flow yields an
active peer record with a valid cert + key. Simulates two gateways
against a single NestJS app instance with FederationModule + overridden
AdminGuard. Steps: keypair → enrollment → cert storage → DB assertion.
Gated by FEDERATED_INTEGRATION=1 and STEP_CA_AVAILABLE=1.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Guard against partial env var sets where STEP_CA_AVAILABLE=1 is set
but provisioner key or root cert path are missing, which would cause
CaService constructor to throw during NestJS module instantiation.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Move DB token from overrideProvider (which requires an existing binding)
to the providers array so Nest can resolve GrantsService dependencies
when FederationModule is tested without DatabaseModule.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
peer addenrollment flowpeer add <url>on Server A yields anactivepeer record with a valid cert + keyTest.createTestingModulewithFederationModuleimported andAdminGuardoverridden to allow all requestsWhat is tested
The test executes the full
peer addenrollment flow in five steps:GrantsService/EnrollmentServicedirectlyPOST /api/admin/federation/peers/keypairasserts 201 with peerId and csrPemPOST /api/federation/enrollment/:tokenwith CSR asserts 200 with certPem and certChainPemPATCH /api/admin/federation/peers/:peerId/certasserts 200Gate env vars
How to run
Quality gates
All passed locally:
Closes #461