Skip to content

Commit b75fb44

Browse files
authored
[core] Use secrets.token_hex(32) to generate auth tokens (#58818)
Replace placeholder. --------- Signed-off-by: Edward Oakes <ed.nmi.oakes@gmail.com>
1 parent e42d621 commit b75fb44

File tree

5 files changed

+33
-33
lines changed

5 files changed

+33
-33
lines changed
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import uuid
1+
import secrets
22

33

4-
# TODO: this is a placeholder for the actual authentication token generator. Will be replaced with a proper implementation.
54
def generate_new_authentication_token() -> str:
6-
return uuid.uuid4().hex
5+
"""Generate an authentication token for the cluster.
6+
7+
256 bits of entropy is considered sufficient to be durable to brute force attacks.
8+
"""
9+
return secrets.token_hex(32)

python/ray/tests/authentication/conftest.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import uuid
2-
31
import grpc
42
import pytest
53
from grpc import aio as aiogrpc
64

5+
from ray._private.authentication.authentication_token_generator import (
6+
generate_new_authentication_token,
7+
)
78
from ray._private.authentication_test_utils import (
89
authentication_env_guard,
910
reset_auth_token_state,
@@ -109,14 +110,9 @@ async def _create(with_auth=True):
109110

110111

111112
@pytest.fixture
112-
def test_token():
113-
"""Generate a test authentication token."""
114-
return uuid.uuid4().hex
115-
116-
117-
@pytest.fixture
118-
def setup_auth_environment(test_token):
113+
def setup_auth_environment():
119114
"""Set up authentication environment with test token."""
115+
test_token = generate_new_authentication_token()
120116
with authentication_env_guard():
121117
set_auth_mode("token")
122118
set_env_auth_token(test_token)

python/ray/tests/authentication/test_async_grpc_interceptors.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import uuid
2-
31
import grpc
42
import pytest
53
from grpc import aio as aiogrpc
64

5+
from ray._private.authentication.authentication_token_generator import (
6+
generate_new_authentication_token,
7+
)
78
from ray._private.authentication_test_utils import (
89
authentication_env_guard,
910
reset_auth_token_state,
@@ -17,7 +18,7 @@
1718
@pytest.mark.asyncio
1819
async def test_async_server_and_client_with_valid_token(create_async_test_server):
1920
"""Test async server + client with matching token succeeds."""
20-
token = uuid.uuid4().hex
21+
token = generate_new_authentication_token()
2122

2223
with authentication_env_guard():
2324
set_auth_mode("token")
@@ -45,8 +46,8 @@ async def test_async_server_and_client_with_valid_token(create_async_test_server
4546
@pytest.mark.asyncio
4647
async def test_async_server_and_client_with_invalid_token(create_async_test_server):
4748
"""Test async server + client with mismatched token fails."""
48-
server_token = uuid.uuid4().hex
49-
wrong_token = uuid.uuid4().hex
49+
server_token = generate_new_authentication_token()
50+
wrong_token = generate_new_authentication_token()
5051

5152
with authentication_env_guard():
5253
# Set up server with server_token
@@ -77,7 +78,7 @@ async def test_async_server_and_client_with_invalid_token(create_async_test_serv
7778
@pytest.mark.asyncio
7879
async def test_async_server_with_auth_client_without_token(create_async_test_server):
7980
"""Test async server with auth, client without token fails."""
80-
token = uuid.uuid4().hex
81+
token = generate_new_authentication_token()
8182

8283
with authentication_env_guard():
8384
# Set up server with auth enabled

python/ray/tests/authentication/test_sync_grpc_interceptors.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import uuid
2-
31
import grpc
42
import pytest
53

4+
from ray._private.authentication.authentication_token_generator import (
5+
generate_new_authentication_token,
6+
)
67
from ray._private.authentication_test_utils import (
78
authentication_env_guard,
89
reset_auth_token_state,
@@ -15,7 +16,7 @@
1516

1617
def test_sync_server_and_client_with_valid_token(create_sync_test_server):
1718
"""Test sync server + client with matching token succeeds."""
18-
token = uuid.uuid4().hex
19+
token = generate_new_authentication_token()
1920

2021
with authentication_env_guard():
2122
set_auth_mode("token")
@@ -42,8 +43,8 @@ def test_sync_server_and_client_with_valid_token(create_sync_test_server):
4243

4344
def test_sync_server_and_client_with_invalid_token(create_sync_test_server):
4445
"""Test sync server + client with mismatched token fails."""
45-
server_token = uuid.uuid4().hex
46-
wrong_token = uuid.uuid4().hex
46+
server_token = generate_new_authentication_token()
47+
wrong_token = generate_new_authentication_token()
4748

4849
with authentication_env_guard():
4950
# Set up server with server_token
@@ -73,7 +74,7 @@ def test_sync_server_and_client_with_invalid_token(create_sync_test_server):
7374

7475
def test_sync_server_with_auth_client_without_token(create_sync_test_server):
7576
"""Test server with auth, client without token fails."""
76-
token = uuid.uuid4().hex
77+
token = generate_new_authentication_token()
7778

7879
with authentication_env_guard():
7980
# Set up server with auth enabled

python/ray/tests/test_token_auth_integration.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def test_local_cluster_generates_token():
146146
f"Files in {default_token_path.parent}: {list(default_token_path.parent.iterdir()) if default_token_path.parent.exists() else 'directory does not exist'}"
147147
)
148148
token = default_token_path.read_text().strip()
149-
assert len(token) == 32
149+
assert len(token) == 64
150150
assert all(c in "0123456789abcdef" for c in token)
151151

152152
# Verify cluster is working
@@ -190,7 +190,7 @@ def test_cluster_token_authentication(tokens_match, setup_cluster_with_token_aut
190190
if tokens_match:
191191
client_token = cluster_token # Same token - should succeed
192192
else:
193-
client_token = "b" * 32 # Different token - should fail
193+
client_token = "b" * 64 # Different token - should fail
194194

195195
set_env_auth_token(client_token)
196196
reset_auth_token_state()
@@ -263,7 +263,7 @@ def test_ray_start_without_token_raises_error(is_head, request):
263263
def test_ray_start_head_with_token_succeeds():
264264
"""Test that ray start --head succeeds when token auth is enabled with a valid token."""
265265
# Set up environment with token auth and a valid token
266-
test_token = "a" * 32
266+
test_token = "a" * 64
267267
env = os.environ.copy()
268268
env["RAY_AUTH_TOKEN"] = test_token
269269
env["RAY_AUTH_MODE"] = "token"
@@ -326,7 +326,7 @@ def test_ray_start_address_with_token(token_match, setup_cluster_with_token_auth
326326
env["RAY_AUTH_TOKEN"] = cluster_token
327327
expect_success = True
328328
else:
329-
env["RAY_AUTH_TOKEN"] = "b" * 32
329+
env["RAY_AUTH_TOKEN"] = "b" * 64
330330
expect_success = False
331331

332332
# Start worker node
@@ -422,7 +422,7 @@ def job_finished():
422422
@pytest.mark.parametrize("use_generate", [True, False])
423423
def test_get_auth_token_cli(use_generate):
424424
"""Test ray get-auth-token CLI command."""
425-
test_token = "a" * 32
425+
test_token = "a" * 64
426426

427427
with authentication_env_guard():
428428
set_auth_mode("token")
@@ -452,7 +452,7 @@ def test_get_auth_token_cli(use_generate):
452452

453453
# Verify token is printed to stdout
454454
token = result.stdout.strip()
455-
assert len(token) == 32, f"Token should be 32 chars, got {len(token)}"
455+
assert len(token) == 64, token
456456
assert all(c in "0123456789abcdef" for c in token), "Token should be hex"
457457

458458
if not use_generate:
@@ -497,7 +497,7 @@ def test_get_auth_token_cli_no_token_no_generate():
497497
)
498498
def test_get_auth_token_cli_piping():
499499
"""Test that ray get-auth-token output can be piped."""
500-
test_token = "b" * 32
500+
test_token = "b" * 64
501501

502502
with authentication_env_guard():
503503
set_auth_mode("token")
@@ -516,9 +516,8 @@ def test_get_auth_token_cli_piping():
516516
)
517517

518518
assert result.returncode == 0
519-
# Should be 32 chars (no newline with nl=False)
520519
char_count = int(result.stdout.strip())
521-
assert char_count == 32, f"Expected 32 chars (no newline), got {char_count}"
520+
assert char_count == 64, f"Expected 64 chars (no newline), got {char_count}"
522521

523522

524523
if __name__ == "__main__":

0 commit comments

Comments
 (0)