redis

package
v0.0.45 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

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

View Source
const (
	DefaultDialTimeout  = redisconn.DefaultDialTimeout
	DefaultReadTimeout  = redisconn.DefaultReadTimeout
	DefaultWriteTimeout = redisconn.DefaultWriteTimeout
)

Default timeouts applied by NewClient when the corresponding Config field is zero.

View Source
const (

	// DefaultAWSElastiCacheIAMTokenTTL is retained for source compatibility.
	// Deprecated: use redisconnaws.DefaultConnMaxLifetime.
	DefaultAWSElastiCacheIAMTokenTTL = redisconnaws.DefaultConnMaxLifetime
)
View Source
const DefaultAzureADTokenTTL = redisconnazure.DefaultConnMaxLifetime

DefaultAzureADTokenTTL is retained for source compatibility. Deprecated: use redisconnazure.DefaultConnMaxLifetime.

View Source
const DefaultGCPMemorystoreIAMTokenTTL = redisconngcp.DefaultConnMaxLifetime

DefaultGCPMemorystoreIAMTokenTTL is retained for source compatibility. Deprecated: use redisconngcp.DefaultConnMaxLifetime.

Variables

This section is empty.

Functions

func BuildTLSConfig deprecated

func BuildTLSConfig(cfg *TLSConfig) (*tls.Config, error)

BuildTLSConfig converts a legacy TLSConfig to crypto/tls configuration.

Deprecated: use redisconn.BuildTLSConfig.

func NewAuthToken added in v0.0.43

func NewAuthToken(ctx context.Context, cfg *Config) (username, password string, err error)

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.

func NewClient deprecated

func NewClient(ctx context.Context, cfg *Config) (goredis.UniversalClient, error)

NewClient constructs and verifies a Redis client.

Deprecated: use redisconn.NewClient.

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.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks Config for connection and provider configuration errors.

type CredentialsFunc added in v0.0.43

type CredentialsFunc func(ctx context.Context) (username, password string, err error)

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.

type TLSConfig

type TLSConfig = redisconn.TLSConfig

TLSConfig is kept for source compatibility. Deprecated: use redisconn.TLSConfig.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL