Each attribute has:

Attributes live in a Merkle Attribute Tree inside the Vault:

attributes_root = MerkleRoot([
    leaf(attribute_1),
    leaf(attribute_2),
    ...
])

Attribute Leaf Encoding

Attribute {
descriptor_id    // e.g. "residency_country"
value_commitment // commitment to the real value
issuer_id        // who asserted it
valid_from
valid_until
attestation_ref? // external attestation link
}

Attribute Tree (recap)

attribute_leaf = H(
  descriptor_id,
  value_commitment,
  issuer_id,
  valid_from,
  valid_until,
  attestation_ref?
)

attributes_root = MerkleRoot(
  sorted_by(descriptor_id, [attribute_leaf_1, attribute_leaf_2, ...])
)

The real values live encrypted in the Vault; the Identity Layer only sees commitments and metadata.

The Vault stores the raw values, encrypted.

The attribute tree only stores commitments and metadata, so Verifiers never see personal data, only committed facts.