Loading vLEI.wiki
Fetching knowledge base...
Fetching knowledge base...
This comprehensive explanation has been generated from 106 GitHub source documents. All source documents are searchable here.
Last updated: October 7, 2025
This content is meant to be consumed by AI agents via MCP. Click here to get the MCP configuration.
Note: In rare cases it may contain LLM hallucinations.
For authoritative documentation, please consult the official GLEIF vLEI trainings and the ToIP Glossary.
Partial disclosure is a graduated disclosure mechanism in ACDC that reveals only selected field maps from a nested attribute tree structure while keeping others compact (represented by their SAIDs), enabling privacy-preserving credential presentations where specific branches can be disclosed or withheld based on verifier requirements and disclosure policies.
Partial disclosure is a privacy-preserving mechanism within the ACDC (Authentic Chained Data Container) specification that operates on nested branches in an ACDC attribute section tree. The fundamental characteristic is binary disclosure control: an attribute branch can either be disclosed (revealed in full detail) or not disclosed (represented only by its SAID - Self-Addressing Identifier).
This mechanism enables credential holders (Disclosers) to progressively reveal credential information to verifiers (Disclosees) based on context, trust level, and contractual agreements. Unlike selective disclosure, which provides fine-grained control over individual attributes within a flat structure, partial disclosure operates on hierarchical field map structures, revealing or concealing entire branches of the attribute tree.
Partial disclosure is characterized as the "weaker version" compared to selective disclosure because it offers less granular control - you can disclose or hide entire nested field maps, but not individual attributes within those maps. However, this coarser granularity is often sufficient for many use cases and provides simpler implementation requirements.
Issuer: The entity that creates the ACDC credential with a nested attribute structure designed to support partial disclosure. The Issuer signs a compact variant of the ACDC where nested field maps are represented by their SAIDs.
Discloser: The entity (often the credential holder or Issuee) that controls which field maps to reveal during presentation. The Discloser makes strategic decisions about what level of detail to disclose based on the interaction context.
Canonical Serialization: Implementations MUST use insertion-ordered field maps and canonical JSON serialization (no whitespace, consistent key ordering) to ensure reproducible SAID computation across different platforms and languages.
Recursive Processing: When computing SAIDs for nested structures, process inner field maps first and replace them with their SAIDs before computing the outer field map's SAID. This ensures the cryptographic binding propagates correctly through the hierarchy.
Hash Function Selection: Use Blake3 or SHA-256 for SAID computation. Blake3 is preferred for performance but SHA-256 provides broader compatibility. The hash function choice must be indicated in the CESR derivation code prepended to the SAID.
Disclosure Boundaries: Design ACDC schemas with field map boundaries that align with natural disclosure decision points. Group related attributes that should be disclosed together into the same nested field map.
Avoid Over-Nesting: While nested structures enable granular disclosure control, excessive nesting complicates disclosure decisions and increases SAID computation overhead. Aim for 2-3 levels of nesting maximum.
Schema Composition: Use JSON Schema oneOf operators to support both compact (SAID string) and expanded (field map object) variants in the same schema definition. This enables validators to accept either form.
SAID Verification First: Always verify that disclosed field maps match their SAID commitments before processing the content. Reject any field map where the computed SAID does not match the expected SAID.
Signature Verification: After verifying individual field map SAIDs, verify the Issuer's signature on the compact variant. This confirms the Issuer's commitment to all field maps, whether disclosed or compact.
TEL Status Checking: Query the Transaction Event Log to verify the credential has not been revoked before accepting any partial disclosure. A revoked credential's disclosures should be rejected regardless of cryptographic validity.
SAID Caching: Pre-compute and cache SAIDs for all field maps during credential creation. This avoids recomputation during disclosure operations.
Compact Variant Storage: Store the compact variant separately from the full ACDC to enable efficient initial presentations without expanding all field maps.
Disclosee: The verifying entity that receives the partially disclosed ACDC. The Disclosee can cryptographically verify that disclosed field maps match their SAID commitments in the compact form, ensuring the disclosed content is authentic and unaltered.
The Issuer creates an ACDC with a hierarchical attribute structure designed for partial disclosure:
{
"v": "ACDC10JSON00011c_",
"d": "EAdXt3gIXOf2BBWNHdSXCJnFJL5OuQPyM5K0neuniccM",
"i": "did:keri:EBkPreYpZfFk66jpf3uFv7vklXKhzBrAqjsKAn2EDIPM",
"s": "ED6jrVPTzlSkUPqGGeIZ8a8FWS7a6s4reAXRZOkogZ2A",
"a": {
"d": "EEveY4-9XgOcLxUderzwLIr9Bf7V_NHwY1lkFrn9y2PY",
"publicInfo": {
"name": "Alice Smith",
"country": "USA"
},
"sensitiveInfo": {
"d": "EH3dCdoFOLe71iheqcywJcnjtJtQIYPvAu6DZIl3MOA",
"ssn": "123-45-6789",
"dateOfBirth": "1990-01-15"
}
}
}
The Issuer computes SAIDs for each nested field map recursively, creating a compact variant where sensitiveInfo is replaced by its SAID.
The Issuer creates a compact variant by replacing nested field maps with their SAIDs:
{
"v": "ACDC10JSON00011c_",
"d": "EAdXt3gIXOf2BBWNHdSXCJnFJL5OuQPyM5K0neuniccM",
"i": "did:keri:EBkPreYpZfFk66jpf3uFv7vklXKhzBrAqjsKAn2EDIPM",
"s": "ED6jrVPTzlSkUPqGGeIZ8a8FWS7a6s4reAXRZOkogZ2A",
"a": {
"d": "EEveY4-9XgOcLxUderzwLIr9Bf7V_NHwY1lkFrn9y2PY",
"publicInfo": {
"name": "Alice Smith",
"country": "USA"
},
"sensitiveInfo": "EH3dCdoFOLe71iheqcywJcnjtJtQIYPvAu6DZIl3MOA"
}
}
The Issuer signs this compact variant and anchors the signature in a Transaction Event Log (TEL), creating a cryptographic commitment to both the disclosed and undisclosed field maps.
When presenting the credential, the Discloser provides the compact variant initially:
publicInfo field map is fully disclosedsensitiveInfo field map is represented only by its SAIDsensitiveInfo field) but cannot access its contentsBased on the interaction context, the Discloser decides whether to reveal additional field maps:
Scenario A - No Further Disclosure: If the Disclosee's requirements are satisfied with the public information, the interaction completes without revealing sensitiveInfo.
Scenario B - Conditional Disclosure: The Discloser may require the Disclosee to agree to contractual terms (via chain-link confidentiality) before revealing sensitiveInfo.
Scenario C - Full Disclosure: After contractual agreements are established, the Discloser provides the full field map:
{
"d": "EH3dCdoFOLe71iheqcywJcnjtJtQIYPvAu6DZIl3MOA",
"ssn": "123-45-6789",
"dateOfBirth": "1990-01-15"
}
The Disclosee verifies the newly disclosed field map:
EH3dCdoFOLe71iheqcywJcnjtJtQIYPvAu6DZIl3MOA)SAID Protocol Compliance: All field maps subject to partial disclosure must be SADs (Self-Addressed Data structures) with properly computed SAIDs. The SAID computation must follow the recursive algorithm:
H(field_map) = H(
field1 = value1,
field2 = value2,
nested_map = H(nested_map) # Recurse for nested structures
)
Cryptographic Binding: The Issuer's signature on the compact variant creates a cryptographic commitment to all field maps, whether disclosed or compact. This binding ensures that:
Hash Function Requirements: The hash function used for SAID computation must be:
KERI typically uses Blake3 or SHA-256 for SAID computation, both providing 256-bit security.
Nested Field Map Architecture: The ACDC attribute section must be structured as a tree where:
d field containing its SAIDInsertion-Ordered Field Maps: ACDC requires insertion-ordered field maps for canonical serialization. This ensures:
Schema Compliance: The ACDC schema must support both compact and expanded variants using JSON Schema composition operators:
{
"oneOf": [
{"type": "string"}, // Compact form (SAID)
{"type": "object"} // Expanded form (field map)
]
}
Asynchronous Disclosure: Partial disclosure supports asynchronous revelation of field maps:
Credential Lifecycle: Partial disclosure must account for credential status:
SAID Mismatch: If a disclosed field map's computed SAID does not match the SAID in the compact variant:
Missing Field Maps: If a Discloser cannot provide a field map for a SAID in the compact variant:
Schema Validation Failure: If a disclosed field map does not conform to the ACDC schema:
Scenario 1: Progressive Trust Building
A credential holder presents a professional credential to a potential employer:
Each stage reveals additional field maps based on the evolving trust relationship and contractual commitments.
Scenario 2: Regulatory Compliance
A financial institution verifies customer credentials for KYC (Know Your Customer) compliance:
Partial disclosure enables risk-based verification where disclosure depth matches regulatory requirements.
Scenario 3: Supply Chain Transparency
A product credential tracks manufacturing and distribution:
Different stakeholders receive different disclosure levels based on their role and need-to-know.
Design for Disclosure Granularity: When creating ACDC schemas, structure the attribute tree to align with expected disclosure patterns:
Implement Disclosure Policies: Establish clear policies for when to disclose field maps:
Leverage Contractual Protections: Combine partial disclosure with contractually protected disclosure:
Optimize for Common Cases: Design disclosure strategies for typical use cases:
IPEX Protocol Integration: Partial disclosure operates within the IPEX (Issuance and Presentation EXchange) protocol:
exn (exchange) messages to request specific field mapsrpy (reply) messages to provide disclosed field mapsTEL Registry Integration: Verify credential status before accepting partial disclosures:
Wallet Integration: Implement partial disclosure in digital wallets:
Verifier Integration: Build verification systems that handle partial disclosures:
Selective disclosure provides finer-grained control than partial disclosure:
Cryptographic Foundation: Selective disclosure uses a cryptographic aggregator mechanism, while partial disclosure uses simpler SAID-based commitments.
Granularity: Selective disclosure operates on individual attributes within a flat structure, while partial disclosure operates on nested field map branches.
Correlation Properties: Selective disclosure provides stronger non-correlation guarantees - disclosed attributes cannot be correlated to undisclosed attributes in the same encompassing block. Partial disclosure does not provide this property; disclosed field maps may reveal structural information about undisclosed field maps.
Complexity: Partial disclosure is simpler to implement and understand, making it suitable for use cases where the additional privacy guarantees of selective disclosure are not required.
Compact disclosure is the foundational mechanism that both partial and selective disclosure build upon:
Compact Disclosure: Represents field maps by their SAIDs without revealing contents.
Partial Disclosure: Selectively expands some field maps while keeping others compact.
Full Disclosure: Expands all field maps, revealing complete credential contents.
Partial disclosure is the middle ground, enabling graduated revelation between fully compact and fully expanded forms.
Graduated disclosure is the overarching framework that encompasses partial disclosure:
Partial disclosure is one of several graduated disclosure strategies, alongside selective disclosure, metadata disclosure, and bulk-issued credential disclosure.
Structural Information Leakage: Even when field maps are not disclosed, their presence in the compact variant reveals structural information:
Mitigation: Use generic field map labels (e.g., data1, data2) or implement private ACDCs with UUIDs to blind structural information.
Correlation Risk: Disclosed field maps may enable correlation across different presentations:
Mitigation: Implement pairwise identifiers, rotate credentials frequently, and vary disclosure patterns across different Disclosees.
Substitution Attack: An attacker attempts to substitute a different field map for a SAID:
Replay Attack: An attacker replays a previously disclosed field map in a different context:
Selective Disclosure Attack: An attacker selectively discloses field maps to manipulate perception:
Implement recursive SAID computation for nested field maps:
import hashlib
import json
def compute_said(field_map):
"""
Compute SAID for a field map with nested structures.
Args:
field_map: Dictionary representing the field map
Returns:
String containing the Base64-encoded SAID
"""
# Create a copy to avoid modifying the original
temp_map = field_map.copy()
# Recursively compute SAIDs for nested field maps
for key, value in temp_map.items():
if isinstance(value, dict) and key != 'd':
# Nested field map - compute its SAID first
nested_said = compute_said(value)
temp_map[key] = nested_said
# Replace the 'd' field with placeholder
if 'd' in temp_map:
said_length = len(temp_map['d'])
temp_map['d'] = '#' * said_length
# Serialize to canonical JSON (insertion-ordered, no whitespace)
canonical_json = json.dumps(temp_map, separators=(',', ':'), ensure_ascii=False)
# Compute hash
hash_bytes = hashlib.blake3(canonical_json.encode('utf-8')).digest()
# Encode to Base64 URL-safe
said = base64.urlsafe_b64encode(hash_bytes).decode('ascii').rstrip('=')
return said
Create compact variants by replacing nested field maps with SAIDs:
def create_compact_variant(acdc, fields_to_compact):
"""
Create a compact variant by replacing specified field maps with SAIDs.
Args:
acdc: The full ACDC structure
fields_to_compact: List of field paths to compact (e.g., ['a.sensitiveInfo'])
Returns:
Compact variant of the ACDC
"""
compact_acdc = acdc.copy()
for field_path in fields_to_compact:
# Navigate to the field
path_parts = field_path.split('.')
current = compact_acdc
for i, part in enumerate(path_parts[:-1]):
current = current[part]
# Replace the field map with its SAID
field_name = path_parts[-1]
field_map = current[field_name]
if isinstance(field_map, dict):
said = compute_said(field_map)
current[field_name] = said
return compact_acdc
Verify disclosed field maps match their SAID commitments:
def verify_disclosed_field_map(compact_variant, field_path, disclosed_field_map):
"""
Verify a disclosed field map matches its SAID in the compact variant.
Args:
compact_variant: The compact ACDC variant
field_path: Path to the field (e.g., 'a.sensitiveInfo')
disclosed_field_map: The disclosed field map to verify
Returns:
Boolean indicating whether verification succeeded
"""
# Navigate to the SAID in the compact variant
path_parts = field_path.split('.')
current = compact_variant
for part in path_parts:
current = current[part]
expected_said = current # Should be a SAID string
# Compute SAID of the disclosed field map
computed_said = compute_said(disclosed_field_map)
# Verify match
return computed_said == expected_said
Implement a progressive disclosure workflow:
class PartialDisclosureManager:
def __init__(self, full_acdc):
self.full_acdc = full_acdc
self.disclosed_fields = set()
def create_initial_presentation(self, public_fields):
"""
Create initial presentation with only public fields disclosed.
"""
fields_to_compact = self._get_all_fields_except(public_fields)
compact_variant = create_compact_variant(self.full_acdc, fields_to_compact)
self.disclosed_fields.update(public_fields)
return compact_variant
def disclose_additional_fields(self, field_paths):
"""
Disclose additional field maps progressively.
"""
disclosed_maps = {}
for field_path in field_paths:
if field_path not in self.disclosed_fields:
field_map = self._get_field_map(field_path)
disclosed_maps[field_path] = field_map
self.disclosed_fields.add(field_path)
return disclosed_maps
def _get_field_map(self, field_path):
"""Navigate to and return the field map at the specified path."""
path_parts = field_path.split('.')
current = self.full_acdc
for part in path_parts:
current = current[part]
return current
def _get_all_fields_except(self, public_fields):
"""Return all field paths except the specified public fields."""
# Implementation would traverse the ACDC structure
# and return all field paths not in public_fields
pass
Partial disclosure is a foundational privacy mechanism in the ACDC specification that enables graduated revelation of credential information through hierarchical field map structures. By operating on nested branches of the attribute tree, it provides a practical balance between privacy protection and verification requirements.
While less granular than selective disclosure, partial disclosure offers simpler implementation, clearer semantics, and sufficient privacy guarantees for many real-world use cases. Its integration with the broader KERI ecosystem - including IPEX for exchange protocols, TEL for credential status, and contractual protections for data governance - makes it a versatile tool for building privacy-preserving credential systems.
Implementers should carefully design ACDC schemas to align with expected disclosure patterns, implement robust SAID verification, and combine partial disclosure with contractual protections to create comprehensive privacy-preserving credential presentations.
Incremental Disclosure: Implement disclosure as an incremental process where previously disclosed field maps are retained and new field maps are added, rather than regenerating the entire disclosure each time.
Timing Attack Mitigation: Use constant-time comparison for SAID verification to prevent timing attacks that could leak information about SAID values.
Input Validation: Validate all disclosed field maps against the ACDC schema before SAID verification to prevent malformed data from reaching cryptographic operations.
Disclosure Logging: Maintain audit logs of all disclosure operations, including which field maps were disclosed, to whom, and when. This supports accountability and incident investigation.
IPEX Message Flow: Implement partial disclosure within IPEX exchange messages using exn messages to request specific field maps and rpy messages to provide them. Support both synchronous (immediate response) and asynchronous (delayed response) patterns.
Wallet UI Design: Provide clear user interfaces that show which field maps are disclosed vs. compact, enable users to select field maps for disclosure, and display disclosure history.
Policy Enforcement: Implement disclosure policies that automatically determine which field maps to disclose based on the Disclosee's identity, the interaction context, and contractual agreements. Support both manual and automatic disclosure decisions.
Graceful Degradation: If a requested field map cannot be disclosed (e.g., due to policy restrictions), return the compact variant with an explanation rather than failing the entire disclosure.
Partial Failure Handling: If some field maps can be disclosed but others cannot, disclose what is possible and clearly indicate which field maps remain compact.
Version Compatibility: Handle schema version mismatches gracefully by supporting multiple schema versions and providing clear error messages when incompatibilities are detected.