Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
bf0aeb2
Add the ID5 identity provider
dhruv8sh Nov 1, 2026
bdbbeab
Add the LiveIntent identity provider
dhruv8sh Nov 1, 2026
d62b5b3
Fix vendor expiry, opt-out and parsing issues
dhruv8sh Nov 2, 2026
40a2239
Let identity providers read their own first-party cookies
dhruv8sh Nov 2, 2026
132f33c
Add the LiveRamp identity provider
dhruv8sh Nov 2, 2026
90c5cbe
Add the Yahoo ConnectID identity provider
dhruv8sh Nov 2, 2026
5193e8a
Add the UID2 identity provider
dhruv8sh Nov 2, 2026
fc9fdd0
Read the ID5 ID from its first-party cookie
dhruv8sh Nov 2, 2026
fceef64
Pass the configured provider ID to identity provider builds
dhruv8sh Nov 2, 2026
f5a75fc
Use cookie name lists across cookie-reading providers
dhruv8sh Nov 2, 2026
8ce1110
Add a Lockr cookie capability for identity providers
dhruv8sh Nov 2, 2026
7b0e085
Mark LiveIntent partner IDs and require a did- distributor ID
dhruv8sh Nov 2, 2026
75a9477
Let identity providers build an EID ext and read cookies in lookups
dhruv8sh Nov 2, 2026
7eb2026
Send the LiveIntent first-party cookie and port its reply mapping
dhruv8sh Nov 2, 2026
9c8fdad
Carry the ID5 linkType and keep ext from encoded ID5 cookies
dhruv8sh Nov 2, 2026
e4faab3
Note the reference provider behaviours left unported
dhruv8sh Nov 2, 2026
d956e90
Read the bare LiveRamp envelope Prebid stores in idl_env
dhruv8sh Nov 2, 2026
82e662d
Add a SharedID identity provider reading the Prebid first-party cookie
dhruv8sh Nov 2, 2026
a7ba910
Add a Criteo identity provider reading the cto_bidid cookie
dhruv8sh Nov 2, 2026
666096e
Add a Unified ID identity provider reading the pbjs-unifiedid cookie
dhruv8sh Nov 2, 2026
4853bec
Document that LiveIntent partner IDs need the publisher distributor ID
dhruv8sh Nov 2, 2026
ab28901
Honour vendor cookie opt-outs and bound cookie-supplied expiry
dhruv8sh Nov 3, 2026
d5a03a7
Refresh UID2 tokens, generate SharedIDs and look up LiveRamp envelope…
dhruv8sh Nov 4, 2026
0dc72b3
Build identity providers when validating the app config
dhruv8sh Nov 4, 2026
d12c9a5
Send ID5 GPP section IDs as an array and use the gs/v2 fetch path
dhruv8sh Nov 5, 2026
d45022c
Send the RFC 3339 timestamp the ID5 gs/v2 fetch requires
dhruv8sh Nov 5, 2026
3aa6910
Log the HTTP status of a failed identity lookup
dhruv8sh Nov 5, 2026
8520709
Treat an ID5 fetch reply with an opt-out UID as an opt-out
dhruv8sh Nov 5, 2026
7e9aa8e
Omit empty LiveIntent segments from the nonId EID
dhruv8sh Nov 5, 2026
d58593b
Read the first non-empty value among duplicate vendor cookies
dhruv8sh Nov 5, 2026
567dec8
Check the lookup rate limit only once a request is built
dhruv8sh Nov 5, 2026
81e9906
Look up the due sources a vendor cookie did not fill
dhruv8sh Nov 5, 2026
bfbe28b
Skip UID2 where GDPR applies
dhruv8sh Nov 5, 2026
8b41fde
Show the TCF vendor ID for the Criteo and Unified ID examples
dhruv8sh Nov 5, 2026
f910910
Note that the ConnectID opt-out is not visible server side
dhruv8sh Nov 5, 2026
4324589
Drop UID2 IDs, including those LiveIntent resolves, where the visitor…
dhruv8sh Nov 5, 2026
7665a01
Generate a SharedID only when the publisher opts in
dhruv8sh Nov 6, 2026
4051496
Check every duplicate cookie for opt-outs and skip expired cookie IDs
dhruv8sh Nov 6, 2026
29c012d
Refresh a due UID even while its cookie repeats it
dhruv8sh Nov 6, 2026
c26a979
Keep held cookie UIDs and refresh state while another source is due
dhruv8sh Nov 11, 2026
8067db1
Hide cookie values from the RequestCookies Debug output
dhruv8sh Nov 11, 2026
81f1e72
Store the percent-decoded Criteo bid ID that Prebid sends
dhruv8sh Nov 11, 2026
35a07e9
Parse LiveRamp v2 envelope replies and send server-to-server atype
dhruv8sh Nov 11, 2026
1c2973f
Send ID5 gpp_sid comma-joined and IPv6 addresses as ipv6
dhruv8sh Nov 11, 2026
cdca7bb
Honour the UID2 SDK opt-out identity cookie
dhruv8sh Nov 11, 2026
69c62e1
Send LiveIntent's TDID as atype 1 and keep nonId when segments are to…
dhruv8sh Nov 11, 2026
996ca33
Match Prebid's ConnectID cookie validity rules
dhruv8sh Nov 11, 2026
7b60dd6
Align provider docs, plans and example config with the code
dhruv8sh Nov 11, 2026
7e3dfc6
Reconcile the vendor providers with the updated collection core
dhruv8sh Nov 12, 2026
8db0bc9
Hand 204 lookup replies to the provider
dhruv8sh Nov 12, 2026
fb0539e
Pass the request time to identity providers
dhruv8sh Nov 12, 2026
5c0bca7
Keep refresh state that is already due
dhruv8sh Nov 12, 2026
7667acf
Keep a refreshed UID2 token over an older cookie token
dhruv8sh Nov 12, 2026
eab8f79
Remember only vendor server opt-outs and let a cookie ID clear one
dhruv8sh Nov 12, 2026
89e0e17
Bound provider relative expiry to 30 days in validation
dhruv8sh Nov 12, 2026
16697b8
Renew an expired generated SharedID instead of replacing it
dhruv8sh Nov 12, 2026
579932d
Test that the Fastly adapter joins every Cookie header for providers
dhruv8sh Nov 12, 2026
54a755f
Check the held-cookie regressions through the write plan
dhruv8sh Nov 12, 2026
fc23145
Send ID5 the provider, domain and origin fields of its server-side cl…
dhruv8sh Nov 12, 2026
f68083c
Skip Lockr cookies where GDPR applies and document the Lockr key overlap
dhruv8sh Nov 12, 2026
8f575ad
Document the UID2 token-chain mitigations and LiveRamp's Custom ID ma…
dhruv8sh Nov 12, 2026
5e01744
Drop placeholder LiveIntent IDs and skip untyped LiveRamp envelopes
dhruv8sh Nov 12, 2026
9b0809a
Log review rounds 7 and 8 for the vendor identity providers
dhruv8sh Nov 12, 2026
9302cf6
Name the commit that bounds UID2 refresh retries in the review log
dhruv8sh Nov 12, 2026
b796282
Name the publisher domain as the LiveIntent TDID provider and keep m
dhruv8sh Nov 12, 2026
c0cfaaf
Withhold stored UIDs of GDPR-excluded sources from egress
dhruv8sh Nov 12, 2026
339681c
Send the previous ID5 signature back as s
dhruv8sh Nov 12, 2026
f364d97
Withhold browser-sent EIDs of GDPR-excluded sources from bidders
dhruv8sh Nov 12, 2026
1427dc4
Potential fix for pull request finding 'CodeQL / Cleartext logging of…
dhruv8sh Nov 12, 2026
ea8d624
Potential fix for pull request finding 'CodeQL / Hard-coded cryptogra…
dhruv8sh Nov 12, 2026
4fd9bd8
Restore the fixed test key in the UID2 reply tests
dhruv8sh Nov 12, 2026
7f55776
Generate the UID2 refresh test key at runtime
dhruv8sh Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 80 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ publish = false
version = "0.1.0"

[workspace.dependencies]
aes-gcm = { version = "0.11", default-features = false, features = ["aes", "alloc"] }
anyhow = "1"
assert_cmd = "2"
async-stream = "0.3"
Expand Down
44 changes: 42 additions & 2 deletions crates/trusted-server-adapter-fastly/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ use trusted_server_core::ec::eid_types::UnixSeconds;
use trusted_server_core::ec::identify::{cors_preflight_identify, handle_identify};
use trusted_server_core::ec::kv::KvIdentityGraph;
use trusted_server_core::ec::page_load::NavigationPermit;
use trusted_server_core::ec::provider::ClientSignals;
use trusted_server_core::ec::provider::{ClientSignals, RequestCookies};
use trusted_server_core::ec::registry::PartnerRegistry;
use trusted_server_core::ec::{EcContext, EcKvSnapshot, EidSyncSource};
use trusted_server_core::error::{IntoHttpResponse as _, TrustedServerError};
Expand Down Expand Up @@ -395,6 +395,7 @@ pub(crate) struct AfterResponseLookups {
pub(crate) ec_id: String,
pub(crate) client_ip: Option<IpAddr>,
pub(crate) user_agent: Option<String>,
pub(crate) cookie_header: String,
}

/// Identity work a navigation hands to the entry point.
Expand Down Expand Up @@ -427,6 +428,7 @@ pub(crate) fn take_navigation_lookups() -> NavigationLookups {
struct ProviderRequestSignals<'a> {
client_ip: Option<IpAddr>,
user_agent: Option<&'a str>,
cookie_header: String,
}

impl<'a> ProviderRequestSignals<'a> {
Expand All @@ -439,10 +441,23 @@ impl<'a> ProviderRequestSignals<'a> {
.headers()
.get(header::USER_AGENT)
.and_then(|value| value.to_str().ok()),
cookie_header: joined_cookie_header(req),
}
}
}

/// Joins every `Cookie` header on the request into one `; `-separated value.
///
/// HTTP/2 and HTTP/3 clients may split cookies across several headers.
fn joined_cookie_header(req: &Request) -> String {
req.headers()
.get_all(header::COOKIE)
.iter()
.filter_map(|value| value.to_str().ok())
.collect::<Vec<_>>()
.join("; ")
}

/// Captures the request signals for after-response identity lookups on a
/// permitted publisher navigation.
///
Expand All @@ -461,6 +476,7 @@ fn prepare_after_response_lookups(
ec_id,
client_ip: signals.client_ip,
user_agent: signals.user_agent.map(str::to_owned),
cookie_header: signals.cookie_header,
})
}

Expand Down Expand Up @@ -502,6 +518,7 @@ async fn dispatch_identity_lookups(
user_agent: signals.user_agent,
},
publisher_domain: &state.settings.publisher.domain,
cookies: RequestCookies::new(&signals.cookie_header),
rate_limiter: &limiter,
now: UnixSeconds::new(now),
},
Expand Down Expand Up @@ -1630,7 +1647,7 @@ mod tests {
use trusted_server_core::ec::provider::{
EidLevelFields, EidShape, IdentityProvider, LookupInput, LookupOutcome,
ProviderCapabilities, ProviderEid, ProviderError, ProviderExpiry, ProviderRequest,
ProviderResponse, ProviderUid, SourceCapability, SourceInput,
ProviderResponse, ProviderUid, RequestCookies, SourceCapability, SourceInput,
};
use trusted_server_core::ec::registry::PartnerRegistry;
use trusted_server_core::error::TrustedServerError;
Expand Down Expand Up @@ -2813,6 +2830,29 @@ mod tests {
request
}

#[test]
fn provider_cookies_join_every_cookie_header() {
// Arrange: HTTP/2 clients may split cookies across headers.
let mut request = navigation_request("/article");
let headers = request.headers_mut();
headers.append(header::COOKIE, HeaderValue::from_static("a=1; b=2"));
headers.append(header::COOKIE, HeaderValue::from_static("vendor_id=c-1"));

// Act
let joined = super::joined_cookie_header(&request);

// Assert
assert_eq!(
joined, "a=1; b=2; vendor_id=c-1",
"should join every Cookie header"
);
assert_eq!(
RequestCookies::new(&joined).get("vendor_id"),
Some("c-1"),
"should let providers read a cookie from a later header"
);
}

fn take_finalize_state(response: &mut Response) -> super::EcFinalizeState {
response
.extensions_mut()
Expand Down
3 changes: 2 additions & 1 deletion crates/trusted-server-adapter-fastly/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use trusted_server_core::ec::eid_types::UnixSeconds;
use trusted_server_core::ec::finalize::ec_finalize_response;
use trusted_server_core::ec::kv::KvIdentityGraph;
use trusted_server_core::ec::page_load::NavigationPermit;
use trusted_server_core::ec::provider::ClientSignals;
use trusted_server_core::ec::provider::{ClientSignals, RequestCookies};
use trusted_server_core::ec::pull_sync::{
PullSyncContext, build_pull_sync_context, dispatch_pull_sync,
};
Expand Down Expand Up @@ -801,6 +801,7 @@ pub(crate) fn run_after_response_lookups(
user_agent: lookups.user_agent.as_deref(),
},
publisher_domain: &settings.publisher.domain,
cookies: RequestCookies::new(&lookups.cookie_header),
rate_limiter: &limiter,
now: UnixSeconds::new(now),
},
Expand Down
2 changes: 2 additions & 0 deletions crates/trusted-server-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ toml = { workspace = true }
toml_edit = { workspace = true }
tracing = { workspace = true }
trusted-server-core = { workspace = true }
trusted-server-identity-providers = { workspace = true }
url = { workspace = true }
uuid = { workspace = true }
validator = { workspace = true }
which = { workspace = true }

# `ts dev lint domains` and `ts dev install-hooks` drive all git access through
Expand Down
Loading
Loading