GitHub
10/31/2026, 8:59 PMEXISTS 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/osctrlGitHub
10/31/2026, 9:10 PM