mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(redis): require TLS for ElastiCache IAM auth
This commit is contained in:
parent
0e4e6cc002
commit
3abaa91d28
2 changed files with 87 additions and 0 deletions
|
|
@ -181,6 +181,13 @@ def _is_true(value: object | None) -> bool:
|
|||
return value is True or (isinstance(value, str) and value.lower() == "true")
|
||||
|
||||
|
||||
def _uses_tls(redis_kwargs: Mapping[str, object]) -> bool:
|
||||
if redis_kwargs.get("startup_nodes") is not None:
|
||||
return _is_true(redis_kwargs.get("ssl"))
|
||||
url: Final = redis_kwargs.get("url")
|
||||
return urlsplit(url).scheme.lower() == "rediss" if isinstance(url, str) else _is_true(redis_kwargs.get("ssl"))
|
||||
|
||||
|
||||
def _build_elasticache_iam_provider(
|
||||
user_name: object | None,
|
||||
cache_name: object | None,
|
||||
|
|
@ -506,6 +513,8 @@ def _get_redis_client_logic(**env_overrides):
|
|||
"for Redis. Using Azure AD. Remove one to avoid misconfiguration."
|
||||
)
|
||||
elif _aws_iam_enabled:
|
||||
if not _uses_tls(redis_kwargs):
|
||||
raise ValueError("AWS ElastiCache IAM Redis authentication requires TLS")
|
||||
verbose_logger.debug("Setting up AWS ElastiCache IAM authentication for Redis.")
|
||||
redis_kwargs["credential_provider"] = _build_elasticache_iam_provider(
|
||||
user_name=redis_kwargs.get("aws_iam_user_name"),
|
||||
|
|
|
|||
|
|
@ -318,6 +318,7 @@ def test_aws_iam_environment_settings_install_provider(clean_redis_environment,
|
|||
monkeypatch.setenv("REDIS_AWS_IAM_USER_NAME", "iam-user")
|
||||
monkeypatch.setenv("REDIS_AWS_IAM_CACHE_NAME", "cache.example.com")
|
||||
monkeypatch.setenv("REDIS_AWS_IAM_REGION", "us-east-1")
|
||||
monkeypatch.setenv("REDIS_SSL", "true")
|
||||
|
||||
redis_kwargs = _get_redis_client_logic(host="cache.example.com", port=6379)
|
||||
|
||||
|
|
@ -325,6 +326,77 @@ def test_aws_iam_environment_settings_install_provider(clean_redis_environment,
|
|||
assert not {"aws_iam_auth", "aws_iam_user_name", "aws_iam_cache_name", "aws_iam_region"} & redis_kwargs.keys()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"transport",
|
||||
[
|
||||
pytest.param({"host": "cache.example.com", "port": 6379}, id="host_without_ssl"),
|
||||
pytest.param({"host": "cache.example.com", "port": 6379, "ssl": False}, id="host_ssl_false"),
|
||||
pytest.param({"url": "redis://cache.example.com:6379", "ssl": True}, id="plaintext_url"),
|
||||
pytest.param(
|
||||
{"startup_nodes": [{"host": "cache.example.com", "port": 6379}]},
|
||||
id="cluster_without_ssl",
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
"url": "rediss://cache.example.com:6379",
|
||||
"startup_nodes": [{"host": "cache.example.com", "port": 6379}],
|
||||
},
|
||||
id="cluster_without_ssl_ignores_url_scheme",
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
"sentinel_nodes": [("sentinel.example.com", 26379)],
|
||||
"service_name": "cache",
|
||||
},
|
||||
id="sentinel_without_ssl",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_aws_iam_auth_rejects_non_tls_connections(clean_redis_environment, transport):
|
||||
with pytest.raises(ValueError, match="requires TLS"):
|
||||
_get_redis_client_logic(
|
||||
**transport,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user",
|
||||
aws_iam_cache_name="cache.example.com",
|
||||
aws_iam_region="us-east-1",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"transport",
|
||||
[
|
||||
pytest.param({"host": "cache.example.com", "port": 6379, "ssl": True}, id="host"),
|
||||
pytest.param({"url": "rediss://cache.example.com:6379"}, id="url"),
|
||||
pytest.param(
|
||||
{
|
||||
"startup_nodes": [{"host": "cache.example.com", "port": 6379}],
|
||||
"ssl": True,
|
||||
},
|
||||
id="cluster",
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
"sentinel_nodes": [("sentinel.example.com", 26379)],
|
||||
"service_name": "cache",
|
||||
"ssl": True,
|
||||
},
|
||||
id="sentinel",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_aws_iam_auth_accepts_tls_connections(clean_redis_environment, transport):
|
||||
redis_kwargs = _get_redis_client_logic(
|
||||
**transport,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user",
|
||||
aws_iam_cache_name="cache.example.com",
|
||||
aws_iam_region="us-east-1",
|
||||
)
|
||||
|
||||
assert isinstance(redis_kwargs["credential_provider"], ElastiCacheIAMCredentialProvider)
|
||||
|
||||
|
||||
def test_aws_iam_settings_are_removed_for_url_and_static_credentials(clean_redis_environment):
|
||||
redis_kwargs = _get_redis_client_logic(
|
||||
url="rediss://url-user:url-pass@cache.example.com:6380",
|
||||
|
|
@ -350,6 +422,7 @@ def test_aws_iam_missing_setting_fails_closed(clean_redis_environment, missing):
|
|||
"aws_iam_user_name": "iam-user",
|
||||
"aws_iam_cache_name": "cache.example.com",
|
||||
"aws_iam_region": "us-east-1",
|
||||
"ssl": True,
|
||||
}
|
||||
settings[missing] = None
|
||||
|
||||
|
|
@ -364,6 +437,7 @@ def test_aws_iam_region_falls_back_to_environment(clean_redis_environment, monke
|
|||
redis_kwargs = _get_redis_client_logic(
|
||||
host="cache.example.com",
|
||||
port=6379,
|
||||
ssl=True,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user",
|
||||
aws_iam_cache_name="cache.example.com",
|
||||
|
|
@ -381,6 +455,7 @@ def test_aws_iam_region_prefers_aws_region_over_default_region(clean_redis_envir
|
|||
redis_kwargs = _get_redis_client_logic(
|
||||
host="cache.example.com",
|
||||
port=6379,
|
||||
ssl=True,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user",
|
||||
aws_iam_cache_name="cache.example.com",
|
||||
|
|
@ -395,6 +470,7 @@ def test_aws_iam_region_prefers_explicit_over_environment(clean_redis_environmen
|
|||
redis_kwargs = _get_redis_client_logic(
|
||||
host="cache.example.com",
|
||||
port=6379,
|
||||
ssl=True,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user",
|
||||
aws_iam_cache_name="cache.example.com",
|
||||
|
|
@ -408,6 +484,7 @@ def test_aws_iam_settings_map_to_distinct_provider_fields(clean_redis_environmen
|
|||
redis_kwargs = _get_redis_client_logic(
|
||||
host="cache.example.com",
|
||||
port=6379,
|
||||
ssl=True,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user-value",
|
||||
aws_iam_cache_name="iam-cache-value",
|
||||
|
|
@ -488,6 +565,7 @@ def test_async_cluster_installs_aws_iam_provider(clean_redis_environment):
|
|||
|
||||
client = get_redis_async_client(
|
||||
startup_nodes=startup_nodes,
|
||||
ssl=True,
|
||||
aws_iam_auth=True,
|
||||
aws_iam_user_name="iam-user",
|
||||
aws_iam_cache_name="cache.example.com",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue