Loading vLEI.wiki
Fetching knowledge base...
Fetching knowledge base...
This comprehensive explanation has been generated from 5 GitHub source documents. All source documents are searchable here.
Last updated: September 21, 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.
Multi-OOBI (moobi) is a proposed KERI protocol extension that would enable simultaneous distribution of multiple Out-Of-Band Introduction endpoints from a single store, but faces significant authorization and multi-signature collaboration challenges that currently prevent practical implementation.
Multi-OOBI (moobi) is a conceptual extension to the KERI protocol's Out-Of-Band Introduction (OOBI) mechanism that would theoretically enable the simultaneous distribution of multiple endpoint associations for a single Autonomic Identifier (AID) through a unified operation. Unlike standard OOBIs which create individual (url, aid) tuples, moobi would create a one-to-many mapping of the form (aid, [url₁, url₂, ..., urlₙ]), allowing a single store to share multiple service endpoints in a single exchange.
Standard OOBI: (url, aid) → Single endpoint association
Moobi Concept: (aid, [url₁, url₂, ..., urlₙ]) → Multiple endpoint associations
While not formally implemented, the theoretical moobi structure would extend the basic OOBI tuple format:
{
"aid": "EaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM",
"endpoints": [
{
"url": "http://witness1.example.com:8080/oobi",
"role": "witness",
"authorization": "<auth_record_1>"
},
{
"url": "http://watcher.example.com:8081/oobi",
"role": "watcher",
"authorization": "<auth_record_2>"
},
{
"url": "http://mailbox.example.com:8082/oobi",
"role": "mailbox",
"authorization": "<auth_record_3>"
}
],
"threshold": "2/3",
"signatures": ["<sig_1>", "<sig_2>", "<sig_3>"]
}
Each endpoint within a moobi would require individual authorization records following KERI's cryptographic verification principles:
Authorization Record Structure:
- endpoint_provider: AID of the service provider
- endpoint_role: Specific role designation (witness, watcher, mailbox, etc.)
- authorization_signature: Cryptographic proof of authorization
- key_state: Reference to authorizing key state in KEL
- timestamp: Authorization timestamp for BADA compliance
- expiration: Optional expiration for time-bounded authorizations
Authorization Bottleneck: The fundamental issue is that each endpoint within a moobi requires individual cryptographic authorization. This means:
Collaboration Complexity: In multi-sig scenarios, moobi becomes a "messy collaboration effort" because:
Temporal Ordering: Each authorization record must independently satisfy BADA rules:
Current Best Practice: Use individual OOBIs instead of moobi:
# Distribute endpoints individually
for endpoint in endpoints:
oobi = create_oobi(aid, endpoint.url, endpoint.role)
distribute_oobi(oobi)
Batch Distribution: If efficiency is needed, batch individual OOBIs at the transport layer rather than the protocol layer.
Memory Scaling: Moobi memory requirements scale as O(endpoints × signers), making it inefficient for large endpoint sets.
Network Overhead: Single large moobi creates network bottlenecks compared to distributed individual OOBIs.
Attack Surface: Moobi increases attack surface by creating single points of failure for multiple endpoints.
Partial Compromise: If one authorization is compromised, the entire moobi may need invalidation.
Coordination Testing: Would require complex distributed testing frameworks to validate multi-signer coordination.
Failure Mode Testing: Extensive testing needed for partial failure scenarios and recovery procedures.
Moobi Construction Phase:
Controller → Generate endpoint list
Controller → Create authorization records for each endpoint
Controller → Collect signatures from all required parties
Controller → Bundle into moobi structure
Distribution Phase:
Store → Receive moobi bundle
Store → Validate all authorization records
Store → Verify signature threshold compliance
Store → Distribute to requesting parties
Verification Phase:
Recipient → Parse moobi structure
Recipient → Validate each endpoint authorization independently
Recipient → Verify cryptographic signatures
Recipient → Apply BADA rules for each authorization
The moobi state machine would be significantly more complex than standard OOBI:
States:
- PENDING_AUTHORIZATIONS: Collecting individual endpoint authorizations
- PENDING_SIGNATURES: Awaiting multi-sig collaboration
- READY_FOR_DISTRIBUTION: All requirements satisfied
- PARTIALLY_VALID: Some endpoints authorized, others failed
- EXPIRED: Time-bounded authorizations expired
- REVOKED: One or more authorizations revoked
Each endpoint within a moobi requires independent cryptographic authorization:
def validate_moobi_endpoint(endpoint, aid_kel):
"""
Each endpoint must be individually authorized
"""
auth_record = endpoint['authorization']
# Verify endpoint provider authorization
if not verify_provider_authorization(auth_record, aid_kel):
return False
# Verify role-specific permissions
if not verify_role_authorization(endpoint['role'], auth_record):
return False
# Apply BADA rules for temporal ordering
if not apply_bada_rules(auth_record, aid_kel):
return False
return True
Different endpoint roles require different authorization levels:
Role Authorization Requirements:
- witness: Requires delegation event (drt) or explicit witness authorization
- watcher: Requires watcher agreement and threshold compliance
- mailbox: Requires mailbox service authorization and access control
- juror: Requires juror pool membership verification
- registrar: Requires registrar authority delegation
In multi-sig scenarios, moobi becomes a "messy collaboration effort":
class MoobiMultiSigChallenge:
def __init__(self, threshold, signers):
self.threshold = threshold # e.g., "2/3"
self.signers = signers
self.authorization_records = []
def collect_authorizations(self):
"""
Each signer must authorize each endpoint individually
Complexity: O(signers × endpoints)
"""
for signer in self.signers:
for endpoint in self.endpoints:
auth = signer.create_authorization(endpoint)
self.authorization_records.append(auth)
def coordinate_signing(self):
"""
All signers must coordinate on the complete moobi
Requires distributed consensus on endpoint list
"""
# This becomes computationally and coordinatively expensive
pass
Signing at the edge scenarios compound the complexity:
Each authorization record within a moobi must comply with BADA rules independently:
def apply_bada_to_moobi(moobi, prior_moobi, kel):
"""
BADA rules must be applied to each authorization record
"""
for i, endpoint in enumerate(moobi.endpoints):
auth_record = endpoint.authorization
prior_auth = prior_moobi.endpoints[i].authorization if prior_moobi else None
# Apply BADA rules individually
if not bada_accept(auth_record, prior_auth, kel):
# Partial failure - what to do with remaining endpoints?
handle_partial_moobi_failure(moobi, i)
class MoobiManager:
def create_moobi(self, aid: str, endpoints: List[EndpointSpec]) -> Moobi:
"""
Create a multi-OOBI with proper authorization
"""
moobi = Moobi(aid=aid)
for endpoint_spec in endpoints:
# Generate authorization record
auth_record = self.create_authorization_record(
endpoint_spec.url,
endpoint_spec.role,
endpoint_spec.provider_aid
)
# Collect required signatures
signatures = self.collect_signatures(auth_record)
moobi.add_endpoint(endpoint_spec, auth_record, signatures)
return moobi
def validate_moobi(self, moobi: Moobi, kel: KEL) -> ValidationResult:
"""
Validate all aspects of a moobi
"""
results = []
for endpoint in moobi.endpoints:
result = self.validate_endpoint_authorization(
endpoint.authorization,
endpoint.role,
kel
)
results.append(result)
return ValidationResult(
overall_valid=all(r.valid for r in results),
endpoint_results=results,
partial_failures=[r for r in results if not r.valid]
)
class MoobiStorage:
def serialize_moobi(self, moobi: Moobi) -> bytes:
"""
CESR-compatible serialization of moobi structure
"""
# Each authorization record must be individually CESR-encoded
cesr_records = []
for endpoint in moobi.endpoints:
cesr_record = cesr_encode({
'url': endpoint.url,
'role': endpoint.role,
'auth': endpoint.authorization,
'sigs': endpoint.signatures
})
cesr_records.append(cesr_record)
return cesr_encode({
'aid': moobi.aid,
'endpoints': cesr_records,
'threshold': moobi.threshold
})
Moobi → KEL Relationships:
- Authorization records must reference specific KEL events
- BADA rules require KEL state for temporal ordering
- Key rotation events invalidate existing authorizations
- Delegation events affect authorization validity
def moobi_witness_coordination(moobi, witness_pool):
"""
Moobi must coordinate with witness pool for validation
"""
witness_endpoints = [e for e in moobi.endpoints if e.role == 'witness']
# Each witness endpoint requires pool consensus
for witness_endpoint in witness_endpoints:
pool_consensus = witness_pool.validate_witness_authorization(
witness_endpoint.authorization
)
if not pool_consensus.valid:
raise WitnessAuthorizationError(
f"Witness pool rejected authorization for {witness_endpoint.url}"
)
def decompose_moobi_to_oobis(moobi: Moobi) -> List[OOBI]:
"""
Convert moobi back to individual OOBIs for compatibility
"""
oobis = []
for endpoint in moobi.endpoints:
oobi = OOBI(
url=endpoint.url,
aid=moobi.aid,
role=endpoint.role
)
oobis.append(oobi)
return oobis
Moobi Operations Complexity:
- Creation: O(n × m × s) where n=endpoints, m=signers, s=signature_ops
- Validation: O(n × v) where v=validation_complexity_per_endpoint
- Storage: O(n × a) where a=authorization_record_size
- Network: O(n × b) where b=bandwidth_per_authorization
def calculate_moobi_memory_footprint(num_endpoints, num_signers, auth_record_size):
"""
Memory requirements scale multiplicatively
"""
base_moobi_size = 256 # bytes for basic structure
authorization_overhead = num_endpoints * auth_record_size
signature_overhead = num_endpoints * num_signers * 64 # 64 bytes per signature
total_size = base_moobi_size + authorization_overhead + signature_overhead
return {
'total_bytes': total_size,
'scaling_factor': num_endpoints * num_signers,
'memory_efficiency': 'Poor - multiplicative scaling'
}
Network Implications:
- Bandwidth: Moobi size grows linearly with endpoints
- Latency: Coordination delays increase with signer count
- Reliability: Single point of failure for entire endpoint set
- Caching: Complex cache invalidation for partial updates
class PartialMoobiFailure(Exception):
def __init__(self, valid_endpoints, failed_endpoints):
self.valid_endpoints = valid_endpoints
self.failed_endpoints = failed_endpoints
def recovery_strategy(self):
"""
How to handle partial moobi failures?
- Fail entire moobi?
- Accept partial moobi?
- Retry failed endpoints?
"""
if len(self.valid_endpoints) >= self.minimum_threshold:
return "ACCEPT_PARTIAL"
else:
return "REJECT_ENTIRE_MOOBI"
def handle_authorization_revocation(moobi, revoked_endpoint_url):
"""
What happens when one endpoint authorization is revoked?
"""
# Remove revoked endpoint
moobi.endpoints = [e for e in moobi.endpoints if e.url != revoked_endpoint_url]
# Check if remaining endpoints meet threshold
if len(moobi.endpoints) < moobi.minimum_threshold:
raise MoobiInvalidatedError("Insufficient valid endpoints after revocation")
# Regenerate moobi signatures?
# This requires re-coordination among all signers
return moobi.regenerate_with_remaining_endpoints()
def handle_temporal_desync(moobi):
"""
Authorization records may have different timestamps
BADA rules become complex with multiple temporal references
"""
timestamps = [e.authorization.timestamp for e in moobi.endpoints]
if max(timestamps) - min(timestamps) > ACCEPTABLE_CLOCK_SKEW:
raise TemporalDesyncError(
"Authorization timestamps exceed acceptable skew"
)
As of the July 27, 2023 KERI development meeting (per Philip Feairheller), moobi remains a conceptual discussion rather than a formal specification due to the identified technical challenges.
KERI Standards Alignment:
- OOBI Specification: Would extend existing OOBI protocol
- CESR Encoding: Must maintain CESR compatibility
- BADA Rules: Must comply with existing BADA mechanisms
- KEL Structure: Must integrate with KEL event processing
If moobi were to be standardized, it would require:
- Formal authorization record schema
- Multi-signature coordination protocol
- Partial failure handling specification
- BADA rule extensions for multi-endpoint scenarios
- Security analysis and threat modeling
- Interoperability testing framework
Instead of moobi, the KERI ecosystem uses:
# Current approach: Individual OOBIs
def distribute_multiple_endpoints(aid, endpoints):
oobis = []
for endpoint in endpoints:
oobi = create_individual_oobi(aid, endpoint.url, endpoint.role)
oobis.append(oobi)
return oobis # Distribute separately
# This avoids the coordination complexity of moobi
If moobi were implemented, it would require extensive monitoring:
class MoobiMetrics:
def __init__(self):
self.creation_latency = Histogram("moobi_creation_seconds")
self.validation_failures = Counter("moobi_validation_failures")
self.partial_failures = Counter("moobi_partial_failures")
self.coordination_timeouts = Counter("moobi_coordination_timeouts")
def track_moobi_operation(self, operation_type, duration, success):
self.creation_latency.observe(duration)
if not success:
self.validation_failures.inc()
The comprehensive analysis reveals that while moobi represents an intuitive extension to OOBI functionality, the technical challenges around authorization, multi-signature coordination, and partial failure handling make it impractical for production use in the current KERI architecture.