redis: add credentials provider option and built-in Entra ID auth - #1626
Open
cosmin-staicu wants to merge 5 commits into
Open
redis: add credentials provider option and built-in Entra ID auth#1626cosmin-staicu wants to merge 5 commits into
cosmin-staicu wants to merge 5 commits into
Conversation
|
cosmin-staicu
force-pushed
the
feat/redis-entra-credentials-provider
branch
from
August 4, 2026 14:27
63e17d0 to
3135f36
Compare
cosmin-staicu
force-pushed
the
feat/redis-entra-credentials-provider
branch
from
August 19, 2026 13:19
3135f36 to
e227b1a
Compare
…start The pieces for changing levels at runtime were already here — the root level and every component level are zap.AtomicLevel, Config.Update pushes new values into them, and newSharedConfig registers itself as an update observer — but nothing ever called Update, so a level change meant restarting the process. Add the missing trigger: when LK_LOG_CONFIG_PATH is set, poll that file and apply it to the Config the service is holding (LK_LOG_CONFIG_INTERVAL overrides the 30s default). The hook sits in newSharedConfig, which is the one path every consumer reaches — livekit-server via InitFromConfig, livekit-sip via NewZapLogger — so no binary needs its own flag or call site. Polling rather than fsnotify because the target is a mounted ConfigMap: kubelet swaps the ..data symlink instead of rewriting the file, so a watch on the file never fires. Two details that would otherwise bite: - Update assigns every field, so a partial file decoded into a zero Config would silently reset the rest. Config.snapshot copies the data fields and the file is unmarshalled over that, leaving unspecified keys — including ComponentLevels, where livekit-server puts pion_level — as they were. - sharedConfig kept the caller's live *Config and read ComponentLevels from it under its own mutex, while Update writes those fields under Config.lock. Two mutexes over the same memory was harmless while Update was unreachable; now it is reachable, so sharedConfig holds a snapshot it owns instead. An unreadable file (an optional ConfigMap not yet mounted), unchanged bytes and malformed YAML all leave the config in force untouched, without logging once per interval. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FgV5yPwbxmFhMuN62ybthK Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
feat(logger): apply a log config file to the live logger without a restart
…ast one
Emptying the watched file was supposed to restore the levels the process booted
with. It did not: each file was decoded over a snapshot of the config currently in
force, so once `level: debug` had been applied, an empty file snapshotted debug and
changed nothing. A component_levels entry that disappeared from the file kept
applying for the same reason.
WatchConfigFile now snapshots the startup config once and applyConfigFile decodes
every file over that baseline, which makes the file a declarative overlay: keys it
omits fall back to the startup values.
A file that goes away is still not a reset. A transient read error would otherwise
flap levels on a live process, so the reset is emptying the file to `{}`, which now
works.
Reported by Copilot on UiPath/cx#823.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FgV5yPwbxmFhMuN62ybthK
Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
fix(logger): apply the config file over the startup config, not the last one
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds support for runtime-rotated Redis credentials to
GetRedisClient, with two entry points: a vendor-neutralWithStreamingCredentialsProvideroption and a config-drivenazure_entraflag for Microsoft Entra ID. Backwards compatible — existing callers and YAML are unaffected.GetRedisClientcurrently only accepts a staticUsername/Password. That doesn't work with managed Redis offerings that authenticate via short-lived identity tokens — Azure Managed Redis and Redis Enterprise Cloud issue Microsoft Entra ID tokens that expire (~1h) and must be refreshed and re-AUTH'd on the live connection before they lapse.With only static credentials, a long-running deployment gets disconnected when the token expires. It's worst for the coordination bus that LiveKit relies on: managed Redis evicts pub/sub connections when their token expires, and under RESP2 a pub/sub socket can't process an out-of-band
AUTH, so it must reconnect with a fresh token. Every component that builds its client throughprotocol— server, sip, egress, ingress — is affected.go-redis already supports this through
StreamingCredentialsProvider(≥ v9.6; this module is on v9.20.0), and Redis publishes an official extension,go-redis-entraid, that implements