-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
Parent epic
Description
Implement PartnerRecord, PartnerStore, and the admin registration endpoint that operators use to onboard ID sync partners.
Scope: ec/partner.rs, ec/admin.rs, router update
Acceptance criteria
PartnerRecordcontains all fields from §13.1 includingpull_sync_allowed_domainsandbatch_rate_limit.PartnerStore::get(),upsert(),find_by_api_key_hash()operate onpartner_storeKV.upsert()returnsResult<bool, ...>(true = created, false = updated).- Secondary indexes:
apikey:{hash} → partner_idfor batch auth,_pull_enabled → [partner_ids]for pull sync. Best-effort, not atomic. Old API key index deleted on key rotation. pull_enabled_partners()re-checkspull_sync_enabled == trueon fetched records (stale index guard).- API key stored as SHA-256 hex; plaintext never written to KV.
verify_api_key()uses constant-time comparison. POST /admin/partners/registervalidatesAuthorization: Bearer <token>in-handler againstsettings.ec.admin_token_hash. Returns401before reading body if invalid.- Validates: required fields,
idformat (^[a-z0-9_-]{1,32}$), reserved names, pull_sync_url + ts_pull_token required when pull_sync_enabled, pull_sync_url domain in allowlist. - Returns
201 Createdon new partner,200 OKon update, with explicit response DTO (never serialize full PartnerRecord).400on validation failure,503on KV failure. /admin/partners/registerNOT added toSettings::ADMIN_ENDPOINTS. Admin-route-scan test updated with exclusion list.[[handlers]]pattern narrowed from^/adminto^/admin/keys.
Spec ref
docs/internal/ssc_technical_spec.md §13
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels