Summary
Many enterprise organizations use Azure OpenAI Service rather than the public OpenAI API. Azure OpenAI has a fundamentally different authentication model — it uses Azure AD tokens or API keys scoped to a resource endpoint, and models are referenced by deployment name rather than model ID.
Today, SkillSpector's openai provider assumes stock OpenAI conventions (OPENAI_API_KEY + model IDs like gpt-5.4). While OPENAI_BASE_URL can point to an Azure endpoint, Azure requires an api-version query parameter and uses deployment-based routing that ChatOpenAI doesn't handle correctly. LangChain provides a dedicated AzureChatOpenAI class for this.
Why This Matters
Scenario: Enterprise security team behind Azure-only policy
A company's infosec policy routes all AI traffic through their Azure OpenAI resource. They have GPT-4o deployed as security-gpt4o. They try:
export SKILLSPECTOR_PROVIDER=openai
export OPENAI_API_KEY=<azure-key>
export OPENAI_BASE_URL=https://myorg.openai.azure.com/
export SKILLSPECTOR_MODEL=security-gpt4o
skillspector scan ./agent-skill/
This fails because:
- Azure requires
api-version in the URL (e.g., 2024-06-01)
- The deployment name
security-gpt4o is not a valid OpenAI model ID
- Azure endpoints use a different path structure (
/openai/deployments/{name}/chat/completions)
They're forced to either skip LLM analysis entirely or set up a proxy that translates between OpenAI and Azure formats.
Proposed Implementation
providers/
azure_openai/
__init__.py
provider.py
model_registry.yaml
Environment variables:
| Variable |
Required |
Description |
AZURE_OPENAI_ENDPOINT |
Yes |
Azure resource endpoint (e.g., https://myorg.openai.azure.com/) |
AZURE_OPENAI_API_KEY |
Yes* |
Azure API key (*or use Azure AD via AZURE_OPENAI_AD_TOKEN) |
AZURE_OPENAI_DEPLOYMENT |
Yes |
Deployment name (used as azure_deployment in LangChain) |
AZURE_OPENAI_API_VERSION |
No |
API version (default: 2024-06-01) |
provider.py:
from langchain_openai import AzureChatOpenAI
class AzureOpenAIProvider:
DEFAULT_MODEL = "gpt-4o"
SLOT_DEFAULTS: dict[str, str] = {}
def resolve_credentials(self) -> tuple[str, str | None] | None:
api_key = os.environ.get("AZURE_OPENAI_API_KEY", "").strip()
endpoint = os.environ.get("AZURE_OPENAI_ENDPOINT", "").strip()
if not api_key or not endpoint:
return None
return api_key, endpoint
def create_chat_model(self, model, *, max_tokens, timeout=120):
creds = self.resolve_credentials()
if creds is None:
return None
api_key, endpoint = creds
deployment = os.environ.get("AZURE_OPENAI_DEPLOYMENT", model).strip()
api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-06-01").strip()
return AzureChatOpenAI(
azure_endpoint=endpoint,
azure_deployment=deployment,
api_key=api_key,
api_version=api_version,
max_tokens=max_tokens,
timeout=timeout,
)
Selection:
export SKILLSPECTOR_PROVIDER=azure_openai
export AZURE_OPENAI_ENDPOINT=https://myorg.openai.azure.com/
export AZURE_OPENAI_API_KEY=<key>
export AZURE_OPENAI_DEPLOYMENT=security-gpt4o
skillspector scan ./my-skill/
Scope
- New
providers/azure_openai/ subpackage (~60 lines)
- Registration in
providers/__init__.py (~5 lines)
- Tests: credential resolution, deployment name mapping, API version defaults
- Documentation: add Azure to README provider table and
.env.example
Dependency
langchain-openai already ships AzureChatOpenAI — no new dependency needed.
Summary
Many enterprise organizations use Azure OpenAI Service rather than the public OpenAI API. Azure OpenAI has a fundamentally different authentication model — it uses Azure AD tokens or API keys scoped to a resource endpoint, and models are referenced by deployment name rather than model ID.
Today, SkillSpector's
openaiprovider assumes stock OpenAI conventions (OPENAI_API_KEY+ model IDs likegpt-5.4). WhileOPENAI_BASE_URLcan point to an Azure endpoint, Azure requires anapi-versionquery parameter and uses deployment-based routing thatChatOpenAIdoesn't handle correctly. LangChain provides a dedicatedAzureChatOpenAIclass for this.Why This Matters
Scenario: Enterprise security team behind Azure-only policy
A company's infosec policy routes all AI traffic through their Azure OpenAI resource. They have GPT-4o deployed as
security-gpt4o. They try:This fails because:
api-versionin the URL (e.g.,2024-06-01)security-gpt4ois not a valid OpenAI model ID/openai/deployments/{name}/chat/completions)They're forced to either skip LLM analysis entirely or set up a proxy that translates between OpenAI and Azure formats.
Proposed Implementation
Environment variables:
AZURE_OPENAI_ENDPOINThttps://myorg.openai.azure.com/)AZURE_OPENAI_API_KEYAZURE_OPENAI_AD_TOKEN)AZURE_OPENAI_DEPLOYMENTazure_deploymentin LangChain)AZURE_OPENAI_API_VERSION2024-06-01)provider.py:Selection:
Scope
providers/azure_openai/subpackage (~60 lines)providers/__init__.py(~5 lines).env.exampleDependency
langchain-openaialready shipsAzureChatOpenAI— no new dependency needed.