<#1137 Cache use improvements in `osctrl-api` and ...
# osctrl
g
#1137 Cache use improvements in `osctrl-api` and `osctrl-tls` Pull request opened by javuto Problem When osctrl-api saved an environment, it deleted the shared Redis cache entry. That left a narrow race: an osctrl-tls request could read the old row from the DB just before the save, then write it to Redis just after the key was deleted. Nodes then got the old environment for up to the 5-minute cache lifetime (TTL). It only happens if the cache entry expires during the save, so it's rare, but a config, secret or flag change could be silently delayed. Separately, osctrl-tls made an extra Redis call (
EXISTS envcache:invalidate:<uuid>
) on every osquery request to check a key that nothing ever sets. Changes • Write the new row into the cache on save. A new
EnvCache.RefreshEnv
method reads the saved row back from the DB and writes it into the cache. If the environment was deleted, it removes the cache entry instead. The API's
invalidateEnvCache
helper now calls it. This matches how the per-node override cache already works (
pkg/nodeconfig
). • Don't overwrite the cache on a miss. When
GetByUUID
doesn't find an environment in Redis, it loads it from the DB and writes it with
SETNX
(only if the key is still empty). An old row read before a save can no longer replace the new one. This adds
RedisJSONCache.SetNX
. • Remove the unused invalidation check. Deleted
SetInvalidationCheck
,
RedisEnvInvalidatePrefix
and the per-request
EXISTS
call in osctrl-tls. That saves one Redis round trip per osquery request. Security / operational impact • Environment changes made through osctrl-api (config, flags, enroll and remove secrets, deletes) now reach osctrl-tls on the next request, even if a cache refill happens at the same time. • One fewer Redis call per osquery request on osctrl-tls. • Known gap: deleting an environment still just removes the cache key, so a deleted environment could come back from the cache for up to one TTL in the same narrow race. Fixing it would mean caching a "deleted" marker. It's marked in the code. • Unchanged:
osctrl-cli --db
edits can't update the cache and still take up to 5 minutes to show up, as the CLI help already says. Validation •
go build ./...
•
go vet
on the changed packages •
go test ./pkg/environments ./pkg/cache ./cmd/api/... ./cmd/tls/...
passes • New `TestEnvCache_RefreshEnv`: saving puts the new row in the cache, and deleting removes the entry. • The
SETNX
refill path isn't covered by tests because the repo has no Redis test fixture. jmpsec/osctrl