From e902991addb520f20d2f1e9679135a3e47b21d88 Mon Sep 17 00:00:00 2001 From: Anshaj Kumar Date: Thu, 21 May 2026 22:01:59 +0530 Subject: [PATCH 1/3] fix(detectors): support 84-character Azure OpenAI API keys Azure OpenAI now issues API keys that are 84 alphanumeric characters in addition to the original 32-character lowercase hex format. The existing regex only matched `[a-f0-9]{32}`, missing the newer keys. Changes: - Expand key pattern to match both 32-char and 84-char keys - Accept mixed-case alphanumeric characters (not just lowercase hex) - Fix Redacted field to use relative indexing for both key lengths - Add test cases for 84-char keys (env var, curl, Python SDK, invalid) Fixes #4389 --- pkg/detectors/azure_openai/azure_openai.go | 4 +-- .../azure_openai/azure_openai_test.go | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pkg/detectors/azure_openai/azure_openai.go b/pkg/detectors/azure_openai/azure_openai.go index 5be045f2f60c..e43606863b55 100644 --- a/pkg/detectors/azure_openai/azure_openai.go +++ b/pkg/detectors/azure_openai/azure_openai.go @@ -31,7 +31,7 @@ var ( // TODO: Investigate custom `azure-api.net` endpoints. // https://github.com/openai/openai-python#microsoft-azure-openai azureUrlPat = regexp.MustCompile(`(?i)([a-z0-9-]+\.openai\.azure\.com)`) - azureKeyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"api[_.-]?key", "openai[_.-]?key"}) + `\b(?-i:([a-f0-9]{32}))\b`) + azureKeyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"api[_.-]?key", "openai[_.-]?key"}) + `\b(?-i:([a-zA-Z0-9]{32}|[a-zA-Z0-9]{84}))\b`) invalidServices = simple.NewCache[struct{}]() ) @@ -76,7 +76,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result for token := range tokens { s1 := detectors.Result{ DetectorType: s.Type(), - Redacted: token[:3] + "..." + token[25:], + Redacted: token[:3] + "..." + token[len(token)-4:], Raw: []byte(token), SecretParts: map[string]string{"key": token}, } diff --git a/pkg/detectors/azure_openai/azure_openai_test.go b/pkg/detectors/azure_openai/azure_openai_test.go index 97ab253761d1..00e353da9be1 100644 --- a/pkg/detectors/azure_openai/azure_openai_test.go +++ b/pkg/detectors/azure_openai/azure_openai_test.go @@ -79,6 +79,34 @@ func TestAzureOpenAI_Pattern(t *testing.T) { }`, want: []string{"57d2de35873840b5ad59d742e90e974e"}, }, + { + name: "84-character key - environment variable", + input: `export OPENAI_API_BASE=https://myservice-east.openai.azure.com/ + export OPENAI_API_KEY=uQ9XsjB7aM2eVt5rL1pZcW6yGk4nF8oHd3RzXaYbT7vUjKmQeP5fNwL9oS2tH1rJ3pZxDkMvYeWq0bAs`, + want: []string{"uQ9XsjB7aM2eVt5rL1pZcW6yGk4nF8oHd3RzXaYbT7vUjKmQeP5fNwL9oS2tH1rJ3pZxDkMvYeWq0bAs"}, + }, + { + name: "84-character key - curl command", + input: `curl -X POST "https://prod-openai.openai.azure.com/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview" \ + -H "Content-Type: application/json" \ + -H "api-key: Rk7mTz3nWx9pLq2vBs5yJd8cFg1hNa6oUi4eXwYrKbQjVm0tPl5sDf3gHn7kMz9aRcWx2bYu4eL"`, + want: []string{"Rk7mTz3nWx9pLq2vBs5yJd8cFg1hNa6oUi4eXwYrKbQjVm0tPl5sDf3gHn7kMz9aRcWx2bYu4eL"}, + }, + { + name: "84-character key - Python SDK", + input: `from openai import AzureOpenAI + client = AzureOpenAI( + azure_endpoint="https://team-ai.openai.azure.com/", + api_key="Ht5mNr9wXz3pLq7vBs2yJd6cFg8hKa1oUi4eTxYrQbMjVn0kPl5sDf3gRn7wMz9aXcWx2bYu4eLk0q", + )`, + want: []string{"Ht5mNr9wXz3pLq7vBs2yJd6cFg8hKa1oUi4eTxYrQbMjVn0kPl5sDf3gRn7wMz9aXcWx2bYu4eLk0q"}, + }, + { + name: "invalid - 50 character key (wrong length)", + input: `OPENAI_API_KEY=uQ9XsjB7aM2eVt5rL1pZcW6yGk4nF8oHd3RzXaYbT7vUjKm + https://test.openai.azure.com/`, + want: []string{}, + }, } for _, test := range tests { From f0d195c9197a2b1961b14394e196e9fd2e8b3b45 Mon Sep 17 00:00:00 2001 From: mangod12 <2329095@kiit.ac.in> Date: Fri, 22 May 2026 18:13:26 +0530 Subject: [PATCH 2/3] fix: correct test key lengths to 84 chars and restore hex-only 32-char regex - All three 84-character test keys were wrong length (80, 75, 78). Replaced with exactly 84-character alphanumeric strings. - Restored 32-char key pattern to [a-f0-9]{32} (lowercase hex only) to avoid false positives. Only the new 84-char format uses the broader [a-zA-Z0-9] character class. Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/detectors/azure_openai/azure_openai.go | 2 +- pkg/detectors/azure_openai/azure_openai_test.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/detectors/azure_openai/azure_openai.go b/pkg/detectors/azure_openai/azure_openai.go index e43606863b55..8dc70fa04eb3 100644 --- a/pkg/detectors/azure_openai/azure_openai.go +++ b/pkg/detectors/azure_openai/azure_openai.go @@ -31,7 +31,7 @@ var ( // TODO: Investigate custom `azure-api.net` endpoints. // https://github.com/openai/openai-python#microsoft-azure-openai azureUrlPat = regexp.MustCompile(`(?i)([a-z0-9-]+\.openai\.azure\.com)`) - azureKeyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"api[_.-]?key", "openai[_.-]?key"}) + `\b(?-i:([a-zA-Z0-9]{32}|[a-zA-Z0-9]{84}))\b`) + azureKeyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"api[_.-]?key", "openai[_.-]?key"}) + `\b(?-i:([a-f0-9]{32}|[a-zA-Z0-9]{84}))\b`) invalidServices = simple.NewCache[struct{}]() ) diff --git a/pkg/detectors/azure_openai/azure_openai_test.go b/pkg/detectors/azure_openai/azure_openai_test.go index 00e353da9be1..bacccaf50972 100644 --- a/pkg/detectors/azure_openai/azure_openai_test.go +++ b/pkg/detectors/azure_openai/azure_openai_test.go @@ -82,24 +82,24 @@ func TestAzureOpenAI_Pattern(t *testing.T) { { name: "84-character key - environment variable", input: `export OPENAI_API_BASE=https://myservice-east.openai.azure.com/ - export OPENAI_API_KEY=uQ9XsjB7aM2eVt5rL1pZcW6yGk4nF8oHd3RzXaYbT7vUjKmQeP5fNwL9oS2tH1rJ3pZxDkMvYeWq0bAs`, - want: []string{"uQ9XsjB7aM2eVt5rL1pZcW6yGk4nF8oHd3RzXaYbT7vUjKmQeP5fNwL9oS2tH1rJ3pZxDkMvYeWq0bAs"}, + export OPENAI_API_KEY=NbrnTP3fAbnFbmOHnKYaXRvj7uff0LYTH8xIZM1JRcoreogrNwwmq6OLkTkx9NIQ0Wobtqn62tOy4CqpIqK3`, + want: []string{"NbrnTP3fAbnFbmOHnKYaXRvj7uff0LYTH8xIZM1JRcoreogrNwwmq6OLkTkx9NIQ0Wobtqn62tOy4CqpIqK3"}, }, { name: "84-character key - curl command", input: `curl -X POST "https://prod-openai.openai.azure.com/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview" \ -H "Content-Type: application/json" \ - -H "api-key: Rk7mTz3nWx9pLq2vBs5yJd8cFg1hNa6oUi4eXwYrKbQjVm0tPl5sDf3gHn7kMz9aRcWx2bYu4eL"`, - want: []string{"Rk7mTz3nWx9pLq2vBs5yJd8cFg1hNa6oUi4eXwYrKbQjVm0tPl5sDf3gHn7kMz9aRcWx2bYu4eL"}, + -H "api-key: yn9FfcgMXAdx9G81aSQHqNgAC72qFl41sNLjVHWGaub52Ztd26fEeVVhDIq2AnHTmt9OBGhnuKoneNo41eoP"`, + want: []string{"yn9FfcgMXAdx9G81aSQHqNgAC72qFl41sNLjVHWGaub52Ztd26fEeVVhDIq2AnHTmt9OBGhnuKoneNo41eoP"}, }, { name: "84-character key - Python SDK", input: `from openai import AzureOpenAI client = AzureOpenAI( azure_endpoint="https://team-ai.openai.azure.com/", - api_key="Ht5mNr9wXz3pLq7vBs2yJd6cFg8hKa1oUi4eTxYrQbMjVn0kPl5sDf3gRn7wMz9aXcWx2bYu4eLk0q", + api_key="ni6JDWYlgAACTP9gyv1plBArp5B1Id9Z850kEnydx9qWCA79ISjs8JHUdKF0j7elKPoh3pKMzKG5mSoyPstU", )`, - want: []string{"Ht5mNr9wXz3pLq7vBs2yJd6cFg8hKa1oUi4eTxYrQbMjVn0kPl5sDf3gRn7wMz9aXcWx2bYu4eLk0q"}, + want: []string{"ni6JDWYlgAACTP9gyv1plBArp5B1Id9Z850kEnydx9qWCA79ISjs8JHUdKF0j7elKPoh3pKMzKG5mSoyPstU"}, }, { name: "invalid - 50 character key (wrong length)", From 944342bddd7fcefe34ea508d0bb4d99fe23ac4cd Mon Sep 17 00:00:00 2001 From: mangod12 <2329095@kiit.ac.in> Date: Fri, 22 May 2026 18:19:40 +0530 Subject: [PATCH 3/3] fix(test): use low-entropy test keys to avoid secret scanner alerts Replace random 84-char test keys with repeating-pattern keys. Avoids GitGuardian false positives while still validating the 84-character key regex. Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/detectors/azure_openai/azure_openai_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/detectors/azure_openai/azure_openai_test.go b/pkg/detectors/azure_openai/azure_openai_test.go index bacccaf50972..7d783547d4ce 100644 --- a/pkg/detectors/azure_openai/azure_openai_test.go +++ b/pkg/detectors/azure_openai/azure_openai_test.go @@ -82,24 +82,24 @@ func TestAzureOpenAI_Pattern(t *testing.T) { { name: "84-character key - environment variable", input: `export OPENAI_API_BASE=https://myservice-east.openai.azure.com/ - export OPENAI_API_KEY=NbrnTP3fAbnFbmOHnKYaXRvj7uff0LYTH8xIZM1JRcoreogrNwwmq6OLkTkx9NIQ0Wobtqn62tOy4CqpIqK3`, - want: []string{"NbrnTP3fAbnFbmOHnKYaXRvj7uff0LYTH8xIZM1JRcoreogrNwwmq6OLkTkx9NIQ0Wobtqn62tOy4CqpIqK3"}, + export OPENAI_API_KEY=aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0aB1cD2eF3gH4iJ5kL6mN7oP8`, + want: []string{"aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0aB1cD2eF3gH4iJ5kL6mN7oP8"}, }, { name: "84-character key - curl command", input: `curl -X POST "https://prod-openai.openai.azure.com/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview" \ -H "Content-Type: application/json" \ - -H "api-key: yn9FfcgMXAdx9G81aSQHqNgAC72qFl41sNLjVHWGaub52Ztd26fEeVVhDIq2AnHTmt9OBGhnuKoneNo41eoP"`, - want: []string{"yn9FfcgMXAdx9G81aSQHqNgAC72qFl41sNLjVHWGaub52Ztd26fEeVVhDIq2AnHTmt9OBGhnuKoneNo41eoP"}, + -H "api-key: Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2"`, + want: []string{"Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2Rr1Qq0Zz9Yy8Xx7Ww6Vv5Uu4Tt3Ss2"}, }, { name: "84-character key - Python SDK", input: `from openai import AzureOpenAI client = AzureOpenAI( azure_endpoint="https://team-ai.openai.azure.com/", - api_key="ni6JDWYlgAACTP9gyv1plBArp5B1Id9Z850kEnydx9qWCA79ISjs8JHUdKF0j7elKPoh3pKMzKG5mSoyPstU", + api_key="a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5a1b2c3d4e5f6g7h8i9j0k1l2", )`, - want: []string{"ni6JDWYlgAACTP9gyv1plBArp5B1Id9Z850kEnydx9qWCA79ISjs8JHUdKF0j7elKPoh3pKMzKG5mSoyPstU"}, + want: []string{"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5a1b2c3d4e5f6g7h8i9j0k1l2"}, }, { name: "invalid - 50 character key (wrong length)",