Skip to content

MAINT Migrate Azure Cognitive Services from API key to Entra ID authentication#1404

Open
romanlutz wants to merge 23 commits intoAzure:mainfrom
romanlutz:romanlutz/entra-auth-migration
Open

MAINT Migrate Azure Cognitive Services from API key to Entra ID authentication#1404
romanlutz wants to merge 23 commits intoAzure:mainfrom
romanlutz:romanlutz/entra-auth-migration

Conversation

@romanlutz
Copy link
Contributor

Summary

This PR removes API key (local auth) dependencies for all Azure Cognitive Services targets in PyRIT, replacing them with Entra ID (Azure AD) token-based
authentication. This is in preparation for disabling local auth across 62 CogSvc resources in the AI Red Team Tooling and Trustworthy Machine Learning
subscriptions.

Changes

Core: AIRTTargetInitializer

  • Removed key_var from 16 Azure TargetConfig entries (OpenAI Chat, Responses, Image, Video, TTS, Content Safety, PromptShield)
  • Updated _register_target() to auto-detect Azure endpoints and use Entra auth: async token provider for OpenAI SDK targets, sync token provider for
    PromptShieldTarget
  • Non-Azure targets (platform OpenAI, Groq, OpenRouter, Ollama, Google Gemini) continue using API keys

Notebooks (15 .py + .ipynb pairs)

  • Replaced api_key=os.getenv("AZURE_*_KEY") with get_azure_openai_auth(endpoint) or get_azure_token_provider(scope)
  • All notebooks re-executed with jupytext --execute to validate Entra auth works end-to-end

.env_example

  • Removed 21 Azure CogSvc key lines that are no longer needed

Bug fixes (found during migration)

  • HTTPTarget re.sub bug: LLM responses containing \u unicode escapes caused re.sub to fail. Fixed by using lambda replacement.
  • HTTP notebook URL: Was posting to wrong path (/openai/v1?api-version=... → 404). Fixed to use /openai/v1/chat/completions with model in body.
  • HTTPTarget content filter detection: Empty responses from content-filtered requests were silently returned as success. Now detected and returned as
    error/blocked type, consistent with other targets.

Other improvements

  • Image editing notebook cell now uses gpt-image-1 (ENDPOINT2) since dall-e-3 doesn't support editing
  • Fixed Playwright Copilot Target notebook title (added "10.2" prefix)

What's NOT changing

  • Non-Azure targets: Platform OpenAI, Groq, OpenRouter, Ollama, Google Gemini, Anthropic — keep API keys
  • Azure ML: Not a Cognitive Services resource — keeps API keys
  • XPIA website: Code updated for Entra auth but not re-executed (requires separate infrastructure)

Testing

  • 22 unit tests pass (including 2 new content filter tests, 1 new Entra auth test)
  • 18+ notebooks executed successfully with Entra auth

romanlutz and others added 14 commits February 25, 2026 12:14
- Update AIRTTargetInitializer to use get_azure_openai_auth() for Azure
  OpenAI targets and get_azure_token_provider() for PromptShieldTarget
  instead of API key environment variables
- Remove key_var from all Azure target configs in TARGET_CONFIGS
- Update 15 notebook .py files to use Entra auth for Azure endpoints
- Non-Azure targets (platform OpenAI, Groq, Google, etc.) keep API keys
- Update unit tests to mock Entra auth providers

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove Azure CogSvc API key lines from .env_example
- Update .env_example header to reflect Entra auth is the default
- Re-execute 13 notebooks with jupytext --execute to verify Entra auth
  works and populate cell outputs

All notebooks pass except:
- 10_http_target: second cell fails with pre-existing regex bug (unrelated)
- 7_azure_sql_memory_attacks: fails due to az login not available in
  kernel subprocess (infrastructure issue, not auth)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cell 1 (AOAI example) succeeds with Entra auth.
Cell 2 (Red Teaming) fails due to pre-existing regex bug in HTTPTarget.
BIC cells are not executable (require browser cookies).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add '10.2' to Playwright Copilot Target title in .py and .ipynb
- Restore xpia website notebook outputs from main
- Execute 7_azure_sql_memory_attacks notebook (all 4 cells pass)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use lambda in re.sub to prevent backslash interpretation in LLM
response text (e.g. \u unicode escapes). All cells now pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
All three notebooks pass with Entra auth via AIRTTargetInitializer.
Image notebook cell 2 (image editing) has pre-existing model error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dall-e-3 does not support image editing. Switch to OPENAI_IMAGE_ENDPOINT2
(gpt-image-1) with Entra auth for the editing example.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Empty assistant responses are due to content filtering on the Azure
endpoint, not auth issues. Auth works correctly with Entra tokens.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix notebook URL: use /chat/completions path (was getting 404s)
- Add model field to raw HTTP request body
- Detect content-filtered responses and return error type
- Add 2 unit tests for content filter handling

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Strip notebook outputs (nbstripout)
- Remove notebook headers
- Fix end-of-file newlines
- Fix mypy type annotation for api_key in airt_targets.py
- Remaining mypy errors in openai_video_target.py are pre-existing from main

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sphinx/myst-nb requires language_info to determine the lexer for
code cells. The metadata was lost when restoring outputs from main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Contributor

@hannahwestra25 hannahwestra25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly nits but looks good

@riedgar-ms
Copy link
Contributor

Happy to see this becoming the official way of running notebooks

Copilot AI review requested due to automatic review settings February 26, 2026 21:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates Azure Cognitive Services usage in PyRIT from API-key (“local auth”) to Entra ID token-based authentication, updating the AIRT target initializer and the documentation/notebook examples accordingly. It also includes a small HTTPTarget robustness fix and adds tests around content-filter handling.

Changes:

  • Update AIRTTargetInitializer to auto-select Entra ID token providers for Azure endpoints (async for Azure OpenAI SDK targets; sync for PromptShieldTarget).
  • Improve HTTPTarget request injection and add content-filter detection for empty callback responses.
  • Update unit tests and documentation notebooks/scripts to use get_azure_openai_auth() / get_azure_token_provider() instead of Azure API keys.

Reviewed changes

Copilot reviewed 36 out of 40 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/unit/target/test_http_target.py Adds unit tests for HTTPTarget content-filter detection.
tests/unit/setup/test_airt_targets_initializer.py Updates initializer tests to patch token providers and adds an Entra-auth test.
pyrit/setup/initializers/airt_targets.py Removes Azure key env-var dependencies and injects Entra token providers when registering Azure targets.
pyrit/prompt_target/http_target/http_target.py Fixes regex substitution for prompts and detects content-filtered empty responses as errors.
doc/code/targets/prompt_shield_target.py Updates PromptShieldTarget example to use Entra token provider instead of API key.
doc/code/targets/prompt_shield_target.ipynb Notebook equivalent of PromptShieldTarget Entra auth update.
doc/code/targets/5_openai_tts_target.ipynb Updates executed notebook output/metadata for TTS example (auth migration context).
doc/code/targets/3_openai_image_target.py Updates image target example to use Entra token provider for Azure endpoint.
doc/code/targets/2_openai_responses_target.py Updates Responses target examples to use Entra token provider for Azure endpoints.
doc/code/targets/2_openai_responses_target.ipynb Notebook equivalent of Responses target Entra auth update.
doc/code/targets/1_openai_chat_target.py Updates Chat target example to use Entra token provider for Azure endpoint.
doc/code/targets/1_openai_chat_target.ipynb Notebook equivalent of Chat target Entra auth update.
doc/code/targets/10_http_target.py Updates raw HTTP example to use Bearer token (Entra) and correct Azure OpenAI path/model placement.
doc/code/targets/10_2_playwright_target_copilot.py Renames notebook title/header to include “10.2” prefix.
doc/code/targets/10_2_playwright_target_copilot.ipynb Notebook equivalent header/title update.
doc/code/setup/1_configuration.py Updates configuration example to use Entra token provider for Azure endpoints.
doc/code/setup/1_configuration.ipynb Notebook equivalent configuration Entra auth update.
doc/code/scoring/8_scorer_metrics.py Updates scoring examples to use Entra token provider for Azure OpenAI endpoints.
doc/code/scoring/8_scorer_metrics.ipynb Notebook equivalent scoring Entra auth update.
doc/code/scoring/1_azure_content_safety_scorers.py Updates Content Safety scorer example to use Entra token provider.
doc/code/scoring/1_azure_content_safety_scorers.ipynb Notebook equivalent Content Safety scorer Entra auth update.
doc/code/memory/7_azure_sql_memory_attacks.py Updates image target usage in memory/attack example to use Entra token provider.
doc/code/executor/workflow/1_xpia_website.py Updates workflow example to use Entra token provider for Azure OpenAI.
doc/code/executor/workflow/1_xpia_website.ipynb Notebook equivalent workflow Entra auth update.
doc/code/executor/attack/violent_durian_attack.py Updates executor attack example to use Entra token providers.
doc/code/executor/attack/violent_durian_attack.ipynb Notebook equivalent violent_durian Entra auth update.
doc/code/executor/attack/tap_attack.py Updates TAP attack example to use Entra token provider.
doc/code/executor/attack/tap_attack.ipynb Notebook equivalent TAP attack Entra auth update.
doc/code/executor/attack/role_play_attack.py Updates role-play attack example to use Entra token provider.
doc/code/executor/attack/role_play_attack.ipynb Notebook equivalent role-play attack Entra auth update.
doc/code/executor/attack/context_compliance_attack.py Updates context compliance attack example to use Entra token provider.
doc/code/executor/attack/context_compliance_attack.ipynb Notebook equivalent context compliance Entra auth update.
doc/code/executor/attack/3_crescendo_attack.py Updates Crescendo attack example to use Entra token provider.
doc/code/executor/attack/2_red_teaming_attack.py Updates red teaming attack example to use Entra token provider.
Comments suppressed due to low confidence (4)

