From f10c9f059eced6b9877d87df10f1dde2698ee209 Mon Sep 17 00:00:00 2001 From: dfgvaetyj3456356-hash <288537585+dfgvaetyj3456356-hash@users.noreply.github.com> Date: Sun, 31 May 2026 10:56:06 -0500 Subject: [PATCH] security: redact OpenAI restriction secrets in logs --- .../fastapi/middleware/api_restriction.py | 9 ++++++++ .../frontend/fastapi_frontend.py | 2 +- .../tests/test_openai_restricted_apis.py | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/python/openai/openai_frontend/frontend/fastapi/middleware/api_restriction.py b/python/openai/openai_frontend/frontend/fastapi/middleware/api_restriction.py index 085434ad46..fc31f9579f 100644 --- a/python/openai/openai_frontend/frontend/fastapi/middleware/api_restriction.py +++ b/python/openai/openai_frontend/frontend/fastapi/middleware/api_restriction.py @@ -102,6 +102,15 @@ def RestrictionDict(self) -> dict[str, tuple[str, str]]: """ return self._restrictions.copy() + def RedactedRestrictionDict(self) -> dict[str, tuple[str, str]]: + """ + Get a copy of the restrictions dictionary safe for logging. + + Returns: + dict: Copy of the restrictions mapping API names to (header_key, redacted_value) + """ + return {api: (key, "***") for api, (key, _) in self._restrictions.items()} + def Insert(self, api: str, restriction: tuple[str, str]): """ Add a restriction for a specific API. diff --git a/python/openai/openai_frontend/frontend/fastapi_frontend.py b/python/openai/openai_frontend/frontend/fastapi_frontend.py index 752befd8bc..8946c8b193 100644 --- a/python/openai/openai_frontend/frontend/fastapi_frontend.py +++ b/python/openai/openai_frontend/frontend/fastapi_frontend.py @@ -140,7 +140,7 @@ def _add_api_restriction_middleware(self, app: FastAPI): APIRestrictionMiddleware, restricted_apis=self.restricted_apis ) print( - f"[INFO] API restrictions enabled. Restricted API endpoints: {self.restricted_apis.RestrictionDict()}" + f"[INFO] API restrictions enabled. Restricted API endpoints: {self.restricted_apis.RedactedRestrictionDict()}" ) def _add_request_size_limit_middleware(self, app: FastAPI): diff --git a/python/openai/tests/test_openai_restricted_apis.py b/python/openai/tests/test_openai_restricted_apis.py index 200412df34..a45651c942 100755 --- a/python/openai/tests/test_openai_restricted_apis.py +++ b/python/openai/tests/test_openai_restricted_apis.py @@ -33,6 +33,8 @@ import requests from tests.utils import OpenAIServer +from frontend.fastapi.middleware.api_restriction import RestrictedFeatures + def assert_response_success( response: requests.Response, expected_status: int = 200, description: str = "" @@ -257,6 +259,26 @@ def test_duplicate_apis(self, malformed_arg): expected_error_pattern="restricted api 'inference' can not be specified in multiple config groups", ) + def test_restriction_log_view_redacts_secret_values(self): + """Restriction secrets are used for auth and must not be printed to logs.""" + restrictions = RestrictedFeatures( + [ + ["inference", "api-key", "my-secret-key"], + ["model-repository", "admin-key", "admin-secret"], + ] + ) + + assert restrictions.RestrictionDict() == { + "inference": ("api-key", "my-secret-key"), + "model-repository": ("admin-key", "admin-secret"), + } + assert restrictions.RedactedRestrictionDict() == { + "inference": ("api-key", "***"), + "model-repository": ("admin-key", "***"), + } + assert "my-secret-key" not in repr(restrictions.RedactedRestrictionDict()) + assert "admin-secret" not in repr(restrictions.RedactedRestrictionDict()) + @pytest.mark.parametrize( "malformed_arg", [