From 46bc9a02c6625b4f48c55749f5ea3aefcd423726 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 7 Mar 2026 23:43:32 +0530 Subject: [PATCH] fix(security): Keep short agent token prefixes in logs Restore the existing short token-prefix logging behavior for agent auth failures while keeping the optional bearer-path rate-limit fix. Update tests and docs so the replacement branch reflects the intended logging policy. Co-Authored-By: Claude --- backend/app/core/agent_auth.py | 6 ++++-- backend/tests/test_agent_auth_security.py | 18 ++++++++++++++---- docs/reference/authentication.md | 2 +- docs/reference/security.md | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/backend/app/core/agent_auth.py b/backend/app/core/agent_auth.py index ef88ac6b..013d82aa 100644 --- a/backend/app/core/agent_auth.py +++ b/backend/app/core/agent_auth.py @@ -133,8 +133,9 @@ async def get_agent_auth_context( agent = await _find_agent_for_token(session, resolved) if agent is None: logger.warning( - "agent auth invalid token path=%s", + "agent auth invalid token path=%s token_prefix=%s", request.url.path, + resolved[:6], ) raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) await _touch_agent_presence(request, session, agent) @@ -178,8 +179,9 @@ async def get_agent_auth_context_optional( agent = await _find_agent_for_token(session, resolved) if agent is None: logger.warning( - "agent auth optional invalid token path=%s", + "agent auth optional invalid token path=%s token_prefix=%s", request.url.path, + resolved[:6], ) return None await _touch_agent_presence(request, session, agent) diff --git a/backend/tests/test_agent_auth_security.py b/backend/tests/test_agent_auth_security.py index e5499baa..dd66d1ec 100644 --- a/backend/tests/test_agent_auth_security.py +++ b/backend/tests/test_agent_auth_security.py @@ -87,7 +87,7 @@ async def test_require_user_or_agent_skips_agent_auth_when_user_auth_succeeds( @pytest.mark.asyncio -async def test_required_agent_auth_invalid_token_logs_no_token_material( +async def test_required_agent_auth_invalid_token_logs_short_prefix_only( monkeypatch: pytest.MonkeyPatch, ) -> None: limiter = _RecordingLimiter() @@ -118,11 +118,16 @@ async def test_required_agent_auth_invalid_token_logs_no_token_material( ) assert exc_info.value.status_code == 401 - assert logged == [("agent auth invalid token path=%s", ("/api/v1/agent/boards",))] + assert logged == [ + ( + "agent auth invalid token path=%s token_prefix=%s", + ("/api/v1/agent/boards", "invali"), + ) + ] @pytest.mark.asyncio -async def test_optional_agent_auth_invalid_token_logs_no_token_material( +async def test_optional_agent_auth_invalid_token_logs_short_prefix_only( monkeypatch: pytest.MonkeyPatch, ) -> None: limiter = _RecordingLimiter() @@ -152,4 +157,9 @@ async def test_optional_agent_auth_invalid_token_logs_no_token_material( ) assert ctx is None - assert logged == [("agent auth optional invalid token path=%s", ("/api/v1/tasks/task-2",))] + assert logged == [ + ( + "agent auth optional invalid token path=%s token_prefix=%s", + ("/api/v1/tasks/task-2", "invali"), + ) + ] diff --git a/docs/reference/authentication.md b/docs/reference/authentication.md index f1ca37b9..0e8eb942 100644 --- a/docs/reference/authentication.md +++ b/docs/reference/authentication.md @@ -36,4 +36,4 @@ Autonomous agents primarily authenticate via an `X-Agent-Token` header. On share Security notes: - Agent auth is rate-limited to **20 requests per 60 seconds per IP**. Exceeding this returns `429 Too Many Requests`. -- Authentication failure logs never include token material. +- Authentication failure logs may include a short token prefix for debugging, but never the full token. diff --git a/docs/reference/security.md b/docs/reference/security.md index 831f596b..52a1f2a1 100644 --- a/docs/reference/security.md +++ b/docs/reference/security.md @@ -72,7 +72,7 @@ This boundary helps LLM-based agents distinguish trusted instructions from untru ## Agent token logging -On authentication failure, logs include request context only. Token values and token prefixes are not written to logs. +On authentication failure, logs include request context and may include a short token prefix for debugging. Full tokens are not written to logs. ## Cross-tenant isolation