All versions since v2.1.1 (2025-02-17)
v2.1.1 (2025-02-17)
Fixes
- ensure postgres ssl config works
- loading of referenced files
v2.1.2 (2025-02-18)
Fixes
- validate elements in attribute set to ensure they are strings in Settings class
v2.2.0 (2025-03-21)
Features
- implement size categorization for entries_data with optimized indexing and monitoring view
- materialized views for improved performance and type handling
Fixes
- enhance service orchestration and database upgrade coordination
- correct LDAP channel listen
- enhance memory and CPU usage metrics
- improve health and healthy check response
v2.3.0 (2025-05-15)
Fixes
- Improved initial data synchronization speed and prevented Out-Of-Memory errors by implementing a high-watermark memory management strategy.
- Eliminated LDAP message size limits to prevent failures with large LDAP server responses.
- Optimized Database connection pool handling to prevent failed acquisitions.
- Enhanced memory and CPU usage metrics for more accurate monitoring.
- Improved performance of health and healthy check responses.
- Streamlined logging levels and messages for better clarity and reduced noise.
Breaking
- Removed built-in Prometheus metrics for PostgreSQL to mitigate excessive database load. For production environments, using the dedicated Prometheus Exporter is now recommended.
v2.4.0 (2025-06-25)
Features
- Faster and More Reliable Lookups: New database indexes have been added to speed up directory entry searches, especially for large datasets.
- Binary LDAP Entry Serialization: Storing LDAP entries in a binary format, for faster processing during sync and retrieval
- Optimized SQL Query Performance: SQL queries are now dynamically constructed for highly selective searches, ensuring PostgreSQL always uses the most efficient query plan.
- Initial Sync Performance: Improved initial synchronization speed by removing unnecessary locking.
- Sync State Query Optimization: Enhanced synchronization speed by optimizing queries that determine the state of entries
Fixes
- Service Info: Improved scribe service info to include the starting state as a healthy state, preventing health check failures during slow startups.
- Health Check: Shows the correct service name in the health check response.
- Monitoring: Suppressed noisy error logs for client disconnects (e.g., βBroken pipeβ, βConnection resetβ) on metrics and health endpoints. These are now logged at debug level instead of error, reducing log noise from normal client disconnects.
- Scribe Service: Improved error handling and logging in case of disconnects for scribe service.
- Scribe Service: After a restart, the scribe service will now continue with the incremental sync instead of the initial sync.
Breaking
- Attribute Sets Removed: Attribute sets are no longer supported and should be removed from the configuration
When removing attributeSets from your configuration, make sure to add all attributes that were previously only listed in
attributeSetsto the main attributes configuration. This ensures that all attributes are still observed and processed as before.
# Before (deprecated)attributeSets = [ "uid, mail, displayName"]attributes = "cn sn"
# After (supported)attributes = """ cn, sn uid, mail, displayName"""- Removed Prometheus Metrics: This version removes the following Prometheus metrics
scribe.entries.refresh.cache.countscribe.entries.refresh.cache.time
v2.5.0 (2025-06-26)
Features
- LDAP Socket Tuning: Added support for tuning the LDAP socket settings using environment variables and configuration properties, with optimized defaults for production environments.
- Monitoring: Use dynamic balanced thread pool for metrics scraping to improve performance.
Fixes
- Query Syntax Correction: Removed invalid
USE INDEXhint from LDAP presence filters. - Prometheus Tag Standardization: All
scribe_events_countmetrics now use a consistent set of tag keys (event,op,target) to comply with Prometheus requirements. For event types whereoportargetare not applicable, the value"none"is used. This applies toevent=add,event=move, andevent=delete. This resolves meter registration errors and ensures reliable metric collection and querying.
v2.6.0 (2025-07-21)
Features
-
LDAP Entry Reconciliation: Automatic reconciliation of entries in the database with the LDAP server.
- The reconciliation is triggered by a maintenance task that runs periodically if either the
intervalorcronis set. See thereference.conffor the configuration options and defaults. - One reconciliation run is triggered after the initial sync is complete and the continuous search is started, regardless of the schedule, to ensure that all deletions during down time are caught.
- Enable scheduled reconciliation if:
- Your LDAP server has unreliable persistent search delete notifications
- You need guaranteed consistency checks for compliance
- You experience frequent network partitions
- New Prometheus metrics for reconciliation:
scribe_reconciliation_entries_verified_total(counter): Number of entries verified as present in LDAP during reconciliation.scribe_reconciliation_entries_deleted_total(counter): Number of entries deleted (synthetic deletes emitted) during reconciliation.scribe_reconciliation_duration_seconds(summary/timer): Total time taken for a full reconciliation run.scribe_reconciliation_last_run_timestamp_seconds(gauge): Unix timestamp of the last completed reconciliation run.
- The reconciliation is triggered by a maintenance task that runs periodically if either the
-
Maintenance Task Scheduling: Added support for scheduling regular maintenance tasks
- Please check the
reference.conffor the configuration options and defaults. - The following services support maintenance tasks:
- Database: for vacuuming and re-indexing the database instead of running these during startup
- New Prometheus metrics for database maintenance:
database_maintenance_duration_seconds(timer): Duration of each maintenance run.database_maintenance_failed_total(counter): Number of failed maintenance runs.database_maintenance_last_run_timestamp_seconds(gauge): Unix timestamp of the last attempted maintenance run.
- New Prometheus metrics for database maintenance:
- Scribe: for automatice reconciliation of entries in the database with the LDAP server.
- New Prometheus metrics for scribe maintenance: are descibed above
- Database: for vacuuming and re-indexing the database instead of running these during startup
- Please check the
-
Intelligent Data Compression: Automatic compression of LDAP entry data to reduce storage footprint and network transfer sizes.
- System automatically selects optimal compression algorithm based on data characteristics
- Completely transparent to applications - no configuration changes required
- Up to 70% reduction in storage usage for typical LDAP entries
- New Prometheus metrics track compression effectiveness and performance
-
LDAP Identity Resolution Reliability: Enhanced the way the system matches and updates LDAP entries, ensuring that even in rare casesβsuch as after directory restores or renamesβentries are always correctly identified and updated.
- Added extra safeguards to prevent rare synchronization issues, further protecting data integrity during both initial and ongoing syncs.
- These improvements make the synchronization process more robust and reliable, especially in complex or high-throughput environments.
-
Monitoring: The metrics are now scraped internally and cached at a regular interval to prevent slow responses.
- Added a new
monitoring.prometheus.scrapeIntervalconfiguration property to control the interval at which the metrics are internally scraped. The default is 15 seconds.
monitoring.prometheus.scrapeInterval = 15s - Added a new
Fixes
- License Verification: Improved license verification to prevent the service from crashing in case of failed license verification due to connectivity issues to third party services like LDAP or databases. The service will now retry up to 5 times.
- Attribute Change Descriptions: Fixed an issue where change logs and event descriptions could use lowercased attribute names instead of the configured casing. All change tracking now consistently uses the attribute casing as defined in your configuration, ensuring clarity and compatibility with downstream systems.
- Operational Attribute Handling: Resolved a bug that could falsely report the removal of certain attributes (such as
createTimestamp,modifyTimestamp, orentryUUID) during entry reconciliation. The system now correctly ignores unobserved operational attributes when comparing entries, preventing spurious removal events and ensuring only relevant changes are tracked.
Breaking Changes
-
Metrics Optimization: This release includes significant changes to metrics that may impact existing dashboards and monitoring configurations.
- Performance Impact
- ~50% fewer metrics: Reduced from ~1,600 to ~800 total metrics
- Memory optimization: Rolling windows with 5-minute expiry to reduce memory usage and provide more accurate metrics
- Reduced cardinality: Service transitions, LDAP searches optimized
- Better precision: Summary percentiles vs histogram approximations
- Lower storage: Fewer time series to store and query, reducing storage requirements
- Monitoring Recommendations
- Update dashboards to use new metric formats before upgrading
- Test queries in staging environment first to ensure the new metrics are working as expected
- Review alerts that depend on histogram buckets to ensure they are still working as expected
- Monitor memory usage after upgrade (should decrease)
Detailed Changes
-
Service Transition Metrics
Before:
service_transition_seconds{service="X",from="new",to="starting",...}service_transition_seconds{service="X",from="starting",to="running",...}service_transition_seconds{service="X",from="running",to="failed",...}After:
service_transition_seconds{service="X",type="startup",...}service_transition_seconds{service="X",type="restart",...}service_transition_seconds{service="X",type="failure",...}Changes:
- Removed:
fromandtotags (high cardinality) - Added:
typetag with meaningful categories (startup,restart,failure,shutdown) - Filtered: Startup noise transitions (
new β starting) - Percentiles: Reduced from 5 to 2 percentiles (
0.5, 0.95)
Migration:
- Update dashboards to use
typeinstead offrom/totags - Categories:
startup,restart,failure,shutdown
Terminal window # Old queryservice_transition_seconds{from="starting",to="running"}# New queryservice_transition_seconds{type="startup"} - Removed:
-
LDAP Search Metrics
Before: Histogram with 50+ buckets
channel_ldap_search_time_seconds_bucket{...,le="0.001"} 0channel_ldap_search_time_seconds_bucket{...,le="0.002"} 1[... 50+ buckets ...]After: Summary with optimized percentiles
channel_ldap_search_time_seconds{...,quantile="0.5"} 0.043channel_ldap_search_time_seconds{...,quantile="0.95"} 0.051channel_ldap_search_time_seconds{...,quantile="0.99"} 0.052Changes:
- Format: Histogram β Summary
- Percentiles: Reduced to
0.5, 0.95, 0.99(high cardinality optimization) - Buckets: Removed all histogram buckets (50+ β 0)
Migration:
- Replace
histogram_quantile()with directquantilelabel access - Update SLI/SLO calculations to use summary percentiles
Terminal window # Old queryhistogram_quantile(0.95, rate(channel_ldap_search_time_seconds_bucket[5m]))# New querychannel_ldap_search_time_seconds{quantile="0.95"} -
Processing Time Metrics
Before: Histogram with SLO buckets
scribe_processing_time_seconds_bucket{entryType="user",phase="diffing",le="0.001"} 5scribe_processing_time_seconds_bucket{entryType="user",phase="diffing",le="0.002"} 25[... many buckets ...]After: Summary with full percentiles
scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.5"} 0.004scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.75"} 0.007scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.9"} 0.015scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.95"} 0.050scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.99"} 0.487Changes:
- Format: Histogram β Summary
- Percentiles: Added
0.5, 0.75, 0.9, 0.95, 0.99(standard set) - Buckets: Removed all histogram buckets
Migration:
- Update queries to use
quantilelabels instead ofhistogram_quantile() - SLIs can now use direct percentile values
Terminal window # Old queryhistogram_quantile(0.90, rate(scribe_processing_time_seconds_bucket[5m]))# New queryscribe_processing_time_seconds{quantile="0.9"} -
New Entry Codec Metrics
Added new compression and entropy metrics:
scribe_entry_encode_bytes{codec="lz4|zstd|none",kind="raw|compressed",quantile="0.5"} 1440scribe_entry_decode_bytes{codec="lz4|zstd|none",kind="raw|compressed",quantile="0.5"} 1440scribe_entry_encode_compression{codec="lz4|zstd",le="5.0"} 4scribe_entry_encode_entropy{le="25.0"} 137598Features:
- Encode/Decode sizes: Track compression effectiveness by codec
- Compression percentage: Business-critical buckets at 85% and 95% thresholds
- Entropy analysis: Optimized buckets for compression decision making
- Percentiles: Standard set
0.5, 0.75, 0.9, 0.95, 0.99
- Performance Impact
v2.7.0 (2025-11-14)
Features
-
Virtual Attributes: Compute attribute values on-demand instead of storing them, solving performance and storage issues with massive multi-valued attributes (100k+ values).
- Define attributes using LDAP filter expressions with variable substitution
- Two patterns supported:
- Cross-reference: Compute relationships to other entries (e.g., finding all groups a user belongs to via
groupMembership) - Self-reference: Filter based on current entryβs attributes (e.g., computing
userLevelbased ondepartmentNumber)
- Cross-reference: Compute relationships to other entries (e.g., finding all groups a user belongs to via
- Zero storage overhead and always up-to-date
- Transparent to LDAP clients - virtual attributes work in searches, filters, and sorting
- Optimized SQL queries leverage existing partitioning and indexing
Configuration Example:
ldap {virtualAttributes {# Cross-reference: Find all groups where this user is a membergroupMembership {filter = "(member={{current.entryDN}})"value = "{{other.entryDN}}"}# Self-reference: Compute user level based on departmentuserLevel {filter = "(departmentNumber=Executive)"value = "senior"}}}transcribes = [{type = "user"ldap {attributes = """cn, sn, mail, groupMembership, userLevel"""# groupMembership and userLevel will be computed virtually}}]Use Cases:
- Massive multi-valued attributes like
equivalentToMeon roles (prevents timeouts and database bloat) - Reverse lookups without storing redundant data (e.g., βshow me all groups this user belongs toβ)
- Computed attributes based on entryβs own properties (e.g., access levels, flags)
See
reference.conffor complete documentation and additional examples.
Fixes
- Checkpoint Advancement Under Load: Checkpoint timestamps now advance incrementally during continuous LDAP synchronization. Previously, checkpoints only updated when the system was idle, causing delays in offline delete detection and reconciliation. This fix improves responsiveness and ensures timely change detection even under sustained traffic.
- Reduced Monitoring Overhead: Simplified Prometheus metric buckets for compression and entropy monitoring, reducing time series by ~40-50%. This lowers memory usage and speeds up dashboard queries while maintaining all actionable thresholds. Existing dashboards remain compatible with no changes required.
- LDAP Connection Monitoring: Fixed an issue where LDAP connection metrics could show negative values in Prometheus monitoring. Connection tracking is now more accurate and reliable.
- LDAP Search Performance: Improved search filter processing for extended DN match filters, ensuring more accurate results.
- Enhanced Logging: Better diagnostic logging when operations are forwarded to the source LDAP server. Logs now include more context about entry types to help with configuration and troubleshooting.
- Query Optimization: Improved performance of LDAP filter processing by optimizing queries for common operational attributes, reducing unnecessary database overhead.
- SQL Function Optimization: Replaced PL/pgSQL functions with SQL functions to improve performance and reduce database overhead.
- SQL Index Optimization: Gather statistics for function based indexes to help the query planner to use the right indexes.
- Prometheus Metrics Restructuring: Reorganized LDAP forwarding metrics to ensure reliable metric collection and prevent registration errors. This change improves monitoring reliability but requires dashboard updates.
v3.0.0 (YYYY-MM-DD)
IdentityScribe v3 is a major platform release for operating and integrating identity data at scale. It adds REST, GraphQL, and MCP access; the built-in Operator UI; embedded documentation; OpenTelemetry-native operations; and large-directory query performance improvements for sorted, filtered, prefix, substring, and cursor-paginated searches.
This release includes breaking database, configuration, endpoint, health, and metrics changes. Plan an upgrade window and start with Upgrading IdentityScribe.
Highlights
- Multi-channel identity APIs β REST/OpenAPI, GraphQL/GraphiQL, MCP, API discovery, streaming export, and consistent identifiers across channels. See REST, GraphQL, and MCP.
- Operator UI and embedded docs β Portal, Entries, Changes, Observe,
/docs, and/ref/*deep links ship with the product. See Monitoring. - Authentication and authorization β OIDC bearer tokens, browser sessions, access rules, channel-specific auth, LDAP bind refinements, and safer ProxyAuth behavior. See Authentication.
- OpenTelemetry-native operations β
/observe/*, MicroProfile health, Prometheus/OTLP metrics, wide logs, pressure signals, Grafana dashboards, Docker Compose, and Helm assets. See Observability and Monitoring. - Large-directory performance β Faster equality, prefix, substring, range, OR, sorted, partial-match, long-text, and cursor-paginated searches, with automatic fallback when acceleration is not suitable. See Database Tuning.
- Change history and point-in-time access β REST and GraphQL access to entry history, temporal lookups, verification timestamps, and operational naming attributes. See Data Model.
- Safer upgrades and supportability β PostgreSQL 17/18 support, partition hardening, startup validation, clearer error codes, support IDs, and cleaner shutdown/cancellation behavior. See Upgrading and Failures.
Breaking Changes
Database support
PostgreSQL 15 and 16 are no longer supported. Upgrade to PostgreSQL 17 or later before installing v3; PostgreSQL 18 is recommended. See Upgrading IdentityScribe.
HTTP, health, and endpoint model
HTTP channels now use one socket configuration model. Deployments that configure old monitoring listener keys such as monitoring.hostname or monitoring.port must move those bindings to http.host, http.port, or http.sockets.*. See the HTTP Server Guide.
Status, health, and legacy monitoring paths changed. Monitoring probes and dashboards using /status, /healthy, or /-/* must move to /observe/*, /readyz, /livez, /startedz, /healthz, or /metrics. JSON health responses now follow MicroProfile Health, so clients parsing the old /healthy body must update their response handling. See Upgrading: endpoints.
Configuration and environment
Environment variable prefixes are standardized on SCRIBE_*. Replace IDENTITY_SCRIBE_* and SCRIBE_TELEMETRY_*. See Upgrading: environment variables.
Connection hints now use a typed session-flags {} object. String-based flag lists and flat work-mem configuration fail startup. See Database Configuration.
Logger configuration is consolidated to the canonical loggers. Old logger keys are removed. See Upgrading: logging.
ldap.authentication-required is removed. Use channels.ldap.auth.enabled. See Authentication.
Observability and client contracts
Metrics now use the scribe.* namespace. Update Prometheus queries, alerts, and dashboards. See Observability.
Error codes are standardized to SCREAMING_SNAKE_CASE. Clients matching on error codes must update their mappings. See Failures.
Broad queries that can span multiple entry types must include an explicit type constraint. Ambiguous requests fail early instead of running against an unintended scope. See Upgrading: query scoping.
Virtual attribute placeholders use {{self.*}}. Legacy {{current.*}} placeholders fail startup with migration guidance. See Upgrading: virtual attributes.
The bundled Grafana datasource now uses OAuth passthrough on the monitoring socket. Existing anonymous Grafana setups must configure OAuth or explicitly opt into temporary anonymous access during migration. See Monitoring.
Added
APIs and integrations
- REST API and OpenAPI UI β Query entries, look up individual identities, stream CSV/JSON/NDJSON/LDIF/JSON-LD exports, read change history, use conditional requests, choose strict or lenient attribute validation, and work with JSON, FleX, SCIM, or LDAP filters from HTTP clients. See REST Channel.
- GraphQL API and GraphiQL UI β Query entries, history, point-in-time state, connection counts, persisted queries, and schema-generated types with Relay-compatible identifiers. See GraphQL Channel.
- MCP channel β AI assistants can query identity data, reference docs, schemas, health, and diagnostics through
/mcpand/observe/mcp. See MCP Channel. - API discovery β
/.well-known/api-catalog, REST specs, and GraphQL schema endpoints make the enabled API surface discoverable. See Channels. - FleX query language β A forgiving filter syntax is available for runtime queries and configuration filters. See Filters Reference.
Operator UI and documentation
- Operator UI β Portal, Entries, Changes, and Observe views provide browser access to system status, identity data, history, pressure, health, JVM metrics, and remediation guidance. See Monitoring.
- Embedded documentation site β
/docsships with guides, reference docs, and/ref/*deep links so operators can jump from config, telemetry, and error references into the matching documentation.
Authentication and access control
- Bearer token authentication β Validate OIDC JWTs offline, support multiple providers, and use the same identity model across REST, GraphQL, MCP, and LDAP. See Authentication.
- Access rules β Define first-match policies using identity, service, request, time, and environment context. See Access Rules.
- Browser sessions β Built-in UI sessions, secure cookies, OIDC redirect handling, and per-UI auto enablement. See Authentication.
- LDAP auth refinements β DN/username bind handling, channel-specific auth settings, unified failure delay, operation-specific gating, strict base enforcement, bind-filter checks, and backend delegation when channel auth is disabled. See LDAP Channel.
Observability and operations
- OpenTelemetry-native observability β Prometheus metrics, OTLP traces/metrics, authenticated metrics export, exemplars, pressure metrics, and structured wide event logs. See Observability.
- Observe endpoints and API UI β Status, health, doctor, pressure, services, indexes, channels, config, license, hints, signatures, attribute coverage, query recommendations, and operational statistics are available under
/observe/*. See Monitoring. - Monitoring bundle β Grafana dashboards, Docker Compose, and Helm assets ship with the distribution. See Monitoring.
- Rule-based log filtering and error classification β Include or suppress wide-log events with glob patterns and LDAP-style filters, and separate noisy client errors from server-health signals. See Logging and Observability.
- Support workflow β Failure responses expose IDs and headers that operators can send to support. See Failures.
Data access and history
- Change history API β REST and GraphQL access to global and per-entry changes, patches, merged views, metadata, and time filters. See REST Channel and GraphQL Channel.
- Point-in-time lookup β Retrieve entry state at a timestamp, relative time, or change cursor. See GraphQL Channel.
- Operational identity attributes β
entryID,entryName,entryRDN, andverifiedTimestampare available across channels. See Data Model. - Virtual attribute improvements β Virtual attributes can be delegated to upstream LDAP backends, scoped by entry type, and validated more strictly in REST and GraphQL. See LDAP Configuration.
Performance and scale
- Large-directory query acceleration β Common equality, prefix, substring, range, OR, sorted, partial-match, long-text, and cursor-paginated searches now use faster paths where safe. Broad or unsupported requests fall back automatically. See Database Tuning.
- Cursor pagination at scale β Sortable single-valued and multi-valued attributes now page more predictably at deep cursors, avoiding several previously pathological large-directory plans. See Database Configuration.
- Adaptive search behavior β Large directories use observed query traffic and maintenance statistics to keep search performance predictable across data distributions. Safe exact plans are used while the system is still warming. See Database Tuning.
- Search and sort controls β Operators can tune advanced search, sort, and preparation behavior when needed. See Database Configuration.
- Backpressure under load β HTTP APIs fail fast with
503andRetry-After; LDAP honors configured time limits. See Database Configuration. - Transcription throughput controls β Bounded workers and queue capacity reduce memory pressure during high ingest. See Transcribes Configuration.
Upgrade and data safety
- Schema hardening β Startup detects naming collisions, repairs legacy database layout issues, and avoids writing to ambiguous storage locations. See Upgrading.
- Startup and schema validation β REST/OpenAPI and GraphQL naming collisions fail early with actionable errors. See REST Channel and GraphQL Channel.
- Transcribe safety checks β Startup can warn, fail, or ignore orphaned transcribe types found in the database but absent from configuration. See Database Configuration.
- Ignored LDAP contexts β Selected LDAP base DNs can bypass local storage and delegate directly to the upstream LDAP backend. See LDAP Channel.
- Faster startup and safer maintenance β Service startup, index builds, readiness reporting, and request cancellation have been tightened for large deployments. See Deployment and Monitoring.
Changed
- Unified HTTP configuration β REST, GraphQL, Observe, docs, and browser UIs share one socket model with named sockets, CORS, compression, request limits, and graceful shutdown. See HTTP Server Guide.
- REST cache semantics β Lookup responses support ETag and Last-Modified validators; search/export responses default to no-store. See REST Channel.
- REST strict/lenient validation β Clients can request strict unknown-attribute handling through
Prefer: handling=strict. See REST Channel. - GraphQL and REST naming β Type, field, and component names are sanitized deterministically with collision guardrails. See REST Channel and GraphQL Channel.
- Transcribes object syntax β Object syntax is preferred and deterministic. Legacy array syntax still works but logs a deprecation warning. See Transcribes Configuration.
- Logging and operator output β Startup summaries, pretty logs, exception logging, third-party logger controls, and routine log noise filtering are cleaner. See Configuration and Observability.
Fixed
- Authentication fails closed β Empty bearer tokens and unsupported ProxyAuth forms return authorization failures instead of inconsistent behavior.
- Bearer DN claims enforce scope β Bearer
dnclaims now honor the configured LDAP base, matching DN and username ProxyAuth paths. - UI auth gating respects
auth.enabled=falseβ/uiand deep links no longer redirect to login when auth is disabled. - Beta upgrade startup β Migration checksum handling no longer blocks affected beta-based upgrade paths.
- Time and shutdown correctness β Timestamps are handled consistently across time zones, shutdown is quieter, failed or timed-out requests cancel remaining database work, and search time limits cancel database work promptly.
- Pagination correctness β Cursor metadata and backward paging now report and stream correctly.
- Virtual attribute behavior β Delegated virtual attributes are forwarded correctly and self-referencing warnings are no longer false positives.
Deprecated
- Legacy config key spellings β camelCase and underscore_case keys still work but log warnings. Use kebab-case keys. See Configuration Reference.
- Legacy transcribes array syntax β Array syntax still works but logs a deprecation warning. Use object syntax keyed by transcribe type. See Transcribes Configuration.
- Legacy channel auth fallback β Use
channels.<name>.auth.enabledinstead ofchannels.<name>.authentication-required. See Authentication.
π§ Unreleased Latest
IdentityScribe v3 is a major platform release for operating and integrating identity data at scale. It adds REST, GraphQL, and MCP access; the built-in Operator UI; embedded documentation; OpenTelemetry-native operations; and large-directory query performance improvements for sorted, filtered, prefix, substring, and cursor-paginated searches.
This release includes breaking database, configuration, endpoint, health, and metrics changes. Plan an upgrade window and start with Upgrading IdentityScribe.
Highlights
- Multi-channel identity APIs β REST/OpenAPI, GraphQL/GraphiQL, MCP, API discovery, streaming export, and consistent identifiers across channels. See REST, GraphQL, and MCP.
- Operator UI and embedded docs β Portal, Entries, Changes, Observe,
/docs, and/ref/*deep links ship with the product. See Monitoring. - Authentication and authorization β OIDC bearer tokens, browser sessions, access rules, channel-specific auth, LDAP bind refinements, and safer ProxyAuth behavior. See Authentication.
- OpenTelemetry-native operations β
/observe/*, MicroProfile health, Prometheus/OTLP metrics, wide logs, pressure signals, Grafana dashboards, Docker Compose, and Helm assets. See Observability and Monitoring. - Large-directory performance β Faster equality, prefix, substring, range, OR, sorted, partial-match, long-text, and cursor-paginated searches, with automatic fallback when acceleration is not suitable. See Database Tuning.
- Change history and point-in-time access β REST and GraphQL access to entry history, temporal lookups, verification timestamps, and operational naming attributes. See Data Model.
- Safer upgrades and supportability β PostgreSQL 17/18 support, partition hardening, startup validation, clearer error codes, support IDs, and cleaner shutdown/cancellation behavior. See Upgrading and Failures.
Breaking Changes
Database support
PostgreSQL 15 and 16 are no longer supported. Upgrade to PostgreSQL 17 or later before installing v3; PostgreSQL 18 is recommended. See Upgrading IdentityScribe.
HTTP, health, and endpoint model
HTTP channels now use one socket configuration model. Deployments that configure old monitoring listener keys such as monitoring.hostname or monitoring.port must move those bindings to http.host, http.port, or http.sockets.*. See the HTTP Server Guide.
Status, health, and legacy monitoring paths changed. Monitoring probes and dashboards using /status, /healthy, or /-/* must move to /observe/*, /readyz, /livez, /startedz, /healthz, or /metrics. JSON health responses now follow MicroProfile Health, so clients parsing the old /healthy body must update their response handling. See Upgrading: endpoints.
Configuration and environment
Environment variable prefixes are standardized on SCRIBE_*. Replace IDENTITY_SCRIBE_* and SCRIBE_TELEMETRY_*. See Upgrading: environment variables.
Connection hints now use a typed session-flags {} object. String-based flag lists and flat work-mem configuration fail startup. See Database Configuration.
Logger configuration is consolidated to the canonical loggers. Old logger keys are removed. See Upgrading: logging.
ldap.authentication-required is removed. Use channels.ldap.auth.enabled. See Authentication.
Observability and client contracts
Metrics now use the scribe.* namespace. Update Prometheus queries, alerts, and dashboards. See Observability.
Error codes are standardized to SCREAMING_SNAKE_CASE. Clients matching on error codes must update their mappings. See Failures.
Broad queries that can span multiple entry types must include an explicit type constraint. Ambiguous requests fail early instead of running against an unintended scope. See Upgrading: query scoping.
Virtual attribute placeholders use {{self.*}}. Legacy {{current.*}} placeholders fail startup with migration guidance. See Upgrading: virtual attributes.
The bundled Grafana datasource now uses OAuth passthrough on the monitoring socket. Existing anonymous Grafana setups must configure OAuth or explicitly opt into temporary anonymous access during migration. See Monitoring.
Added
APIs and integrations
- REST API and OpenAPI UI β Query entries, look up individual identities, stream CSV/JSON/NDJSON/LDIF/JSON-LD exports, read change history, use conditional requests, choose strict or lenient attribute validation, and work with JSON, FleX, SCIM, or LDAP filters from HTTP clients. See REST Channel.
- GraphQL API and GraphiQL UI β Query entries, history, point-in-time state, connection counts, persisted queries, and schema-generated types with Relay-compatible identifiers. See GraphQL Channel.
- MCP channel β AI assistants can query identity data, reference docs, schemas, health, and diagnostics through
/mcpand/observe/mcp. See MCP Channel. - API discovery β
/.well-known/api-catalog, REST specs, and GraphQL schema endpoints make the enabled API surface discoverable. See Channels. - FleX query language β A forgiving filter syntax is available for runtime queries and configuration filters. See Filters Reference.
Operator UI and documentation
- Operator UI β Portal, Entries, Changes, and Observe views provide browser access to system status, identity data, history, pressure, health, JVM metrics, and remediation guidance. See Monitoring.
- Embedded documentation site β
/docsships with guides, reference docs, and/ref/*deep links so operators can jump from config, telemetry, and error references into the matching documentation.
Authentication and access control
- Bearer token authentication β Validate OIDC JWTs offline, support multiple providers, and use the same identity model across REST, GraphQL, MCP, and LDAP. See Authentication.
- Access rules β Define first-match policies using identity, service, request, time, and environment context. See Access Rules.
- Browser sessions β Built-in UI sessions, secure cookies, OIDC redirect handling, and per-UI auto enablement. See Authentication.
- LDAP auth refinements β DN/username bind handling, channel-specific auth settings, unified failure delay, operation-specific gating, strict base enforcement, bind-filter checks, and backend delegation when channel auth is disabled. See LDAP Channel.
Observability and operations
- OpenTelemetry-native observability β Prometheus metrics, OTLP traces/metrics, authenticated metrics export, exemplars, pressure metrics, and structured wide event logs. See Observability.
- Observe endpoints and API UI β Status, health, doctor, pressure, services, indexes, channels, config, license, hints, signatures, attribute coverage, query recommendations, and operational statistics are available under
/observe/*. See Monitoring. - Monitoring bundle β Grafana dashboards, Docker Compose, and Helm assets ship with the distribution. See Monitoring.
- Rule-based log filtering and error classification β Include or suppress wide-log events with glob patterns and LDAP-style filters, and separate noisy client errors from server-health signals. See Logging and Observability.
- Support workflow β Failure responses expose IDs and headers that operators can send to support. See Failures.
Data access and history
- Change history API β REST and GraphQL access to global and per-entry changes, patches, merged views, metadata, and time filters. See REST Channel and GraphQL Channel.
- Point-in-time lookup β Retrieve entry state at a timestamp, relative time, or change cursor. See GraphQL Channel.
- Operational identity attributes β
entryID,entryName,entryRDN, andverifiedTimestampare available across channels. See Data Model. - Virtual attribute improvements β Virtual attributes can be delegated to upstream LDAP backends, scoped by entry type, and validated more strictly in REST and GraphQL. See LDAP Configuration.
Performance and scale
- Large-directory query acceleration β Common equality, prefix, substring, range, OR, sorted, partial-match, long-text, and cursor-paginated searches now use faster paths where safe. Broad or unsupported requests fall back automatically. See Database Tuning.
- Cursor pagination at scale β Sortable single-valued and multi-valued attributes now page more predictably at deep cursors, avoiding several previously pathological large-directory plans. See Database Configuration.
- Adaptive search behavior β Large directories use observed query traffic and maintenance statistics to keep search performance predictable across data distributions. Safe exact plans are used while the system is still warming. See Database Tuning.
- Search and sort controls β Operators can tune advanced search, sort, and preparation behavior when needed. See Database Configuration.
- Backpressure under load β HTTP APIs fail fast with
503andRetry-After; LDAP honors configured time limits. See Database Configuration. - Transcription throughput controls β Bounded workers and queue capacity reduce memory pressure during high ingest. See Transcribes Configuration.
Upgrade and data safety
- Schema hardening β Startup detects naming collisions, repairs legacy database layout issues, and avoids writing to ambiguous storage locations. See Upgrading.
- Startup and schema validation β REST/OpenAPI and GraphQL naming collisions fail early with actionable errors. See REST Channel and GraphQL Channel.
- Transcribe safety checks β Startup can warn, fail, or ignore orphaned transcribe types found in the database but absent from configuration. See Database Configuration.
- Ignored LDAP contexts β Selected LDAP base DNs can bypass local storage and delegate directly to the upstream LDAP backend. See LDAP Channel.
- Faster startup and safer maintenance β Service startup, index builds, readiness reporting, and request cancellation have been tightened for large deployments. See Deployment and Monitoring.
Changed
- Unified HTTP configuration β REST, GraphQL, Observe, docs, and browser UIs share one socket model with named sockets, CORS, compression, request limits, and graceful shutdown. See HTTP Server Guide.
- REST cache semantics β Lookup responses support ETag and Last-Modified validators; search/export responses default to no-store. See REST Channel.
- REST strict/lenient validation β Clients can request strict unknown-attribute handling through
Prefer: handling=strict. See REST Channel. - GraphQL and REST naming β Type, field, and component names are sanitized deterministically with collision guardrails. See REST Channel and GraphQL Channel.
- Transcribes object syntax β Object syntax is preferred and deterministic. Legacy array syntax still works but logs a deprecation warning. See Transcribes Configuration.
- Logging and operator output β Startup summaries, pretty logs, exception logging, third-party logger controls, and routine log noise filtering are cleaner. See Configuration and Observability.
Fixed
- Authentication fails closed β Empty bearer tokens and unsupported ProxyAuth forms return authorization failures instead of inconsistent behavior.
- Bearer DN claims enforce scope β Bearer
dnclaims now honor the configured LDAP base, matching DN and username ProxyAuth paths. - UI auth gating respects
auth.enabled=falseβ/uiand deep links no longer redirect to login when auth is disabled. - Beta upgrade startup β Migration checksum handling no longer blocks affected beta-based upgrade paths.
- Time and shutdown correctness β Timestamps are handled consistently across time zones, shutdown is quieter, failed or timed-out requests cancel remaining database work, and search time limits cancel database work promptly.
- Pagination correctness β Cursor metadata and backward paging now report and stream correctly.
- Virtual attribute behavior β Delegated virtual attributes are forwarded correctly and self-referencing warnings are no longer false positives.
Deprecated
- Legacy config key spellings β camelCase and underscore_case keys still work but log warnings. Use kebab-case keys. See Configuration Reference.
- Legacy transcribes array syntax β Array syntax still works but logs a deprecation warning. Use object syntax keyed by transcribe type. See Transcribes Configuration.
- Legacy channel auth fallback β Use
channels.<name>.auth.enabledinstead ofchannels.<name>.authentication-required. See Authentication.