Summary
9.0 adds caller ownership to the reporting ledger. Every configuration generation, obligation and status row is keyed by (account_id, consumer_id, …). The request a reporting source receives does not name that consumer. ReportingSourceSliceRequestV1.identity (ReportingSourceIdentityV1) carries account_id, delivery_config_id, delivery_config_version, reporting_obligation_id and source_scope, but no consumer_id.
Why it matters
Some sellers authorize delivery reads per caller: a buyer principal may only read its own media buys. Such a seller needs to know whose obligation it is fetching for. There are two ways to get that today:
- Put the consumer into
source_scope. The account context resolver receives the ReportingConfiguration, which has consumer_id. This works, but source_scope is documented as the opaque place a source pins itself (provider, network, credential binding). The caller is an authorization fact, not a pin. Every adopter has to remember to add it. If one forgets, its source fetches with no caller, or with the wrong one, and nothing in the SDK notices.
- Fold the caller into
account_id (for example tenant:account:principal). This is what we did before 9.0. It duplicates what caller ownership now does, and then responses have to be rewritten so buyers see their own account id.
A third option is to look the obligation up by reporting_obligation_id through the store. That costs an extra read per slice and depends on store internals.
Ask
Add consumer_id to ReportingSourceIdentityV1 (or to ReportingSourceSliceRequestV1), set from the obligation the slice is for. If it belongs in the logical slice fingerprint, fingerprint it there too.
Context
Hit while moving the Embedded Sales Agent (scope3data/embedded-sales-agent) to 9.0.0b1. It keeps option 2 for now (core/reporting.py, ledger_account_id). It would drop the fold once the slice request names the consumer.
Summary
9.0 adds caller ownership to the reporting ledger. Every configuration generation, obligation and status row is keyed by
(account_id, consumer_id, …). The request a reporting source receives does not name that consumer.ReportingSourceSliceRequestV1.identity(ReportingSourceIdentityV1) carriesaccount_id,delivery_config_id,delivery_config_version,reporting_obligation_idandsource_scope, but noconsumer_id.Why it matters
Some sellers authorize delivery reads per caller: a buyer principal may only read its own media buys. Such a seller needs to know whose obligation it is fetching for. There are two ways to get that today:
source_scope. The account context resolver receives theReportingConfiguration, which hasconsumer_id. This works, butsource_scopeis documented as the opaque place a source pins itself (provider, network, credential binding). The caller is an authorization fact, not a pin. Every adopter has to remember to add it. If one forgets, its source fetches with no caller, or with the wrong one, and nothing in the SDK notices.account_id(for exampletenant:account:principal). This is what we did before 9.0. It duplicates what caller ownership now does, and then responses have to be rewritten so buyers see their own account id.A third option is to look the obligation up by
reporting_obligation_idthrough the store. That costs an extra read per slice and depends on store internals.Ask
Add
consumer_idtoReportingSourceIdentityV1(or toReportingSourceSliceRequestV1), set from the obligation the slice is for. If it belongs in the logical slice fingerprint, fingerprint it there too.Context
Hit while moving the Embedded Sales Agent (scope3data/embedded-sales-agent) to 9.0.0b1. It keeps option 2 for now (
core/reporting.py,ledger_account_id). It would drop the fold once the slice request names the consumer.