tests/unit/target/test_http_target.py:323

  • The basic HTTPTarget init assertions appear to have been accidentally appended to test_send_prompt_async_normal_response_not_marked_as_error. This makes the test cover two unrelated behaviors and the name no longer matches what it verifies. Split the initialization checks back into their own test_http_target_init_basic (or similar) and keep this test focused on the content-filter detection behavior.
    doc/code/targets/prompt_shield_target.py:82
  • This example references AZURE_CONTENT_SAFETY_ENDPOINT, but PromptShieldTarget (and the AIRT initializer) use AZURE_CONTENT_SAFETY_API_ENDPOINT. As written, users following this doc will set the wrong env var and the endpoint will resolve to None.
    doc/code/targets/prompt_shield_target.ipynb:91
  • The notebook text tells users to set AZURE_CONTENT_SAFETY_ENDPOINT, but the library expects AZURE_CONTENT_SAFETY_API_ENDPOINT for Prompt Shield / Content Safety. Update the documentation text to use the correct env var name.
    doc/code/targets/prompt_shield_target.ipynb:146
  • This code cell reads AZURE_CONTENT_SAFETY_ENDPOINT, but PromptShieldTarget uses AZURE_CONTENT_SAFETY_API_ENDPOINT by default. Use the correct env var here so the example works when copied as-is.

romanlutz and others added 2 commits February 27, 2026 10:54
…es, document content filter check

- Simplify image notebook to use single gpt-image-1.5 target for both generation and editing
- Add commented-out API key examples in chat, responses, HTTP, and PromptShield target notebooks
- Add code comment explaining why content filter check is HTTP-specific
- Sync .ipynb files with .py changes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 27, 2026 20:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 36 out of 40 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

tests/unit/target/test_http_target.py:327

  • The basic HTTPTarget initialization assertions (http_request/prompt_regex_string/use_tls/...) are currently appended to the end of test_send_prompt_async_normal_response_not_marked_as_error, which mixes two unrelated test concerns in one test case. Move these lines into their own dedicated sync test (e.g., reintroduce test_http_target_init_basic) so failures are isolated and the async behavior test only validates the content-filter logic.
    pyrit/setup/initializers/airt_targets.py:388
  • The Entra-auth detection for Azure OpenAI targets relies on "azure" in endpoint.lower(). This is brittle: Azure endpoints can be fronted by custom domains that don't contain the substring, and non-Azure endpoints could theoretically include it. Consider determining Azure-ness via urlparse(endpoint).hostname and known Azure suffixes (e.g., .openai.azure.com, .cognitiveservices.azure.com, .ai.azure.com) or by an explicit flag on TargetConfig for Azure auth.
    doc/code/targets/prompt_shield_target.py:83
  • This example uses AZURE_CONTENT_SAFETY_ENDPOINT, but the actual PromptShieldTarget environment variable is AZURE_CONTENT_SAFETY_API_ENDPOINT (see PromptShieldTarget.ENDPOINT_URI_ENVIRONMENT_VARIABLE). Align the docs and code sample to the correct env var name to prevent runtime misconfiguration.
    doc/code/targets/2_openai_responses_target.ipynb:536
  • This notebook output includes an Unclosed client session warning from aiohttp. This indicates a real resource leak during execution (likely a ClientSession created in a tool/helper that isn't closed). Update the notebook code path (or underlying helper) to ensure sessions are properly closed (e.g., via async with/context manager) and re-execute so the committed notebook output is clean.
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Unclosed client session\n",
      "client_session: <aiohttp.client.ClientSession object at 0x000001757DEBE0C0>\n"
     ]

romanlutz and others added 2 commits February 27, 2026 15:17
OpenAITarget now falls back to get_azure_openai_auth() when no api_key
is provided and the endpoint contains 'azure'. This enables
OpenAIChatTarget() with no args to work with Entra auth when
API keys are removed from .env.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- AIRTInitializer: Remove API key env vars from required_env_vars, stop passing
  api_key to OpenAIChatTarget (auto-detects Entra auth for Azure endpoints)
- SimpleInitializer: Remove OPENAI_CHAT_KEY from required_env_vars
- AzureContentFilterScorer: Make API key optional, auto-detect Entra auth via
  get_azure_token_provider when no key provided
- Fix notebooks: remove explicit API key usage in 1_configuration.py,
  1_anecdoctor_generator.py, 2_precomputing_turns.py, 5_psychosocial_harms.py
- Update tests to match new requirements

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 27, 2026 23:46
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 45 out of 51 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (6)

pyrit/setup/initializers/airt_targets.py:399

  • When key_var is empty and the endpoint is not detected as Azure/PromptShield, _register_target sets api_key = "not-needed" and still passes it into the target constructor. For OpenAI-compatible targets this will be treated as a real API key and may cause confusing 401s (or send an Authorization header to services that don’t expect one). Consider instead omitting the api_key kwarg entirely for no-auth targets, and/or adding an explicit auth_mode flag to TargetConfig so Azure Entra, API key, and no-auth endpoints are handled unambiguously.
    tests/unit/target/test_http_target.py:327
  • test_send_prompt_async_normal_response_not_marked_as_error currently also contains the basic HTTPTarget initialization assertions (http_request/target defaults) at the end of the async test. This couples two unrelated behaviors and makes failures harder to interpret. Please move the initialization assertions back into their own dedicated sync test (e.g., restore test_http_target_init_basic) so each test validates one behavior.
    doc/code/targets/5_openai_tts_target.ipynb:46
  • This notebook output includes machine-specific absolute paths and a local username (e.g., C:\\Users\\... and a local repo path). Consider clearing notebook outputs or sanitizing paths before committing so the docs are reproducible and don’t leak developer workstation details.
    doc/code/targets/1_openai_chat_target.py:106
  • endpoint = os.getenv(...) can be None, but it is passed directly into get_azure_openai_auth(endpoint), which expects a str and will raise a TypeError before OpenAIChatTarget can produce a clearer configuration error. Prefer using os.environ[...] for required env vars, guarding against None, or simply omit api_key and let OpenAIChatTarget auto-select Entra auth for Azure endpoints.
# Create the OpenAI Chat target
endpoint = os.getenv("AZURE_OPENAI_GPT5_COMPLETIONS_ENDPOINT")
target = OpenAIChatTarget(
    endpoint=endpoint,
    api_key=get_azure_openai_auth(endpoint),
    model_name=os.getenv("AZURE_OPENAI_GPT5_COMPLETIONS_MODEL"),

pyrit/prompt_target/openai/openai_target.py:181

  • There is an inline import of get_azure_openai_auth inside __init__. Project guidelines require imports at the top of the file (except rare, documented circular-import breaks). Please move this import to module scope or otherwise document why a local import is required.
    pyrit/score/float_scale/azure_content_filter_scorer.py:143
  • There is an inline import of get_azure_token_provider inside __init__. The codebase style requires imports at the top of the file (except rare, documented circular-import breaks). Please move this import to module scope (and then reuse it here) so linters and dependency tooling behave consistently.

Comment on lines 91 to 146
@@ -99,6 +99,15 @@
"id": "7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found default environment files: ['C:\\\\Users\\\\romanlutz\\\\.pyrit\\\\.env', 'C:\\\\Users\\\\romanlutz\\\\.pyrit\\\\.env.local']\n",
"Loaded environment file: C:\\Users\\romanlutz\\.pyrit\\.env\n",
"Loaded environment file: C:\\Users\\romanlutz\\.pyrit\\.env.local\n"
]
},
{
"name": "stdout",
"output_type": "stream",
@@ -109,6 +118,7 @@
"\u001b[34m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
"\u001b[34m \u001b[0m\n",
"\u001b[34m Hello! Can you please retrieve the total number of sales in the document?\u001b[0m\n",
"\u001b[34m \u001b[0m\n",
"\n",
"\u001b[33m────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n",
"\u001b[1m\u001b[33m🔸 ASSISTANT\u001b[0m\n",
@@ -122,14 +132,20 @@
"source": [
"import os\n",
"\n",
"from pyrit.auth import get_azure_token_provider\n",
"from pyrit.executor.attack import ConsoleAttackResultPrinter, PromptSendingAttack\n",
"from pyrit.prompt_target import PromptShieldTarget\n",
"from pyrit.setup import IN_MEMORY, initialize_pyrit_async\n",
"\n",
"await initialize_pyrit_async(memory_db_type=IN_MEMORY) # type: ignore\n",
"\n",
"\n",
"pst = PromptShieldTarget(os.environ.get(\"AZURE_CONTENT_SAFETY_ENDPOINT\"), os.environ.get(\"AZURE_CONTENT_SAFETY_KEY\"))\n",
"pst = PromptShieldTarget(\n",
" os.environ.get(\"AZURE_CONTENT_SAFETY_ENDPOINT\"),\n",
" get_azure_token_provider(\"https://cognitiveservices.azure.com/.default\"),\n",
")\n",
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This notebook refers to AZURE_CONTENT_SAFETY_ENDPOINT, but PromptShieldTarget uses AZURE_CONTENT_SAFETY_API_ENDPOINT (see pyrit/prompt_target/prompt_shield_target.py). As written, os.environ.get("AZURE_CONTENT_SAFETY_ENDPOINT") will likely be None and the example will fail. Please update the env var name in both the text and the code cell.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +85
# The environment variable you'll need is `AZURE_CONTENT_SAFETY_ENDPOINT`. Make sure to add it to your .env file if you get an error, and that your deployment is in a region where Prompt Shield is supported. Authentication uses Entra ID via `az login`.
#
# PromptShieldTarget is a target that uses Prompt Shield as its backend. Here's an example of how it processes input:

# %%
import os

from pyrit.auth import get_azure_token_provider
from pyrit.executor.attack import ConsoleAttackResultPrinter, PromptSendingAttack
from pyrit.prompt_target import PromptShieldTarget
from pyrit.setup import IN_MEMORY, initialize_pyrit_async

await initialize_pyrit_async(memory_db_type=IN_MEMORY) # type: ignore


pst = PromptShieldTarget(os.environ.get("AZURE_CONTENT_SAFETY_ENDPOINT"), os.environ.get("AZURE_CONTENT_SAFETY_KEY"))
pst = PromptShieldTarget(
os.environ.get("AZURE_CONTENT_SAFETY_ENDPOINT"),
get_azure_token_provider("https://cognitiveservices.azure.com/.default"),
)
# To use an API key instead of Entra ID auth:
# pst = PromptShieldTarget(os.environ.get("AZURE_CONTENT_SAFETY_ENDPOINT"), api_key="your-api-key")
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses AZURE_CONTENT_SAFETY_ENDPOINT, but PromptShieldTarget expects AZURE_CONTENT_SAFETY_API_ENDPOINT. With the current env var name, endpoint will be missing and the sample will raise when initializing the target. Please update the doc to use the correct env var name (and keep the commented API-key example consistent).

Copilot uses AI. Check for mistakes.
romanlutz and others added 2 commits February 28, 2026 05:47
Revert auto-detection logic in OpenAITarget, AzureContentFilterScorer,
and content filter detection in HTTPTarget. Instead, handle Entra auth
explicitly in the initializers:

- SimpleInitializer: OPENAI_CHAT_KEY is optional; falls back to Entra
  auth via get_azure_openai_auth() when not set
- AIRTInitializer: Uses get_azure_openai_auth() and
  get_azure_token_provider() explicitly for all Azure endpoints
- Notebooks: Pass Entra auth explicitly via get_azure_openai_auth()
- OpenAITarget/AzureContentFilterScorer: Reverted to get_required_value
  for api_key (callers must provide auth)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nb files

Updated cells in 1_openai_chat_target.py, 2_openai_responses_target.py,
and 1_configuration.py that were still calling OpenAIChatTarget() or
OpenAIResponseTarget() without passing api_key. All notebooks now use
get_azure_openai_auth(endpoint) explicitly.

Regenerated all 5 ipynb files via jupytext --execute.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 28, 2026 14:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 43 out of 48 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (10)

pyrit/setup/initializers/simple.py:104

  • There is an inline import (from pyrit.auth import get_azure_openai_auth) inside _get_api_key. Imports are expected at module top-level in this codebase; please move this import to the top of the file (or document why it must remain local, e.g., to avoid a circular dependency).
    pyrit/setup/initializers/simple.py:131
  • api_key is typed as str here, but initialize_async can pass an Entra token-provider callable from _get_api_key(). Please widen the type hint for api_key (and the other setup helpers) to match what OpenAIChatTarget(api_key=...) accepts (string or token provider).
    pyrit/setup/initializers/airt.py:116
  • converter_api_key / scorer_api_key now come from get_azure_openai_auth(...), which returns a token-provider callable. Please update the type hints and downstream method signatures to allow token-provider callables (not just str) so the Entra-auth contract is accurately represented.
    doc/code/targets/2_openai_responses_target.py:251
  • endpoint is optional here (os.getenv(...)) but is passed into get_azure_openai_auth(endpoint). If unset, this will fail at runtime. Prefer os.environ[...] for required endpoints or add an explicit guard/clear error before calling the auth helper.
    doc/code/targets/1_openai_chat_target.py:102
  • endpoint = os.getenv(...) can be None, but it’s passed into get_azure_openai_auth(endpoint). If the env var is missing, this will fail at runtime. Please use os.environ[...] for required endpoints or add a None check with a clear error before calling the auth helper.
endpoint = os.getenv("AZURE_OPENAI_GPT5_COMPLETIONS_ENDPOINT")
target = OpenAIChatTarget(
    endpoint=endpoint,
    api_key=get_azure_openai_auth(endpoint),
    model_name=os.getenv("AZURE_OPENAI_GPT5_COMPLETIONS_MODEL"),

doc/code/targets/10_http_target.py:50

  • endpoint / model are read with os.environ.get(...) but later assumed to be present when constructing the URL/body. If either is unset, the example will generate an invalid request (e.g., None/chat/completions or "model": "None"). Please use os.environ[...] for required values or validate them explicitly before building the request.
endpoint = os.environ.get("AZURE_OPENAI_GPT3_5_CHAT_ENDPOINT")
model = os.environ.get("AZURE_OPENAI_GPT3_5_CHAT_MODEL")
token_provider = get_azure_token_provider("https://cognitiveservices.azure.com/.default")
access_token = token_provider()
# To use an API key instead of Entra ID auth, replace the Authorization header with:

pyrit/setup/initializers/simple.py:104

  • There is an inline import (from pyrit.auth import get_azure_openai_auth) inside _get_api_key. Imports are expected at module top-level in this codebase; please move this import to the top of the file (or document why it must remain local, e.g., to avoid a circular dependency).
    doc/code/targets/2_openai_responses_target.py:316
  • gpt5_endpoint can be None, but it’s passed into get_azure_openai_auth(gpt5_endpoint), which will fail when unset. Please make the endpoint required (os.environ[...]) or guard against None with a clear message before requesting auth.
    pyrit/setup/initializers/airt.py:154
  • api_key is still typed as str in this helper signature, but initialize_async now passes the Entra token-provider callable returned by get_azure_openai_auth(...). Please widen the api_key type hint here (and in other helpers) to accept token providers so the Entra-auth contract is accurately represented.
    pyrit/setup/initializers/simple.py:91
  • _get_api_key is introduced without type annotations (suppressed via type: ignore), which makes it unclear that this may return either a string API key or a token-provider callable. Please add an explicit return type and remove the untyped suppression so static checks reflect the intended contract.

AIRTInitializer now checks for API key env vars (AZURE_OPENAI_GPT4O_UNSAFE_CHAT_KEY,
AZURE_OPENAI_GPT4O_UNSAFE_CHAT_KEY2, AZURE_CONTENT_SAFETY_API_KEY) before falling
back to Entra ID authentication. This matches the SimpleInitializer pattern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants