Documentation
¶
Overview ¶
Package redis provides a deprecated compatibility facade for the extracted redisconn modules. New code should import github.com/stacklok/toolhive-core/redisconn and the selected cloud provider child module directly.
Deprecated: use redisconn.
The package wraps github.com/redis/go-redis/v9 with a single Config type and NewClient factory that supports three connection modes:
- Standalone — a single endpoint (Addr).
- Cluster — Redis Cluster protocol against a single seed Addr.
- Sentinel — high-availability failover via SentinelConfig.
The returned client is a goredis.UniversalClient so callers can write mode-agnostic code.
Connection Modes ¶
Standalone:
cli, err := redis.NewClient(ctx, &redis.Config{
Addr: "redis.example.com:6379",
Password: "...",
DB: 0,
})
Cluster:
cli, err := redis.NewClient(ctx, &redis.Config{
Addr: "cluster.example.com:6379",
ClusterMode: true,
Username: "app",
Password: "...",
})
Sentinel:
cli, err := redis.NewClient(ctx, &redis.Config{
SentinelConfig: &redis.SentinelConfig{
MasterName: "mymaster",
SentinelAddrs: []string{"sentinel-0:26379", "sentinel-1:26379"},
},
Password: "...",
})
TLS ¶
TLS is opt-in per connection target. When TLS is set, master/cluster connections use it. SentinelTLS, when set, applies to sentinel daemon connections independently — useful when the master and sentinels present different certificate chains. Both fields accept either system CAs (CACert nil) or a custom CA bundle. To use mTLS, set ClientCert and ClientKey to a PEM-encoded client certificate/key pair; the master and sentinel connections can use different pairs.
Defaults and Validation ¶
NewClient applies DefaultDialTimeout, DefaultReadTimeout, and DefaultWriteTimeout when the corresponding Config fields are zero, then validates connection-mode topology (Addr XOR SentinelConfig, ClusterMode requires Addr, Sentinel requires MasterName plus at least one address). It verifies the connection with a Ping before returning. Caller-specific validation (key-prefix requirements, ACL enforcement) remains the caller's responsibility.
Dynamic Authentication ¶
Config.DynamicAuth mints short-lived AUTH credentials from a cloud IAM backend instead of using a static Password:
- AWSElastiCacheIAM — ElastiCache/MemoryDB IAM authentication tokens, hand-signed with SigV4 (there is no RDS-style auth.BuildAuthToken helper for these services). Supports ElastiCache/MemoryCache Serverless via ResourceType.
- AzureAD — Entra ID (formerly Azure AD) access tokens for Azure Cache for Redis.
- GCPMemorystoreIAM — GCP OAuth2 access tokens for Memorystore for Redis Cluster IAM authentication. This backend authenticates token-only (AUTH <token>, no username) — Config.Username must be left empty.
Dynamic authentication requires a verified TLS connection (Config.TLS set, with InsecureSkipVerify false): these are bearer credentials, and sending them over an unverified or plaintext connection lets a network attacker capture and replay them. Set DynamicAuthConfig.AllowInsecureTransport to opt out for trusted local tunneling.
Unlike pgx's BeforeConnect hook, go-redis has no per-dial hook that runs before its own HELLO/AUTH handshake, and pooled connections are long-lived rather than reconnecting per operation. NewClient works around the first problem by wiring Options.CredentialsProviderContext, which go-redis resolves during that handshake — before RESP3 negotiation and DB selection — rather than OnConnect, which only fires afterward (breaking non-zero DB selection and silently downgrading otherwise RESP3-capable connections to RESP2). It works around the second by setting ConnMaxLifetime (defaulted per backend, inside the token's TTL, when Config.ConnMaxLifetime is zero) so go-redis retires an over-age connection lazily when that connection is reused, then redials it — re-running CredentialsProviderContext and picking up current credentials. This is not proactive refresh or active reauthentication.
For Sentinel, CredentialsProviderContext is wired only onto the data-node (master/replica) connections: go-redis's FailoverOptions deliberately does not propagate it to the internal Sentinel-daemon connections it builds (those authenticate with SentinelUsername/SentinelPassword instead), so the cloud data-node identity never reaches the Sentinel daemons.
cli, err := redis.NewClient(ctx, &redis.Config{
Addr: "my-cluster.abcdef.ng.0001.use1.cache.amazonaws.com:6379",
Username: "app-iam-user",
TLS: &redis.TLSConfig{},
DynamicAuth: &redis.DynamicAuthConfig{
AWSElastiCacheIAM: &redis.DynamicAuthAWSElastiCacheIAM{
Region: "us-east-1",
ClusterName: "my-cluster",
},
},
})
Whether Config.Username is required depends on the backend: AWS ElastiCache/ MemoryDB IAM and Azure Entra ID require it (the IAM user / principal object ID that minted tokens authenticate as); GCP Memorystore IAM authentication rejects a username. Config.Password must always be empty when DynamicAuth is set.
Index ¶
- Constants
- func BuildTLSConfig(cfg *TLSConfig) (*tls.Config, error)deprecated
- func NewAuthToken(ctx context.Context, cfg *Config) (username, password string, err error)
- func NewClient(ctx context.Context, cfg *Config) (goredis.UniversalClient, error)deprecated
- type Config
- type CredentialsFunc
- type DynamicAuthAWSElastiCacheIAM
- type DynamicAuthAzureAD
- type DynamicAuthConfig
- type DynamicAuthGCPMemorystoreIAM
- type SentinelConfig
- type TLSConfig
Constants ¶
const ( DefaultDialTimeout = redisconn.DefaultDialTimeout DefaultReadTimeout = redisconn.DefaultReadTimeout DefaultWriteTimeout = redisconn.DefaultWriteTimeout )
Default timeouts applied by NewClient when the corresponding Config field is zero.
const ( // DefaultAWSElastiCacheIAMTokenTTL is retained for source compatibility. // Deprecated: use redisconnaws.DefaultConnMaxLifetime. DefaultAWSElastiCacheIAMTokenTTL = redisconnaws.DefaultConnMaxLifetime )
const DefaultAzureADTokenTTL = redisconnazure.DefaultConnMaxLifetime
DefaultAzureADTokenTTL is retained for source compatibility. Deprecated: use redisconnazure.DefaultConnMaxLifetime.
const DefaultGCPMemorystoreIAMTokenTTL = redisconngcp.DefaultConnMaxLifetime
DefaultGCPMemorystoreIAMTokenTTL is retained for source compatibility. Deprecated: use redisconngcp.DefaultConnMaxLifetime.
Variables ¶
This section is empty.
Functions ¶
func BuildTLSConfig
deprecated
func NewAuthToken ¶ added in v0.0.43
NewAuthToken returns the username and short-lived password minted by the dynamic-auth backend configured in cfg.DynamicAuth. When DynamicAuth is nil, both return values are empty and no error is raised — this lets callers fall back to a static Username/Password.
This entry point is for callers that mint credentials outside NewClient (for example, a standalone health-check tool). NewClient does not call it; NewClient resolves a CredentialsFunc once and re-invokes it on every connection attempt so the credentials used stay current across reconnects.
Types ¶
type Config ¶
type Config struct {
// Addr is the Redis server address (host:port) for standalone or cluster
// modes. Mutually exclusive with SentinelConfig.
Addr string
// ClusterMode enables the Redis Cluster protocol. Requires Addr. Cluster
// mode ignores DB because Redis Cluster only supports database 0.
ClusterMode bool
// SentinelConfig activates Sentinel failover mode. Mutually exclusive
// with Addr.
SentinelConfig *SentinelConfig
// Username is the optional ACL username (Redis 6.0+). When empty, auth
// falls back to legacy AUTH using only Password.
//
// When DynamicAuth is set, whether Username is required depends on the
// backend: AWS ElastiCache/MemoryDB IAM and Azure Entra ID require it (the
// IAM user / principal object ID that minted tokens authenticate as); GCP
// Memorystore IAM authentication is token-only and rejects a username, so
// Username must be left empty for that backend.
Username string
// Password is the AUTH/ACL password. May be empty when the server does
// not require authentication. Mutually exclusive with DynamicAuth.
Password string //nolint:gosec // G101: field name, not a hardcoded credential
// DynamicAuth, when non-nil, mints short-lived AUTH credentials from a
// cloud IAM backend instead of using a static Password. NewClient
// installs an Options.CredentialsProviderContext hook that resolves
// fresh credentials for each connection attempt — during go-redis's
// handshake, before RESP3 negotiation and DB selection — and sets
// ConnMaxLifetime (when Config's own ConnMaxLifetime is zero) to a value
// inside the backend's token TTL. go-redis retires an over-age pooled
// connection lazily when it is reused; this does not proactively refresh
// or reauthenticate an open connection.
//
// Dynamic authentication requires a verified TLS connection (Config.TLS
// set, with InsecureSkipVerify false): cloud IAM tokens are bearer
// credentials, and sending them over an unverified or plaintext
// connection lets a network attacker capture and replay them. Set
// DynamicAuthConfig.AllowInsecureTransport to opt out for trusted local
// tunneling (for example, a sidecar-terminated mTLS tunnel where this
// package's own TLS handshake would be redundant).
DynamicAuth *DynamicAuthConfig
// DB is the Redis database index. Applies to standalone and sentinel
// modes; ignored in cluster mode.
DB int
// DialTimeout is the timeout for establishing a connection. When zero,
// DefaultDialTimeout is used.
DialTimeout time.Duration
// ReadTimeout is the timeout for socket reads. When zero,
// DefaultReadTimeout is used.
ReadTimeout time.Duration
// WriteTimeout is the timeout for socket writes. When zero,
// DefaultWriteTimeout is used.
WriteTimeout time.Duration
// TLS configures TLS for master/cluster connections. When nil, those
// connections are plaintext.
TLS *TLSConfig
// SentinelTLS configures TLS for sentinel daemon connections. Only
// applies when SentinelConfig is set. When nil, sentinel connections are
// plaintext (independent of TLS).
SentinelTLS *TLSConfig
// ConnMaxLifetime is the maximum amount of time a connection may be
// reused before go-redis retires and redials it. When zero and
// DynamicAuth is set, a backend-specific default inside the token's TTL
// is used instead of go-redis's own default. Ignored (left at go-redis's
// default) when DynamicAuth is nil and this is zero.
ConnMaxLifetime time.Duration
}
Config configures a Redis client. Exactly one of Addr or SentinelConfig must be set. ClusterMode upgrades an Addr-based config to the Redis Cluster protocol.
type CredentialsFunc ¶ added in v0.0.43
CredentialsFunc resolves the username/password to authenticate a dynamic-auth-enabled connection with. It is wired into go-redis's Options.CredentialsProviderContext, which go-redis calls during the HELLO/AUTH handshake inside initConn — before RESP3 negotiation and DB selection happen. An OnConnect hook is unsuitable for this: go-redis only invokes OnConnect after HELLO/AUTH and any SELECT have already completed, which would silently downgrade otherwise RESP3-capable servers to RESP2 and break selection of a non-zero database when Password is left empty for the hook to fill in later.
type DynamicAuthAWSElastiCacheIAM ¶ added in v0.0.43
type DynamicAuthAWSElastiCacheIAM struct {
// Region is the AWS region used to sign IAM tokens. Use "detect" to
// auto-discover the region from the EC2 instance metadata service (IMDS).
Region string
// ClusterName is the ElastiCache replication group ID / cache name, or
// the MemoryDB cluster name, that the presigned token is scoped to.
ClusterName string
// ServiceName is the SigV4 signing service name. Must be empty (the
// default, treated as "elasticache") or "memorydb".
ServiceName string
// ResourceType selects the AWS-required resource-type query parameter
// for serverless caches. Must be empty (the default, for provisioned
// ElastiCache/MemoryDB clusters) or "ServerlessCache" (for ElastiCache
// Serverless / MemoryDB Serverless).
ResourceType string
}
DynamicAuthAWSElastiCacheIAM configures AWS ElastiCache/MemoryDB IAM dynamic authentication.
type DynamicAuthAzureAD ¶ added in v0.0.43
type DynamicAuthAzureAD struct{}
DynamicAuthAzureAD configures Azure Entra ID (formerly Azure AD) authentication for Azure Cache for Redis. It has no fields: the token is minted from DefaultAzureCredential's normal resolution order (environment variables — including AZURE_CLIENT_ID to select a user-assigned managed identity — workload identity, system-assigned managed identity, Azure CLI, ...).
type DynamicAuthConfig ¶ added in v0.0.43
type DynamicAuthConfig struct {
// AWSElastiCacheIAM enables AWS ElastiCache/MemoryDB IAM authentication
// tokens.
AWSElastiCacheIAM *DynamicAuthAWSElastiCacheIAM
// AzureAD enables Azure Entra ID (formerly Azure AD) authentication
// tokens for Azure Cache for Redis.
AzureAD *DynamicAuthAzureAD
// GCPMemorystoreIAM enables GCP Memorystore for Redis Cluster IAM
// authentication tokens.
GCPMemorystoreIAM *DynamicAuthGCPMemorystoreIAM
// AllowInsecureTransport opts out of the requirement that Config.TLS be
// set (with verification enabled) when DynamicAuth is configured. Leave
// false unless a trusted local tunnel already provides transport
// security outside this package's own TLS handling.
AllowInsecureTransport bool
}
DynamicAuthConfig selects a dynamic-authentication backend. Exactly one backend field must be non-nil when DynamicAuthConfig itself is non-nil.
type DynamicAuthGCPMemorystoreIAM ¶ added in v0.0.43
type DynamicAuthGCPMemorystoreIAM struct{}
DynamicAuthGCPMemorystoreIAM configures GCP Memorystore for Redis Cluster IAM authentication. It has no fields: the token is minted from ambient Application Default Credentials, scoped for Memorystore IAM auth. Authentication is token-only (AUTH <token>) — Config.Username must be empty for this backend; Memorystore does not accept a username alongside the token.
type SentinelConfig ¶
type SentinelConfig = redisconn.SentinelConfig
SentinelConfig is kept for source compatibility. Deprecated: use redisconn.SentinelConfig.