Skip to content

Version History

v3.0.0-rc.4 (2026-05-28)

Fixed

  • Approximate (~=) searches return more useful matches and run faster — LDAP ~= filters and the equivalent REST/GraphQL approximate match now find compound names such as “Michael Schmidt” more reliably, while single-field searches on large directories complete faster. Very short search terms still return no matches to protect large directories from expensive broad scans.
  • Approximate searches across multiple fields avoid unnecessary full-directory work — Searches that combine approximate conditions across fields configured for substring search now use the faster available lookup with the same result set as before. Fields that are not configured for substring search continue to use the safe compatibility path.
  • Combined prefix searches across configured search fields are faster — Searches that combine several prefix-searchable attributes with entry name or distinguished name filters now avoid unnecessary full-directory work when only a few entries match. This improves broad search-box queries in large directories while preserving result order and cursor pagination.
  • Custom attributes missing from equality and prefix indexesindices.value-match and indices.partial-match settings (and the SCRIBE_INDICES_VALUE_MATCH / SCRIBE_INDICES_PARTIAL_MATCH environment variables) were silently ignored when set. Only the built-in baseline attributes received equality and prefix indexes. Custom equality and prefix indexes are now created as configured.
  • Abandoned REST count/HEAD and GraphQL requests stop sooner — REST ?include=count, REST HEAD, and GraphQL directory queries no longer keep database work running indefinitely after the client stops waiting. REST count/HEAD requests follow channels.rest.connection-hints.statement-timeout (SCRIBE_REST_STATEMENT_TIMEOUT) when configured and use a 30-second default otherwise; GraphQL requests use a 30-second execution deadline.
  • Searches preserve requested filters and result shapes more consistently — Directory searches with repeated attribute predicates, sorted filters, multi-type results, continuation pages, and point-in-time lookups now preserve the caller’s filters, connection hints, selected fields, and result column names more reliably.
  • Cancelled searches release resources more safely — Count-only searches, point-in-time lookups, and streams cancelled while opening a database connection now use the same cancellation, timeout, and connection policy as normal searches, avoiding leaked connections or permits after callers stop waiting.
  • GraphQL connection responses are more predictable — Connection queries now return requested pageInfo and counts together, support larger configured pagination limits correctly, and handle malformed POST bodies without surprising parsing behavior.
  • REST/OpenAPI export contracts are documented more accurately — Change events now expose their runtime entry identifiers in the API schema, and search export responses document the supported media types and download headers.
  • Query diagnostic reports are safer to share and easier to act on — Redacted support exports avoid raw search values, preserve the context Kenoxa support needs, explain when timing evidence is unavailable, and avoid recommending coverage changes that are already satisfied.
  • Prefix searches recommend the right index setting — Queries that filter by a “starts with” attribute now point operators to indices.value-match instead of indices.partial-match. Attributes that are only ever searched by prefix can be removed from indices.partial-match; combined prefix-and-substring workloads keep both recommendations.
  • Observe recommendations resolve more consistently — Inbox and query recommendation links now open the matching detail views more reliably, recommendations that point to expired query evidence are hidden, and storage coverage views use the available screen width more effectively.
  • Ingestion and maintenance edge cases are handled more safely — Interrupted throttling no longer drops a live LDAP entry, reconciliation startup failures clean up active sync work, transient LDAP search interruptions reconnect with bounded warnings, and maintenance scheduling now recognizes threshold-only soft schedules.
  • Monitoring and deployment bundles start more reliably — Helm health probes, Grafana OAuth passthrough, production replica defaults, monitoring-only datasources, full-stack Compose startup, and shutdown error reporting now match the runnable deployment shapes.

Changed

  • Single-attribute approximate searches on short common names may return fewer matches — Approximate matching is more selective for short terms against attributes that usually hold a single word, such as givenname. A search like givenname ~= "mic" may return a smaller set than in prior releases. Multi-field approximate searches and approximate searches against attributes that commonly hold multiple words, such as cn or description, are unaffected. Contact support if a specific attribute needs different matching behavior.
  • Index attributes are fetched automatically — Attributes listed in a transcribe’s indices.value-match, indices.partial-match, or indices.sortable are now fetched and stored automatically. They no longer need to be duplicated in ldap.attributes.
  • Kubernetes readiness now tracks traffic safety/readyz and JSON readiness report when the pod can safely receive requests. Scripts that need to wait for initial ingest and required index work to finish should use /observe/convergence. See Endpoints.
  • Observe recommendations are retained across restarts by default — Recommendation history and query diagnostic reports now remain available after restart. Set monitoring.hints.persistence.enabled = false to keep recommendations memory-only, or monitoring.hints.persistence.clear-on-startup = true to start each run with an empty recommendation history.
  • Query diagnostics are easier to share — Slow-query rows, coverage evidence, and recommendation links now open a report page that starts with operator actions and can export a Redacted or Full support bundle when Kenoxa support requests it.
  • Diagnostics and operator signals are easier to interpret — Reports preserve troubleshooting context and count repeated observations consistently, ingest lag severity matches the documented thresholds, and Observe recommendation pruning avoids deleting concurrent lifecycle updates.

v3.0.0-rc.3 (2026-05-15)

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.
  • Upgrades catch unsafe configurations earlier and fail more clearly — PostgreSQL 17/18 support, storage hardening, startup validation, clearer error codes, support IDs, and cleaner shutdown and cancellation behavior make upgrades easier to diagnose. 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 /mcp and /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/docs ships 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, recommendation history, 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 attributesentryID, entryName, entryRDN, and verifiedTimestamp are available across channels. See Data Model.
  • Virtual attributes can delegate upstream and vary by entry type — REST and GraphQL also validate them more strictly. 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.
  • Large-directory searches adapt safely to observed traffic — IdentityScribe uses query traffic and maintenance statistics to keep performance predictable across data distributions. It uses safe exact choices while evidence 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 503 and Retry-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

  • Startup detects ambiguous storage before writing — It catches naming collisions and repairs legacy database layout issues. See Upgrading.
  • Startup and schema validation — REST/OpenAPI and GraphQL naming collisions fail early with actionable errors. See REST Channel and GraphQL Channel.
  • Startup handles orphaned transcribe types explicitly — It can warn, fail, or ignore 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.
  • Observe entry point and layout/ui/observe lands on Inbox so open recommendations are visible first. System status renders as a collapsible header with per-operator collapsed-state, and previously closed recommendations that re-appear surface above Open in their own Regressed section. See Monitoring.

Fixed

  • Faster sorted substring search — Sorted substring (contains) searches now pick the faster path more reliably at small and medium directory sizes. See Database Tuning.

  • Authentication fails closed — Empty bearer tokens and unsupported ProxyAuth forms return authorization failures instead of inconsistent behavior.

  • Bearer DN claims enforce scope — Bearer dn claims now honor the configured LDAP base, matching DN and username ProxyAuth paths.

  • UI auth gating respects auth.enabled=false/ui and 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.

  • Timeouts cancel database work and timestamps stay consistent across time zones — Shutdown is quieter, and failed or timed-out requests promptly cancel their remaining work.

  • Backward paging reports and streams cursor metadata correctly — Clients receive complete pagination state in both directions.

  • Delegated virtual attributes forward without false self-reference warnings — Forwarding and validation now agree on self-references.

  • Authentication paths fail closed more consistently — OpenID Connect, token introspection, trusted client IP handling, and HTTPS certificate-chain limits now reject uncertain states.

  • Reconciliation and history preserve the right entry state — Distinguished-name changes, temporal lookups, history rewind, and change-history streams now return correct results and surface invalid requests as structured errors instead of silent success.

  • Large searches avoid result-boundary errors — Negated filters, large value ranges, cursor pagination, and sorted result boundaries no longer hit edge cases that could return incorrect rows.

  • REST, GraphQL, LDAP, and MCP honor their documented contracts — Exports enforce row-limit and pagination rules before committing responses, GraphQL returns standard error fields and per-entry changes reliably, LDAP Virtual List View jumps work for common single-sort requests, and MCP tools honor standard arguments and numeric limits.

  • Operational signals report their state reliably — Collector endpoint configuration, telemetry lifecycle handling, Prometheus compression negotiation, and index-build status tracking now agree with the running system.

  • The Operator UI preserves navigation state and sanitizes external links — Login redirects preserve query state, entry and history views avoid stale navigation data, and Observe deep links and sidebar states render consistently.

  • Documentation links and examples match the shipped product — Generated and reference material no longer points to unavailable fields or stale commands.

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.enabled instead of channels.<name>.authentication-required. See Authentication.

v2.7.0 (2025-11-14)

Added

  • Virtual attributes are computed when requested — Large multi-valued attributes, including sets with more than 100,000 values, no longer need to be stored with every entry.

    • Define them with LDAP filter expressions and variable substitution.
    • Two patterns are available:
      • Cross-reference: Compute relationships to other entries, such as every group a user belongs to through groupMembership.
      • Self-reference: Filter with the current entry’s attributes, such as a userLevel derived from departmentNumber.
    • Values stay current without consuming entry storage.
    • LDAP clients can request, filter, and sort virtual attributes like stored attributes.
    • Existing database coverage accelerates virtual-attribute searches where applicable.

    Configuration Example:

    ldap {
    virtualAttributes {
    # Cross-reference: Find all groups where this user is a member
    groupMembership {
    filter = "(member={{current.entryDN}})"
    value = "{{other.entryDN}}"
    }
    # Self-reference: Compute user level based on department
    userLevel {
    filter = "(departmentNumber=Executive)"
    value = "senior"
    }
    }
    }
    transcribes = [
    {
    type = "user"
    ldap {
    attributes = """
    cn, sn, mail, groupMembership, userLevel
    """
    # groupMembership and userLevel will be computed virtually
    }
    }
    ]

    Common uses:

    • Large multi-valued attributes such as equivalentToMe on roles, without timeouts or database bloat.
    • Reverse lookups without redundant stored data, such as every group a user belongs to.
    • Values derived from an entry’s own properties, such as access levels or flags.

    See LDAP Configuration for configuration and more examples.

Fixed

  • Checkpoints advance during continuous synchronization — They previously advanced only while the system was idle, delaying offline-delete detection and reconciliation under sustained traffic.
  • Compression monitoring uses 40–50% fewer time series — Memory use and dashboard query time drop while actionable thresholds remain available. Existing dashboards need no changes.
  • LDAP connection metrics no longer become negative — Prometheus now reports the active connection count accurately.
  • Extended DN searches return accurate matches — LDAP filter processing now handles extended DN matching correctly.
  • Forwarded LDAP operations carry more diagnostic context — Logs now identify the relevant entry types for configuration and troubleshooting.
  • Common operational-attribute filters require less database work — LDAP searches avoid unnecessary processing for these attributes.
  • Database helper functions run with less overhead — Their lower-cost implementation reduces work during searches.
  • Searches use configured indexes more reliably — IdentityScribe now keeps the statistics needed to choose them.
  • LDAP forwarding metrics register reliably — The reorganized metrics prevent registration errors. Existing dashboards must be updated for the new format.

v2.6.0 (2025-07-21)

Added

  • Scheduled reconciliation keeps stored entries aligned with LDAP — IdentityScribe periodically verifies entries against the source directory.

    • Set either interval or cron to schedule the maintenance task. See the Configuration Reference for options and defaults.
    • One reconciliation runs after the initial sync and continuous search start, regardless of the schedule, to catch deletions that occurred during downtime.
    • Enable scheduled reconciliation if:
      • Your LDAP server has unreliable persistent-search delete notifications.
      • You need periodic 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.
  • Maintenance tasks can run on a schedule — See the Configuration Reference for options and defaults.

    • These services support maintenance tasks:
      • Database: perform routine storage upkeep after 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.
      • Scribe: reconcile stored entries with the LDAP server.
        • The Scribe maintenance metrics are listed above.
  • Entry data compresses automatically — This reduces storage and network transfer size.

    • IdentityScribe selects the compression algorithm from the data characteristics.
    • Applications need no configuration changes.
    • Typical LDAP entries can use up to 70% less storage.
    • Prometheus metrics report compression effectiveness and cost.
  • LDAP entries keep their identity through restores and renames — Additional matching safeguards protect both initial and continuous synchronization, including rare directory restore and rename cases.

  • Prometheus scrapes return cached metrics — Metrics refresh on a regular interval so scrapes do not wait for collection work.

    • Set monitoring.prometheus.scrapeInterval to control the refresh interval. The default is 15 seconds.
    monitoring.prometheus.scrapeInterval = 15s

Fixed

  • License checks retry transient dependency failures — Connectivity failures involving LDAP or database services no longer crash the service immediately. IdentityScribe retries up to five times.
  • Attribute changes keep their configured casing — Change logs and event descriptions no longer lowercase attribute names, so downstream systems receive the configured names.
  • Reconciliation ignores unobserved operational attributes — It no longer reports false removals for attributes such as createTimestamp, modifyTimestamp, or entryUUID; history contains only changes IdentityScribe actually observed.

Breaking

  • BREAKING: Monitoring uses about half as many time series — dashboards and alerts that depend on the former formats may stop matching. Migration: update them to the formats below before upgrading, test them in staging, and monitor memory use after deployment.

    • Performance Impact
      • ~50% fewer metrics: Reduced from ~1,600 to ~800 total metrics
      • Memory: Rolling windows expire after 5 minutes, reducing memory use and keeping measurements current.
      • Cardinality: Service-transition and LDAP-search labels use fewer combinations.
      • Precision: Summary percentiles replace histogram approximations.
      • Storage: Fewer time series require less monitoring storage.
    • Monitoring Recommendations
      • Update dashboards to use new metric formats before upgrading
      • Test queries in a staging environment before using the new metrics in production.
      • Verify alerts that depend on histogram buckets before upgrading.
      • 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: from and to tags (high cardinality)
      • Added: type tag with fixed 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 type instead of from/to tags
      • Categories: startup, restart, failure, shutdown
      Terminal window
      # Old query
      service_transition_seconds{from="starting",to="running"}
      # New query
      service_transition_seconds{type="startup"}
    • LDAP Search Metrics

      Before: Histogram with 50+ buckets

      channel_ldap_search_time_seconds_bucket{...,le="0.001"} 0
      channel_ldap_search_time_seconds_bucket{...,le="0.002"} 1
      [... 50+ buckets ...]

      After: Summary with selected percentiles

      channel_ldap_search_time_seconds{...,quantile="0.5"} 0.043
      channel_ldap_search_time_seconds{...,quantile="0.95"} 0.051
      channel_ldap_search_time_seconds{...,quantile="0.99"} 0.052

      Changes:

      • 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 direct quantile label access
      • Update SLI/SLO calculations to use summary percentiles
      Terminal window
      # Old query
      histogram_quantile(0.95, rate(channel_ldap_search_time_seconds_bucket[5m]))
      # New query
      channel_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"} 5
      scribe_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.004
      scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.75"} 0.007
      scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.9"} 0.015
      scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.95"} 0.050
      scribe_processing_time_seconds{entryType="user",phase="diffing",quantile="0.99"} 0.487

      Changes:

      • 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 quantile labels instead of histogram_quantile()
      • SLIs can now use direct percentile values
      Terminal window
      # Old query
      histogram_quantile(0.90, rate(scribe_processing_time_seconds_bucket[5m]))
      # New query
      scribe_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"} 1440
      scribe_entry_decode_bytes{codec="lz4|zstd|none",kind="raw|compressed",quantile="0.5"} 1440
      scribe_entry_encode_compression{codec="lz4|zstd",le="5.0"} 4
      scribe_entry_encode_entropy{le="25.0"} 137598

      Reports:

      • Encoded and decoded sizes by codec.
      • Compression thresholds at 85% and 95%.
      • Entropy distribution used for compression choices.
      • Percentiles 0.5, 0.75, 0.9, 0.95, 0.99.

v2.5.0 (2025-06-26)

Added

  • LDAP socket behavior is configurable — Environment variables and configuration properties can tune socket settings; the defaults suit production use.
  • Metrics scraping uses a dynamically balanced worker pool — Scrapes complete with less contention under changing load.

Fixed

  • LDAP presence searches no longer fail on an unsupported optimization — IdentityScribe now sends a valid search to the database.
  • Scribe event metrics use consistent labels — Every scribe_events_count series carries event, op, and target. Add, move, and delete events use "none" where op or target does not apply, preventing meter registration errors.

v2.4.0 (2025-06-25)

Added

  • Directory lookups are faster on large datasets — Additional database coverage reduces work for common entry searches.
  • Binary LDAP entry storage speeds synchronization and retrieval — Entries require less processing as they move between storage and channels.
  • Selective searches use faster execution choices — IdentityScribe adapts database requests to searches that match only a small part of the directory.
  • Initial synchronization avoids unnecessary lock contention — More work can proceed concurrently during the first sync.
  • Synchronization state checks complete faster — Continuous synchronization spends less time determining each entry’s current state.

Fixed

  • Startup counts as healthy while services initialize — Slow startup no longer causes a false health-check failure.
  • Health responses show the correct service name — Operators can identify the affected service directly from the response.
  • Routine monitoring disconnects no longer flood error logs — Client disconnects such as Broken pipe and Connection reset on metrics and health endpoints now log at debug level.
  • Scribe disconnect failures are easier to diagnose — Error handling and logs now preserve the useful failure context.
  • Restarts resume incremental synchronization — IdentityScribe no longer repeats the initial sync after every restart.

Breaking

  • BREAKING: Attribute sets are no longer supported — attributes that exist only in attributeSets stop being observed. Migration: move every listed attribute into the main attributes configuration before upgrading.
# Before (deprecated)
attributeSets = [
"uid, mail, displayName"
]
attributes = "cn sn"
# After (supported)
attributes = """
cn, sn
uid, mail, displayName
"""
  • BREAKING: Refresh-cache metrics were removed — dashboards and alerts that query them stop receiving data. Migration: remove these series from monitoring configuration:
    • scribe.entries.refresh.cache.count
    • scribe.entries.refresh.cache.time

v2.3.0 (2025-05-15)

Fixed

  • Initial synchronization uses bounded memory — Large imports complete faster and no longer fail when memory pressure rises.
  • Large LDAP responses no longer hit a message-size ceiling — Clients can receive entries that previously exceeded the limit.
  • Database connections are acquired more reliably — Pool handling no longer causes avoidable acquisition failures.
  • Memory and CPU metrics report more accurate values — Dashboards reflect resource use more closely.
  • Health endpoints respond faster — Both health and healthy checks require less work.
  • Routine logs are quieter and clearer — Normal activity uses appropriate levels and shorter messages.

Breaking

  • BREAKING: Built-in PostgreSQL metrics were removed — dashboards that rely on them stop receiving data. Migration: collect database metrics with the dedicated Prometheus Exporter.

v2.2.0 (2025-03-21)

Added

  • Entry-size categories improve storage monitoring — Operators can distinguish entry data by size and see the distribution in monitoring views.
  • Type-aware operations complete faster — Stored summaries reduce repeated work when IdentityScribe handles different entry types.

Fixed

  • Service startup and database upgrades coordinate correctly — Service orchestration now follows the database upgrade lifecycle.
  • The LDAP channel starts listening correctly — Clients can connect after channel startup.
  • Memory and CPU metrics report accurate values — Resource dashboards no longer show misleading measurements.
  • Health endpoints respond faster — Both health and healthy checks require less work.

v2.1.2 (2025-02-18)

Fixed

  • Attribute-set configuration rejects non-string values — Invalid elements fail validation with a configuration error.

v2.1.1 (2025-02-17)

Fixed

  • PostgreSQL TLS settings are applied correctly — Secure database connections now honor their configuration.
  • Referenced configuration files load correctly — Split configurations no longer fail while resolving included files.