Changes for decisions/index.md: 1 added line, 0 removed lines.
Original line number
Diff line number
Diff line
@@ -51,3 +51,4 @@ the reasoning lives here. Never renumber; supersede instead (see the record-deci
*[ADR-0047](0047-terminal-record-read-follows-camara-schema.md) - terminal-record read behaviour follows each family's own vendored CAMARA schema: Traffic Influence returns 200 with `state: deleted`, QoD stays 404 (amends ADR-0034's blanket 404 rule and its 204 delete code)
*[ADR-0048](0048-platform-roles.md) - three realm roles (app-provider, operator, platform-admin); new users get app-provider but call only the API products granted to them (each CAMARA scope gated by a product role); tenancy is the `organization` claim, else `sub`; development mode switches login off on localhost (amends ADR-0006's tenant identity and ADR-0035's entitlement note)
*[ADR-0062](0062-zone-state-uses-camara-inactive.md) - `zone.state` uses CAMARA's `active`/`inactive`/`unknown` (was `offline`), so OEG passes the zone status filter and value through unmapped; domain, capability and control-path-binding states keep `offline`
*[ADR-0063](0063-callback-tokens-encrypted-in-oeg-db.md) - client callback tokens (EAM sinkCredential, QoD notificationAuthToken) are stored AES-GCM encrypted in oeg_db under one app-wide key; no key → 501; expired/revoked tokens are tombstoned and their deliveries skipped, never sent unauthenticated (amends ADR-0006's sink_credential_ref)
Changes for oeg/app-deployment-flow.md: 5 added lines, 1 removed line.
Original line number
Diff line number
Diff line
@@ -117,7 +117,10 @@ POST /deployments (CAMARA NBI)
the deploy command's service_specification_id (ADR-0011) — appDeploymentName
from the request body, edgeCloudZones[])
- one app_instances row per zone (state=instantiating, app_deployment_id set)
10. Store callback if subscriptionRequest.sink present
10. Store callback if subscriptionRequest.sink present (callback_registrations, plus an
encrypted callback_credentials row if sinkCredential is present — ADR-0063).
A sinkCredential with no CALLBACK_SETTINGS__SECRET_KEY configured is rejected 501
NOT_IMPLEMENTED before step 9, so nothing is written or published.
11. Publish CommandEnvelopeV1 + SrmServiceDeployV1 with N-entry targets[] (DataBus)
subject: command.srm.service.deploy
│
@@ -321,3 +324,4 @@ mapping is deferred pending that decision (see ADR-0005 revisit trigger).
| Version | Date | Summary |
|---------|------|---------|
| 2.0 | 2026-07-07 | OOP Release 2.0. |
| 2.0 | 2026-10-06 | Step 10 stores the `sinkCredential` encrypted in `callback_credentials` and rejects it `501` when no callback key is configured (ADR-0063). |
`status: failed` (the id was assigned at request time; the instance just never reached `ready`).
`operationId` is never included — it is not a CAMARA field (ADR-0005, ADR-0008).
**Authorization (ADR-0063):** with no `sinkCredential` on the request, the callback is sent
without an `Authorization` header. With one, OEG decrypts the stored token and sends it as
`Bearer`. If that token has expired or been revoked, or cannot be decrypted, the callback is
**skipped**, never sent unauthenticated, and a `callback_deliveries` row records
`state=skipped`. Once every instance under the subscription is `terminated`, OEG revokes the
stored token.
---
# AppInstanceStatus Mapping
@@ -719,3 +735,4 @@ CloudEvent if a callback is registered.
| Version | Date | Summary |
|---------|------|---------|
| 2.0 | 2026-07-07 | OOP Release 2.0. |
| 2.0 | 2026-10-06 | §6.3: `sink_credential_ref` replaced by a `callback_credentials` row (encrypted token + expiry), plus the 501/400 rules for `sinkCredential`; Response 4 states when callbacks carry, omit or skip `Authorization` (ADR-0063). |
Changes for oeg/architecture.md: 2 added lines, 1 removed line.
Original line number
Diff line number
Diff line
@@ -337,7 +337,7 @@ These questions are not resolved by the current architecture text. Keep them vis
| REQ-OEG-05 | For long-running operations, the system shall persist an operation record in `oeg_db` with status `PENDING` under a unique internal `operationId`, publish a `command.srm.*` message on the DataBus matching `CommandEnvelopeV1` + payload schemas shared with SRM, and return HTTP 202 with the CAMARA resource body (`AppInstanceInfo` or `{appDeploymentId}`); `operationId` is exposed only via `/platform/v1/operations/{operationId}` (ADR-0005). | OPG.02 v10.0, OPG.10 v2.0 |
| REQ-OEG-06 | The system shall consume `event.srm.operation.completed` events from the DataBus and shall update the matching `operations` row to `COMPLETED`, `PARTIALLY_COMPLETED`, or `FAILED`, including error details from the payload (ADR-0005). | OPG.02 v10.0 |
| REQ-OEG-07 | The system shall perform idempotent publishes: the same logical request (same `operationId` or client `Idempotency-Key`) shall not create duplicate `PENDING` rows or duplicate `command.srm.*` publishes. | CAMARA Commonalities r4.3 |
| REQ-OEG-08 | When a request carries `subscriptionRequest.sink`, the system shall deliver status-change notifications as CloudEvents (`application/cloudevents+json`) per the vendored CAMARA EAM spec on terminal operation state, authenticating to the sink with `Authorization: Bearer` using the registered `sinkCredential` (ADR-0008). `operationId` is never included in callback payloads. | OPG.02 v10.0, CAMARA Commonalities r4.3 |
| REQ-OEG-08 | When a request carries `subscriptionRequest.sink`, the system shall deliver status-change notifications as CloudEvents (`application/cloudevents+json`) per the vendored CAMARA EAM spec on terminal operation state, authenticating to the sink with `Authorization: Bearer` using the registered `sinkCredential` (ADR-0008), stored encrypted at rest; a delivery whose token has expired or been revoked is skipped, never sent unauthenticated (ADR-0063). `operationId` is never included in callback payloads. | OPG.02 v10.0, CAMARA Commonalities r4.3 |
| REQ-OEG-09 | **Deferred to a later release:** the system shall enforce rate limits per tenant and API product, from the quota in `api_subscriptions` (ADR-0048). Release 2 enforces no rate limits. | OPG.02 v10.0 |
| REQ-OEG-10 | The system shall emit structured JSON logs including `x_correlator`, `operation_id`, `tenant_id`, `app_provider_id`, `client_id`, HTTP method/path, and outcome. | Platform baseline |
| REQ-OEG-11 | The system shall record API usage for billing/analytics in `api_usage_records` with timestamp, API family, HTTP status, and bytes estimate. | OPG.02 v10.0 |
@@ -505,3 +505,4 @@ Structured logging and correlation IDs are the minimum observability baseline. P
| 2.0 | 2026-09-04 | UC-OEG-05 split by target type: zone-based deployment locality moves to SRM (ADR-0044), subscriber-identifier routing unchanged. Added UC-OEG-06 and REQ-OEG-17 for the OEG-proxied federation-establishment trigger (ADR-0043). Zone-based flow's cross-references corrected from UC-SRM-03/§G3 (now inbound/subscriber-identifier-only) to UC-SRM-03a/§G4. |
| 2.0 | 2026-10-04 | Auth responsibility and REQ-OEG-02 add per-operation CAMARA scope checks; F4 resolved for tenancy (`organization` claim, else `sub`), device mapping still open; F5 records that tenant scoping of reads and deletes is deferred; REQ-OEG-09 rate limits deferred and keyed by tenant and API product (ADR-0048). |
| 2.0 | 2026-10-04 | Auth and logging match the OEG implementation: no `oop-commons`; the CAMARA scope is required for every token, including QoD sessions (stricter than QoD v0.10.1). REQ-OEG-10 and §Structured Logging list the fields OEG logs (caller `tenant_id`, `app_provider_id`, `client_id`; one `http_request` line per request) and what is not logged yet (`operation_id`). |
| 2.0 | 2026-10-06 | REQ-OEG-08: the sink token is stored encrypted, and expired/revoked tokens skip the delivery (ADR-0063). |