Universal Search
Google for your identities — but only showing what each user is allowed to see. Relevance-ranked, typo-tolerant search across persons, accounts, groups, roles, and entitlements in 42ms, with three privacy modes and a 3-line React SDK.
Key advantages
The scattered search problem
"200 helpdesk analysts × 40 tickets/day × 5 minutes wasted per search = 666 hours/month — the equivalent of 4 full-time employees doing nothing but fighting search." — Identity Operations Analysis
Unreliable search
SQL LIKE across 60+ columns and 9M+ rows causes full table scans and 5-30 second response times. Users abandon and call the helpdesk.
Zero typo tolerance
"Patrik" returns nothing instead of finding "Patrick." Every misspelling is a dead end and wasted analyst time.
No relevance ranking
Results are alphabetical or random. The right identity is buried on page 3. No weighting by match quality or entity importance.
No privacy controls
All-or-nothing visibility. No PII masking option for helpdesk users — either they see everything or nothing.
Inconsistent behavior
Each console searches different fields with different speed and quirks. Training is a nightmare — 3-5 search-related bugs per plugin.
No filtering capability
Finding "high-risk entitlements" requires exporting to Excel. No faceted search, no real-time drill-down.
Why alternatives fall short
How it works
Source systems publish changes via Kafka. The search indexer builds optimized projections in Postgres 16. Queries pass through a 7-step pipeline with policy-aware post-filtering — results in 42ms, every time.
Index
- →Source systems publish change events to Kafka — SQL Server, Postgres, Neo4j, HR/AD/SAP
- →Indexer computes tsvectors with 4-weight field ranking (A=identifiers, B=names, C=org, D=text)
- →Upserts into Postgres 16 with GIN indexes for FTS and pg_trgm for fuzzy — <5s index lag
Parse & fast-path
- →Queries validated (max 500 chars), normalized, checked for identifier patterns
- →Email "@" or UUID/employee-ID triggers B-tree exact lookup — O(1), <5ms, score 10.0
- →Fast path skips full-text search entirely — critical for security incident response
Search & PDP filter
- →FTS with ts_rank() weighted scoring; trigram fallback if <5 results and query ≥ 3 chars
- →Batched AuthZEN PDP evaluation (max 100/batch, 200ms timeout) — filtered, masked, or full
- →Fail-closed: PDP down = empty results, never unauthorized data. Circuit breaker after 5 failures
Performance at scale
Capabilities
Six core capabilities that transform fragmented identity search into a governed, policy-aware platform service.
7 entity types
Persons · accounts · groups · app roles · entitlements · bundles · delegations
7 entity types
Global search fans out to all 7 entity types simultaneously. Each type has specific facets and filters — risk level for entitlements, system type for accounts, membership count for groups.
- Type-specific facets and filters per entity
- Fan-out search returns unified, relevance-ranked results
- Facet counts are post-PDP — only authorized entities counted
Identifier fast path
Email · UUID · employee ID — B-tree exact lookup in <5ms
Identifier fast path
When a query contains "@" or matches UUID/employee-ID patterns, the system triggers a B-tree exact lookup. O(1), <5ms, score 10.0 with an "exact match" badge. Full-text search is skipped entirely.
- Critical for security incident response — find compromised identities instantly
- Email fast path resolves in <50ms (often <15ms)
Three visibility modes
Full · masked · filtered — enforced by AuthZEN PDP
Three visibility modes
Full mode returns all fields. Masked mode redacts PII (email → a***@acme.com, employee_id hidden). Filtered mode excludes unauthorized entities entirely. Highlights are omitted in masked mode to prevent information leakage via match position patterns.
- Fail-closed: PDP down = empty results, never unauthorized data
- Circuit breaker opens after 5 failures, recovers after 30 seconds
3-layer React SDK
API client · React hooks · UI components
3-layer React SDK
Layer 1: typed API client with caching and AbortController cancellation. Layer 2: React hooks (useSearch, useSuggest) with 300ms debounce and stale-window cache. Layer 3: UI components (SearchBar with WAI-ARIA combobox, FacetPanel, HighlightText with XSS safety).
SearchPagecomponent — full-page search in 3 lines of code- 5 minutes to integrate vs. 2-4 hours per plugin
HMAC-signed pagination
Keyset cursors · HMAC-SHA256 · constant performance
HMAC-signed pagination
Keyset cursors (seek method, not OFFSET) signed with HMAC-SHA256 via pgcrypto. Constant performance at any page depth — page 1 and page 1,000 are equally fast.
- Cross-tenant cursor reuse rejected by design
- PII in URLs stripped by the SDK
Backfill & recovery
Disposable index · 9M rows in ~30 min · resumable
Backfill & recovery
The search index is disposable: truncate and backfill recovers 9M entities in ~30 minutes at 5,000 rows/sec. Chunked, checkpointed, resumable. Resource-bounded: 2 DB connections, 512MB memory.
- If index is compromised — truncate and rebuild, not repair
- Checkpoint resumption handles interruptions gracefully
Business impact
2-5 min to find an identity → under 10 seconds
~200 search-related tickets/month → fewer than 50
2-4 hours per plugin → 5 minutes with the React SDK
2-3 day audit preparation → 2-3 hours with faceted search
How Universal Search compares
Frequently asked questions
How is Universal Search different from adding Elasticsearch?
Universal Search is a purpose-built projection: it indexes from Kafka events, enforces AuthZEN PDP visibility per entity, provides fail-closed security (PDP down = empty, never unauthorized), and serves as the foundation for DGE, Identity Resolution, and AI agents. Elasticsearch would need all of this custom-built. Universal Search also ships with a 3-line React SDK for instant plugin integration.
Can we use our existing Elasticsearch?
The backend is pluggable. Phase 1 uses Postgres FTS, Phase 2 supports OpenSearch. Same SDK, same UX, swap the engine. No rip-and-replace required.
What happens if the PDP is unavailable?
Fail-closed by design. In filtered/full mode, the system returns empty results with a warning. In masked mode, it returns all-masked results. A circuit breaker opens after 5 failures and recovers after 30 seconds. Unauthorized data is never returned under any failure scenario.
How sensitive is the search index data?
Three visibility modes plus fail-closed security. PII in logs is hashed. PII in URLs is stripped by the SDK. Highlight fragments are structured (no raw HTML injection). HMAC-signed cursors prevent cross-tenant reuse. The index is disposable — truncate and backfill in 30 minutes if compromised.
Standards & protocols
Protocols
Accessibility
Compliance
Use cases
Related reading
Ready to see it live?
Book a 15-minute walkthrough with an engineer. We'll map Universal Search to your architecture, show real event flows, and answer every technical question.