1. Overview
The LeakAggregator module provides the orchestration layer for BastionGuard’s Identity Leak feature (IdentityLeakPage). It aggregates breach/leak results from multiple independent data providers and returns a single normalized result set for UI consumption.
The module is designed to:
- Support multiple leak intelligence providers through a common interface
- Execute provider queries sequentially and safely
- Ensure failures in one provider do not block the overall query
- Normalize and deduplicate merged results via
LeakNormalizer
2. Components and Interfaces
The module integrates the following internal components:
- ILeakProvider – provider interface exposing
checkEmail(email) - LeakRecord – normalized record structure for leak/breach findings
- LeakNormalizer – canonicalization and normalization pipeline applied to merged results
Providers are injected at runtime using ownership-safe semantics (std::unique_ptr).
3. Provider Registration
3.1 addProvider()
Providers are registered through:
void LeakAggregator::addProvider(std::unique_ptr<ILeakProvider> provider)
Operational behavior:
- Transfers ownership of the provider instance to
LeakAggregator - Stores providers in an internal container (
providers) - Enables composition of multiple heterogeneous provider implementations
This design supports pluggable data sources and simplifies unit testing by allowing provider stubs/mocks.
4. Aggregated Query Execution
4.1 queryAll()
The main execution path is:
std::vector<LeakRecord> LeakAggregator::queryAll(const std::string& email)
The function returns a normalized list of LeakRecord objects, suitable for direct rendering by IdentityLeakPage.
4.2 Provider Iteration Strategy
The module iterates through all registered providers and invokes:
provider->checkEmail(email)
Each provider returns a collection of leak records. These are appended into a single vector (all) in the order they are received.
4.3 Fault Isolation
Provider execution is wrapped in an exception boundary:
- Any
std::exceptionthrown by a provider is caught - The exception is intentionally suppressed
- Processing continues with subsequent providers
This ensures:
- Partial availability of intelligence still yields usable results
- Transient API/provider failures do not break the Identity Leak workflow
Logging is not performed at this layer; upstream components may optionally implement telemetry if required.
5. Normalization and Canonical Output
5.1 LeakNormalizer Integration
After collecting all provider results, the module returns:
LeakNormalizer::normalize(all)
The normalizer is responsible for converting heterogeneous provider records into a canonical representation. Typical tasks performed by a normalizer in this context include:
- Deduplication across providers
- Field canonicalization (service name, breach date formats, categories)
- Confidence/quality harmonization (if providers differ in scoring)
- Sorting/grouping rules for consistent UI presentation
The aggregation layer intentionally does not enforce these policies directly and delegates them to LeakNormalizer.
6. Runtime and Security Considerations
- Isolation of failures: a single provider failure does not prevent the completion of an identity leak query
- Provider trust boundaries: providers may query remote services; input validation and privacy controls should be enforced at provider level or upstream UI policy
- Deterministic output contract: normalization ensures the UI receives a consistent schema regardless of provider variability
- Ownership safety: provider instances are owned exclusively via
std::unique_ptr, preventing accidental shared-lifetime bugs - Performance profile: providers are executed sequentially; if providers involve network I/O, an async or parallel execution model may be introduced in future revisions
- PII handling: the queried identifier (email) is sensitive; any logging/telemetry should be carefully controlled and ideally anonymized or minimized