[KV-Offloading] Support workload identity for objectstore secondary tier (#47063)
Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com> Co-authored-by: Or Ozeri <oro@il.ibm.com>
Pierangelo Di Pilato committed
Jul 7, 2026 at 15:30 UTC
65a7b4628409a77cc9d89246397e793ce41367fe
3 files changed
+76
-11
tests/v1/kv_offload/tiering/test_obj_tier.py
+47
@@ -25,6 +25,7 @@ from vllm.v1.kv_offload.base import (
25
make_offload_key,
26
)
27
from vllm.v1.kv_offload.tiering.base import JobMetadata, JobResult
28
+from vllm.v1.kv_offload.tiering.obj.config import ObjStoreConfig
29
from vllm.v1.kv_offload.tiering.obj.manager import ObjectStoreSecondaryTierManager
30
31
# ---------------------------------------------------------------------------
@@ -418,3 +419,49 @@ class TestMockObjTierShutdown:
419
tier, _ = _make_tier(num_blocks=4)
420
tier.shutdown()
421
tier.shutdown() # must not raise
422
+
423
+
424
+class TestObjStoreConfig:
425
+ def test_explicit_credentials_included(self):
426
+ cfg = ObjStoreConfig(
427
+ bucket="b",
428
+ endpoint_override="ep",
429
+ access_key="ak",
430
+ secret_key="sk",
431
+ )
432
+ params = cfg.to_nixl_params()
433
+ assert params["access_key"] == "ak"
434
+ assert params["secret_key"] == "sk"
435
+
436
+ def test_credentials_omitted_when_empty(self):
437
+ cfg = ObjStoreConfig(bucket="b", endpoint_override="ep")
438
+ params = cfg.to_nixl_params()
439
+ assert "access_key" not in params
440
+ assert "secret_key" not in params
441
+ assert "session_token" not in params
442
+ assert "region" not in params
443
+ assert params["bucket"] == "b"
444
+ assert params["endpoint_override"] == "ep"
445
+
446
+ def test_session_token_and_region_included(self):
447
+ cfg = ObjStoreConfig(
448
+ bucket="b",
449
+ endpoint_override="ep",
450
+ access_key="ak",
451
+ secret_key="sk",
452
+ session_token="tok",
453
+ region="us-east-1",
454
+ )
455
+ params = cfg.to_nixl_params()
456
+ assert params["session_token"] == "tok"
457
+ assert params["region"] == "us-east-1"
458
+
459
+ def test_ca_bundle_included_when_set(self):
460
+ cfg = ObjStoreConfig(
461
+ bucket="b",
462
+ endpoint_override="ep",
463
+ ca_bundle="/path/to/ca.pem",
464
+ )
465
+ params = cfg.to_nixl_params()
466
+ assert params["ca_bundle"] == "/path/to/ca.pem"
467
+ assert "access_key" not in params
vllm/v1/kv_offload/tiering/obj/config.py
+25
-9
@@ -2,29 +2,45 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
"""Connection configuration for the object store secondary tier."""
4
5
-from dataclasses import dataclass
5
+from dataclasses import dataclass, field
6
7
8
@dataclass
9
class ObjStoreConfig:
10
- """Connection parameters for an object store backend."""
10
+ """Connection parameters for an object store backend.
11
+
12
+ When ``access_key`` and ``secret_key`` are left empty the NIXL OBJ
13
+ plugin falls back to the AWS SDK default credential provider chain
14
+ (IAM roles, environment variables, credential files, etc.), which
15
+ enables workload-identity based auth on Kubernetes.
16
+ """
17
18
bucket: str
19
endpoint_override: str
14
- access_key: str
15
- secret_key: str
20
+ access_key: str = field(default="", repr=False)
21
+ secret_key: str = field(default="", repr=False)
22
+ session_token: str = field(default="", repr=False)
23
+ region: str = ""
24
scheme: str = "http"
25
ca_bundle: str = ""
26
27
def to_nixl_params(self) -> dict[str, str]:
20
- """Build the NIXL backend params dict."""
28
+ """Build the NIXL backend params dict.
29
+
30
+ Credential and optional fields are only included when non-empty
31
+ so that the AWS SDK default credential chain can activate.
32
+ """
33
params: dict[str, str] = {
34
"bucket": self.bucket,
35
"endpoint_override": self.endpoint_override,
36
"scheme": self.scheme,
25
- "access_key": self.access_key,
26
- "secret_key": self.secret_key,
37
}
28
- if self.ca_bundle:
29
- params["ca_bundle"] = self.ca_bundle
38
+ # Omit empty optional fields so the NIXL OBJ plugin's underlying
39
+ # AWS SDK can fall back to its default credential provider chain
40
+ # (IAM roles, env vars, credential files, etc.).
41
+ # https://github.com/ai-dynamo/nixl/blob/main/src/plugins/obj/README.md
42
+ for key in ("access_key", "secret_key", "session_token", "region", "ca_bundle"):
43
+ value = getattr(self, key)
44
+ if value:
45
+ params[key] = value
46
return params
vllm/v1/kv_offload/tiering/obj/manager.py
+4
-2
@@ -157,8 +157,10 @@ class ObjectStoreSecondaryTierManager(SecondaryTierManager):
157
except Exception as e:
158
raise RuntimeError(
159
f"Object store tier connectivity probe failed — check bucket, "
160
- f"endpoint_override, access_key, secret_key, and scheme. "
161
- f"Error: {e}"
160
+ f"endpoint_override, and scheme. If using explicit credentials "
161
+ f"verify access_key and secret_key; otherwise ensure the AWS "
162
+ f"SDK default credential chain is configured (IAM role, env "
163
+ f"vars, credential file). Error: {e}"
164
) from e
165
166
def _exists(self, obj_key: str) -> bool: