Edge Cookie Setup Guide
End-to-end setup and verification guide for Edge Cookie (EC) identity flows.
This guide covers:
- Fastly store setup
- Partner configuration
- Server-to-server batch sync (
/_ts/api/v1/batch-sync) - Identity verification (
/_ts/api/v1/identify) - Auction bidstream verification (
/auction)
Prerequisites
- Trusted Server deployed and reachable (example:
https://trusted-server.example.com) - Access to update
trusted-server.toml/ deployment configuration - Fastly CLI authenticated (for store verification)
- A valid TCF v2 format string (
euconsent-v2) for consent-required requests
1) Required Configuration
Generate the passphrase and partner token independently with openssl rand -base64 32, then set EC configuration in trusted-server.toml. The replace-with-* values below are intentionally rejected placeholders:
[ec]
passphrase = "ec_passphrase"
ec_store = "ec_identity_store"
[[ec.partners]]
name = "Mocktioneer SSP"
source_domain = "formally-vital-lion.edgecompute.app"
api_token = "partner_api_token"
bidstream_enabled = trueThe passphrase and api_token fields contain keys in the Trusted Server secret store, not the credential values. This workflow calls the inbound identify and batch-sync APIs, so its partner needs api_token. Partners that do not call either API may omit it. Provision high-entropy values under ec_passphrase and partner_api_token; see Configuration.
Required behavior assumptions:
- The value stored under
ec_passphraseis long-lived HMAC-SHA256 keying material for EC ID derivation; use a high-entropy random value of at least 32 characters ec_storeis linked to the active Fastly service versionec_storeis the only KV-backed EC lifecycle store; it contains identity graph state, minimal consent metadata, source-domain keyed partner UIDs, and withdrawal tombstones- Live consent is interpreted from request cookies, headers, geolocation, and policy defaults rather than a separate consent KV store
- Partners are configured statically in
[[ec.partners]]and loaded into an in-memory registry at startup source_domainis the canonical key used for stored IDs and controls EID source matching during ingestion- Partner has
bidstream_enabled = trueif you wantuser.ext.eidsin bidstream
2) Configure Demo Variables
TS_BASE_URL="https://trusted-server.example.com"
MOCK_SSP_URL="https://ssp.example.com"
PARTNER_SOURCE_DOMAIN="ssp.example.com"
PARTNER_NAME="Mocktioneer SSP"
# Use the value provisioned under the partner_api_token secret-store key.
PARTNER_API_KEY="<resolved-partner-api-token>"
# Optional: use a real browser EC if already present
EC_ID="<64hex.6chars>"
TCF_CONSENT="<euconsent-v2-string>"
PARTNER_UID="mock-user-$(date +%s)"3) Configure Partner
Partners are configured in trusted-server.toml and loaded at startup:
[[ec.partners]]
name = "Mocktioneer SSP"
source_domain = "formally-vital-lion.edgecompute.app"
api_token = "partner_api_token"
bidstream_enabled = trueProvision the bearer token value under partner_api_token, then deploy or restart after changing partner configuration. The token is required for this demo because it exercises the inbound partner APIs.
4) Acquire or Reuse EC Cookie
If you already have an EC from browser traffic, reuse it.
Otherwise, attempt generation with consent:
curl -si "${TS_BASE_URL}/" \
-H "Cookie: euconsent-v2=${TCF_CONSENT}"Look for:
Set-Cookie: ts-ec=<64hex.6chars>
5) Batch Sync (S2S)
Endpoint: POST /_ts/api/v1/batch-sync
Important: request field is ec_id (full {64hex}.{6alnum} value). The timestamp field remains required for API compatibility, but it no longer orders writes because EC identity entries do not store per-partner sync timestamps. Valid mappings are idempotent last-write-wins: unchanged UIDs are accepted without a write, and different UIDs replace the stored value.
BATCH_UID="${PARTNER_UID}-batch"
NOW_TS="$(date +%s)"
curl -X POST "${TS_BASE_URL}/_ts/api/v1/batch-sync" \
-H "Authorization: Bearer ${PARTNER_API_KEY}" \
-H "Content-Type: application/json" \
-d "{
\"mappings\": [{
\"ec_id\": \"${EC_ID}\",
\"partner_uid\": \"${BATCH_UID}\",
\"timestamp\": ${NOW_TS}
}]
}" | python3 -m json.toolExpected:
{
"accepted": 1,
"rejected": 0,
"errors": []
}6) Verify Identity
Endpoint: GET /_ts/api/v1/identify
curl -s "${TS_BASE_URL}/_ts/api/v1/identify" \
-H "Authorization: Bearer ${PARTNER_API_KEY}" \
-H "Cookie: ts-ec=${EC_ID}; euconsent-v2=${TCF_CONSENT}" | python3 -m json.toolExpected shape:
{
"ec": "<ec-id>",
"consent": "ok",
"degraded": false,
"source_domain": "ssp.example.com",
"uid": "mock-user-123",
"eid": {
"source": "ssp.example.com",
"uids": [{ "id": "mock-user-123", "atype": 3 }]
},
"cluster_size": 12
}7) Verify Auction Bidstream Enrichment
Endpoint: POST /auction
curl -si -X POST "${TS_BASE_URL}/auction" \
-H "Cookie: ts-ec=${EC_ID}; euconsent-v2=${TCF_CONSENT}" \
-H "Content-Type: application/json" \
-d '{"adUnits":[{"code":"test","mediaTypes":{"banner":{"sizes":[[300,250]]}}}]}'Check response headers:
x-ts-ec-consentx-ts-eids
For returning users, ordinary page views should not refresh Set-Cookie: ts-ec=.... A Set-Cookie header is expected when the EC is newly generated.
Decode x-ts-eids:
echo "<x-ts-eids-base64-value>" | base64 -d | python3 -m json.toolExpected decoded payload contains:
source = ssp.example.comuids[0].id = <partner-uid>
8) Fastly KV Operational Checks
List stores:
fastly kv-store listCheck service resource links for active version:
fastly resource-link list --service-id <service-id> --version <active-version>Inspect EC identity entry:
fastly kv-store-entry get --store-id <identity-store-id> --key "${EC_ID}"If batch sync returns ineligible, check whether the KV entry is missing or has consent.ok = false from a withdrawal tombstone.
9) Troubleshooting Quick Map
| Symptom | Likely Cause | Check |
|---|---|---|
invalid_token on batch sync | Wrong partner API key | Re-register partner with known API key |
missing field ec_id | Wrong request schema | Use ec_id field |
/_ts/api/v1/identify returns {"consent":"denied"} | No consent for current request | Send consent cookie |
No uid in /_ts/api/v1/identify | No successful sync yet | Run batch sync or ensure Prebid EID ingestion has populated the partner UID |
See also: Edge Cookies, Configuration, API Reference