Skip to content

Align identity-graph reads and tombstones with the provider key form #1073

Description

@jwrosewell

A consistency follow-up from the provider-code envelope work in #1043, filed now so it is not lost; nothing shipped today can hit it.

The asymmetry

On both mint paths (organic generation and the client-cycle resolve), the identity-graph row is written under the provider-coded key with the provider's canonical value form inside the envelope (provider_kv_key, which calls the provider's normalize_id_for_kv on the value part). Reads (identify, EID resolution) and withdrawal tombstones use the raw in-use identifier from the cookie as the key.

For every provider shipped today these are the same string: the HMAC and host-signal providers use the default normalization, which lowercases a hash their generator already emits in lowercase, and the demo provider normalizes to identity. The asymmetry only bites a future provider whose canonical form differs from its minted form, for example one that case-folds: its rows would be written under a key its own reads and tombstones never produce, so a withdrawal marker could miss the row it is meant to kill.

Direction

Withdrawal and tombstoning are core-only operations on the key in use; they are not provider surface, and this fix must keep them that way. Two options, to be decided when the first canonicalizing vendor value is real:

  1. Route every graph access (reads, writes, tombstones) through one keying helper, so the canonical form is applied uniformly.
  2. Drop value normalization from the write path entirely, since the provider-code envelope now provides the namespacing that normalization partly existed for, and require providers to mint in canonical form.

Option 2 is simpler and removes the trap rather than managing it, but it changes the normalize_id_for_kv contract, so it belongs with the vendor-provider work rather than a hotfix.

Produced with AI assistance under James Rosewell's direction; reviewed before filing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions