@@ -340,7 +334,7 @@ The current schema deliberately contains no thumbprint or client-certificate ide
2.**No internal identifiers in EWBI responses.** SUPIs, IMSIs, internal UUIDs (where they would reveal system architecture), and Kubernetes-internal identifiers are stripped or replaced with opaque federation-scoped references.
3.**Correlation ID boundary.** Internal `correlation_id` values are mapped to `X-Federation-Correlation-ID` at the EWBI boundary. Partners never see internal trace identifiers.
3.**Correlation ID boundary.** Internal `correlation_id` values appear only in logs and `federation_transactions`; FM adds no custom header or field to EWBI traffic. Cross-operator correlation uses the identifiers OPG.04 defines (`federationContextId`, `txnIdentifier`, `Idempotency-Key`, `Location`).
4.**PII minimization.** FM logs partner identifiers and API types but does not log subscriber-level PII (MSISDN, IP) except in the routing lookup path where it is necessary.
@@ -381,7 +375,7 @@ FM uses oop-commons structured JSON logging. Every log entry includes:
"level":"INFO",
"service":"fm",
"correlation_id":"internal-uuid",
"federation_correlation_id":"fed-corr-abc-123",
"external_txn_id":null,
"partner_op_id":"uuid",
"partner_mcc_mnc":"214-07",
"ewbi_method":"POST",
@@ -434,7 +428,7 @@ remove the FM fleet from load balancing.
-**Routing resolution:** Test MSISDN longest-prefix matching (overlapping prefixes, exact match, no match). Test IP CIDR range matching.
-**Topology hiding:** Test that internal IPs (IPv4/IPv6), Kubernetes DNS names, namespace references, and prohibited keys are stripped from various payload shapes. Test that legitimate data is preserved.
-**Agreement validation:** Test expired agreements, suspended partners, API type restrictions, zone restrictions.
-**X-Federation-Correlation-ID mapping:** Test bidirectional mapping and that internal IDs never appear in external-facing outputs.
-**Correlation boundary:** Test that internal `correlation_id` values never appear in outbound EWBI requests or EWBI responses, and that no `X-*` header is ever sent to a partner.
### S.2 Integration Tests
@@ -635,3 +629,4 @@ This validates the core architectural claim: FM publishes the same `command.srm.
| Version | Date | Summary |
|---------|------|---------|
| 2.0 | 2026-07-07 | OOP Release 2.0. |
| 2.0 | 2026-09-08 | Dropped the `X-Federation-Correlation-ID` extension: no `federation_correlation` middleware, EWBI client sends only `Authorization`; logs and audit carry `external_txn_id` instead. |
Changes for fm/overview-and-architecture.md: 6 added lines, 5 removed lines.
Original line number
Diff line number
Diff line
@@ -94,7 +94,7 @@ There are two success definitions:
| **Operation tracking** | Consume `event.srm.operation.status` and `event.srm.operation.completed` from DataBus. Track federation request lifecycle. |
| **Topology hiding** | Strip all internal IPs, cluster names, namespace names, pod UIDs, node names, and internal trace IDs from responses before they cross the operator boundary. |
| **Resource catalogue sync** | Publish local edge zone availability to partners. Subscribe to partner resource updates. |
| **Correlation ID management** | Map internal `correlation_id`to external `X-Federation-Correlation-ID` at the EWBI boundary to prevent internal trace leakage. |
| **Correlation ID management** | Keep internal `correlation_id`inside the platform; correlate with partners only through OPG.04 identifiers (`federationContextId`, `txnIdentifier`, `Idempotency-Key`). |
### A.2 EWBI OAuth2 Trust Flows
@@ -175,7 +175,7 @@ replaced later by `private_key_jwt` without changing outbound callers or Bearer-
| **Routing Rule** | A mapping from a user identifier range (MSISDN prefix, IP CIDR block) to a specific partner operator. Stored in PostgreSQL. |
| **Federation Agreement** | The logical ruleset governing what resources, APIs, and capabilities can be shared between two operator platforms, including usage limits and validity period. |
| **Topology Hiding** | Mandatory removal of all internal infrastructure details (IPs, cluster names, namespace names, pod UIDs, node names, internal trace IDs) from any response that crosses the operator boundary. |
| **X-Federation-Correlation-ID** | An external correlation identifier used in EWBI communications. Mapped to/from the internal `correlation_id`at the FM boundary. |
| **txnIdentifier** | OPG.04 transaction identifier carried in Service API forwarding requests and responses; the identifier both operators hold for one interaction. Stored as `external_txn_id`; internal `correlation_id`never crosses the boundary. |
| **Resource Catalogue Sync** | The bidirectional exchange of edge zone and capability availability data between federation partners. |
---
@@ -239,7 +239,7 @@ A locally connected App Provider makes a request that targets a subscriber on a
1. OEG calls FM via internal HTTP with the request and routing identifiers.
2. FM queries routing table for MSISDN prefix or IP CIDR match. Resolves target partner OP.
3. FM checks federation agreement: is outbound federation permitted for this API type and partner?
4. FM strips internal headers, obtains or reuses a `fed-mgmt` access token from the partner's Authorization Server, and injects `X-Federation-Correlation-ID` as an OOP trace extension.
4. FM strips internal headers and obtains or reuses a `fed-mgmt` access token from the partner's Authorization Server.
5. FM forwards the request to the partner OP's canonical OPG.04 EWBI endpoint with `Authorization: Bearer <token>`.
6. Partner OP returns the result.
7. FM passes the result back to OEG (partner responses are already topology-scoped to that OP; FM does not re-expose our internal topology).
@@ -281,7 +281,7 @@ A partner operator queries device location or device status for a subscriber tha
-**Main flow:**
1. FM validates the Bearer JWT and checks partner status is `active`.
2. FM checks federation agreement: is this partner authorized for the `device-location` or `device-status` API family?
3. FM maps `X-Federation-Correlation-ID` to internal `correlation_id`.
3. FM assigns an internal `correlation_id` for the request; it appears only in logs and `federation_transactions`, never in the EWBI response.
4. FM calls SRM synchronously: `POST /internal/network-queries/location` or `POST /internal/network-queries/device-status` with the subscriber identifier, the partner's tenant identity as `app_provider_id`, and the `service_specification_id` the federation agreement references for that API family (ADR-0018).
5. SRM calls the appropriate TF-SDK network adapter, which queries the NEF (Network Exposure Function).
6. SRM returns the result to FM.
@@ -333,7 +333,7 @@ A locally connected App Provider deploys to an Edge Cloud Zone that turns out to
-**Outbound federation routing** — resolve target partner from routing identifiers, forward requests over EWBI.
-**Topology hiding** — mandatory stripping of internal details (IPs, cluster names, namespace names, pod UIDs, node names, internal trace IDs) from all EWBI responses.
-**Resource catalogue synchronization** — bidirectional exchange of zone/capability availability with partners.
-**Correlation ID boundary management** — map internal `correlation_id`↔ external `X-Federation-Correlation-ID`.
-**Correlation ID boundary management** — internal `correlation_id`never leaves the platform; partner-facing correlation uses OPG.04 identifiers only.
-**Database ownership** — PostgreSQL `fm_db` is FM-owned; other services do not read or write it directly.
@@ -423,3 +423,4 @@ goes through OEG at all — see G4.
|---------|------|---------|
| 2.0 | 2026-07-07 | OOP Release 2.0. |
| 2.0 | 2026-09-04 | Added OEG-proxied federation-establishment trigger and FM bootstrap config (ADR-0043, UC-FM-06 updated). Added UC-FM-07: SRM (not OEG) now owns zone-based deployment locality and the hand-off to FM (ADR-0044); UC-FM-02/G3 narrowed to subscriber-identifier routing; added G4 for the open SRM→FM transport question. |
| 2.0 | 2026-09-08 | Dropped the `X-Federation-Correlation-ID` extension (UC-FM-02/UC-FM-05, scope, glossary): no custom headers on EWBI; correlation via OPG.04 identifiers. |
| `correlation_id` | UUID | | Internal trace ID. Never sent to partners in any header or field |
| `external_txn_id` | VARCHAR(255) | | OPG.04 transaction identifier both operators hold when the operation defines one (`txnIdentifier` / `apiTxnId`); NULL otherwise |
| `idempotency_key` | VARCHAR(255) | | Required OPG.04 `Idempotency-Key` where the operation declares it |
| `request_fingerprint` | CHAR(64) | | SHA-256 of canonical request data; detects idempotency-key reuse with different content |
| `external_resource_id` | VARCHAR(255) | | Contract-defined external identifier, such as `appInstIdentifier` |
@@ -253,7 +253,7 @@ Indexes: `idx_shared_catalogue_partner_direction` on `(partner_op_id, direction)
Indexes: `idx_fed_tx_partner`, `UNIQUE (federation_operation_id) WHERE federation_operation_id IS NOT NULL`, `UNIQUE (partner_op_id, api_type, idempotency_key) WHERE idempotency_key IS NOT NULL`, `idx_fed_tx_context`, `idx_fed_tx_operation`, `idx_fed_tx_status`, `idx_fed_tx_started`, `idx_fed_tx_fed_correlation`.
Indexes: `idx_fed_tx_partner`, `UNIQUE (federation_operation_id) WHERE federation_operation_id IS NOT NULL`, `UNIQUE (partner_op_id, api_type, idempotency_key) WHERE idempotency_key IS NOT NULL`, `idx_fed_tx_context`, `idx_fed_tx_operation`, `idx_fed_tx_status`, `idx_fed_tx_started`, `idx_fed_tx_external_txn` on `external_txn_id`.
Retention: configurable per operator policy; consider partitioning by `started_at` quarter.
│ ├── dependencies.py # DI wiring (repo/adapter selection)
│ └── main.py # composition root + lifespan
└── tests/ unit | integration | e2e
@@ -325,7 +325,7 @@ federation-manager/
| Outbound AuthN | OAuth2 Client-Credentials — FM fetches a token from the partner's realm using our registered client credentials (ADR-0042) |
| Future: mTLS defense-in-depth | Deferred until real Nginx mTLS termination exists (ADR-0042). `partner_ca_cert_path` supports ordinary HTTPS verification; it is not an mTLS identity field. |
| Topology hiding | mandatory `TopologyHider` on every EWBI response (REQ-FED-02); strips internal IPs, cluster/namespace/node names, pod UIDs, trace IDs |
| Correlation boundary | internal `correlation_id`stays in logs and `federation_transactions`; no custom header or field crosses the EWBI; partner-side correlation uses OPG.04 identifiers (`federationContextId`, `txnIdentifier`, `Idempotency-Key`) |
| Header trust | FM must be reachable only via Nginx. FM trusts no caller-supplied identity header — partner identity comes solely from the validated JWT. |
Changes for fm/requirements-and-design.md: 11 added lines, 8 removed lines.
Original line number
Diff line number
Diff line
@@ -27,14 +27,14 @@ status: "ETSI SDG OOP"
| REQ-FED-07 | For inbound stateless queries (device location, device status), the system shall call SRM internal HTTP endpoints synchronously (`POST /internal/network-queries/location`, `POST /internal/network-queries/device-status`) — supplying the partner's tenant identity as `app_provider_id` and the `service_specification_id` the federation agreement references for that API family (ADR-0018) — apply topology hiding to the result, and return the sanitized response to the partner OP. | [srm/interface-contract.md](/srm/interface-contract.md) §E.2 |
| REQ-FED-08 | The system shall consume `event.srm.operation.status`, `event.srm.operation.completed`, and `event.srm.catalog.updated` events from the DataBus `OOP_EVENTS` stream via the `fm-event-worker` consumer to track the lifecycle of federation-originated requests and trigger resource catalogue re-sync. | Platform binding (DataBus Configuration) |
| REQ-FED-09 | The system shall call SRM `POST /internal/capacity-check` before dispatching inbound deployment requests as a best-effort pre-flight (SRM holds no capacity or reservations — ADR-0002), rejecting requests with an appropriate EWBI error when the query reports insufficient capacity. Backend admission control remains the enforcement point at execution time. | Platform binding (Internal HTTP Surface) |
| REQ-FED-10 | The system shall map internal `correlation_id` values to external `X-Federation-Correlation-ID` headers at the EWBI boundary, ensuring internal trace context never leaks to partner operators while maintaining end-to-end traceability within the platform. | OPG.02 v10.0 §4.2.3; CAMARA Commonalities r4.3 |
| REQ-FED-10 | The system shall keep internal `correlation_id` values inside the platform: stored in `federation_transactions` and logs, never sent to a partner in any header or field. FM shall add no custom tracing header to EWBI requests or responses; cross-operator correlation relies only on identifiers OPG.04 defines (`federationContextId`, `txnIdentifier`/`apiTxnId`, `Idempotency-Key`, `Location`). | OPG.04 v6.0 OpenAPI v1.4.0 (no correlation header defined); OPG.02 v10.0 §4.2.3 |
| REQ-FED-11 | The system shall enforce per-partner rate limits keyed by `partner_op_id` and API type with configurable windows, to protect internal infrastructure from partner abuse. Limits are enforced per FM pod for the current release; the effective fleet-wide rate is approximately (configured limit × pod count) rather than a single global ceiling — see [fm/implementation-and-delivery.md](/fm/implementation-and-delivery.md) §Q.3. | OPG.02 v10.0 §3.3.2.2 (Traffic Management) |
| REQ-FED-12 | The system shall implement OPG.04 federation-management operations, including `CreateFederation`, `GetFederationDetails`, `DeleteFederationDetails`, `GetFederationHealth`, and `RenewFederation`, maintaining partner connection status and alerting on consecutive health-check failures. | OPG.04 v6.0 OpenAPI v1.4.0 |
| REQ-FED-13 | The system shall persist all federation transactions (inbound and outbound) in `federation_transactions` in `fm_db` with enough detail for dispute resolution and audit compliance. | OPG.04 v6.0 |
| REQ-FED-14 | The system shall return EWBI errors as OPG.04 `application/problem+json``ProblemDetails`, using only response statuses declared by each operation unless an explicit OOP OpenAPI profile extends the contract. | OPG.04 v6.0 OpenAPI v1.4.0 |
| REQ-FED-15 | The system shall expose `GET /healthz` and `GET /readyz` via oop-commons health router, with readiness checking PostgreSQL and DataBus connectivity (same baseline as OEG and SRM). Partner federation health is monitored per REQ-FED-12 but does not gate `/readyz`. | Platform baseline |
| REQ-FED-16 | For each OPG.04 operation mapped to SRM, FM shall publish the same canonical command subject and schema as OEG, ensuring SRM receives identical formats regardless of origin (ADR-0001). FM shall not expose `command.srm.service.scale` through EWBI unless a documented OPG.04 profile/extension defines that operation. | Platform binding (Component Boundary Matrix) |
| REQ-FED-17 | The system shall emit structured JSON logs (via oop-commons) including `correlation_id`, `federation_correlation_id`, `partner_op_id`, EWBI method/path, and outcome for all federation operations. | Platform baseline |
| REQ-FED-17 | The system shall emit structured JSON logs (via oop-commons) including `correlation_id`, `external_txn_id`, `partner_op_id`, EWBI method/path, and outcome for all federation operations. | Platform baseline |
| REQ-FED-18 | *(later phase)* The system shall produce secure federation usage/charging records and integrate them with the operator-controlled charging system according to configured charging factors. FM does not perform inter-operator financial settlement. | OPG.02 v10.0 §4.3.3 and Annex G |
| REQ-FED-19 | The system shall provide an internal admin API (L.2) for the full partner onboarding, update, and decommission lifecycle, and for managing routing rules. For partner OP profiles and federation agreements specifically, *create* normally arrives via OEG's proxied federation-establishment trigger (`command.fm.federation.create`, ADR-0043) or FM's own bootstrap configuration, with L.2's `POST /internal/partners` / `/internal/agreements` remaining available for operational/break-glass use; `read`/`update`/decommission stay on L.2 for both, unaffected. Routing rules are out of ADR-0043's scope (they serve subscriber-identifier routing, not federation establishment) — L.2's `POST /internal/routing-rules` remains their sole, primary creation path. | OA UC-FM-06, ADR-0043 |
| REQ-FED-20 | The system shall consume `command.fm.federation.create` and `command.fm.federation.zone_subscribe` published by OEG (ADR-0043), applying the same create/update logic as the L.2 admin API, and shall support an equivalent self-initiated bootstrap path from startup configuration. | ADR-0043 |
| `direction` | VARCHAR(10) | NOT NULL | `inbound` or `outbound` |
| `federation_operation_id` | UUID | | Optional federation-side transaction handle, independent of internal `operation_id`. It is not a universal OPG.04 `operationId`: each OPG.04 operation's own response schema controls which external identifier is returned. NULL for synchronous queries. |
| `operation_id` | UUID | | Correlation to SRM operation when the EWBI call dispatched an async command; NULL for synchronous queries. Never returned to partners. |
| `correlation_id` | UUID | | Internal trace correlation ID (UUID) generated at request entry or accepted from OEG on outbound hand-off (REQ-FED-10); mapped to/from `federation_correlation_id` at the EWBI boundary. Never returned to partners. Stored and passed as UUID (not a stringly-typed value). |
| `federation_correlation_id` | VARCHAR(255) | | Optional OOP `X-Federation-Correlation-ID` extension; NULL when caller omits it |
| `correlation_id` | UUID | | Internal trace correlation ID (UUID) generated at request entry or accepted from OEG on outbound hand-off (REQ-FED-10). Never sent to partners in any header or field. Stored and passed as UUID (not a stringly-typed value). |
| `external_txn_id` | VARCHAR(255) | | OPG.04 transaction identifier both operators hold when the operation defines one (`txnIdentifier` / `apiTxnId`); the cross-operator dispute-lookup key. NULL for operations without one |
| `idempotency_key` | VARCHAR(255) | | Required OPG.04 `Idempotency-Key` for operations that declare it |
| `request_fingerprint` | CHAR(64) | | SHA-256 of canonical request data; rejects reuse of an idempotency key with a different request |
| `external_resource_id` | VARCHAR(255) | | Contract-defined external identifier such as `appInstIdentifier` |
and internal `correlation_id` never leaves the platform (REQ-FED-10).
Likewise, `federation_transactions.federation_operation_id` is internal audit/correlation data; FM
must return the operation-specific identifiers defined by OPG.04 rather than a universal custom
`operationId` response.
@@ -628,7 +630,7 @@ A locally connected App Provider queries device location for a subscriber on a p
3. OEG determines the MSISDN does not belong to the local network. Calls FM `POST /internal/federation/outbound` (L.3) with routing identifiers plus normalized `api_service_id`, customer/transaction context, and `service_api_body`.
4. FM queries routing table: MSISDN prefix `+34` → resolves to Partner OP Telefonica.
5. FM checks federation agreement: location API is permitted with Telefonica.
6. FM strips internal headers, injects `X-Federation-Correlation-ID` as an optional OOP trace extension, and obtains/reuses a `fed-mgmt` token from Telefonica's Authorization Server.
6. FM strips internal headers and obtains/reuses a `fed-mgmt` token from Telefonica's Authorization Server.
7. FM writes `federation_transactions` row (direction=`outbound`).
8. FM resolves the outbound `federationContextId`, constructs the required OPG.04 `APIForwarding` wrapper, and posts it to `https://telefonica-ewbi.example.com/operatorplatform/federation/v1/{federationContextId}/apiservice/DeviceLocation` with `Authorization: Bearer <token>`.
9. Telefonica returns profiled OPG.04 `serviceAPIResponse` and optional session `Location`.
@@ -644,3 +646,4 @@ A locally connected App Provider queries device location for a subscriber on a p
|---------|------|---------|
| 2.0 | 2026-07-07 | OOP Release 2.0. |
| 2.0 | 2026-09-04 | REQ-FED-19 narrowed for partner profiles/agreements only (routing rules explicitly unaffected — out of ADR-0043's scope); added REQ-FED-20/21 for OEG-proxied federation establishment (ADR-0043) and SRM-forwarded federated deploys (ADR-0044). Added L.3a and `command.fm.federation.*` to K.2; L.3 scoped to subscriber-identifier routing only. |
| 2.0 | 2026-09-08 | Dropped the `X-Federation-Correlation-ID` extension: OPG.04 v1.4.0 defines no correlation header and a partner never stores or echoes it. REQ-FED-10 reworded; `federation_transactions.federation_correlation_id` replaced by `external_txn_id` (OPG.04 `txnIdentifier`/`apiTxnId`). |