# How SkillSpector Handles LLM Authentication for Different Providers

> Learn how SkillSpector handles LLM authentication for various providers. Discover credential resolution, discovery, and unified error handling for seamless integration.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-07-13

---

**SkillSpector abstracts each LLM vendor behind provider classes that implement a `resolve_credentials()` method to read environment variables and return an `(api_key, base_url)` tuple, with the `_PROVIDERS` registry in [`src/skillspector/providers/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/__init__.py) managing discovery and unified error handling.**

NVIDIA's SkillSpector delegates LLM authentication to modular provider implementations that share a common interface defined in [`src/skillspector/providers/base.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/base.py). This architecture allows you to switch between OpenAI, Anthropic, NVIDIA Inference, and Amazon Bedrock by adjusting only environment variables, eliminating the need for code changes when changing backends.

## The Provider Abstraction Architecture

SkillSpector implements a **provider abstraction pattern** where each LLM vendor encapsulates its authentication logic in a dedicated class. The critical method is `resolve_credentials()`, which returns a tuple of `(api_key, base_url | None)` according to the interface in [`src/skillspector/providers/base.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/base.py).

The authentication flow follows four distinct steps:

1. **Provider discovery** – The CLI or internal graph engine looks up the active provider in the `_PROVIDERS` registry defined in [`src/skillspector/providers/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/__init__.py).
2. **Credential resolution** – The selected provider calls its own `resolve_credentials()` implementation, pulling the appropriate environment variables.
3. **Chat model construction** – The provider hands the returned credentials to the factory in [`src/skillspector/providers/chat_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/chat_models.py), which builds the concrete LangChain chat model (`ChatOpenAI`, `ChatAnthropic`, etc.).
4. **Error handling** – If required variables are missing, `resolve_credentials()` returns `None`, triggering `raise_no_llm_api_key_configured()` from [`src/skillspector/providers/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/__init__.py) to prevent unauthorized requests.

Higher-level code can also access credentials through the public API in [`src/skillspector/llm_utils.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/llm_utils.py).

## Provider-Specific Authentication Requirements

Each supported LLM backend uses distinct environment variables and authentication schemes.

### OpenAI

The `OpenAIProvider` in [`src/skillspector/providers/openai/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/openai/provider.py) expects:

- `OPENAI_API_KEY` (required): The API key for OpenAI's platform or compatible endpoints.
- `OPENAI_BASE_URL` (optional): Overrides the default `https://api.openai.com/v1`.

### Anthropic

The `AnthropicProvider` in [`src/skillspector/providers/anthropic/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/anthropic/provider.py) requires:

- `ANTHROPIC_API_KEY`: The API key for `api.anthropic.com`. This provider uses a hardcoded base URL.

### Anthropic Proxy

The `AnthropicProxyProvider` in [`src/skillspector/providers/anthropic_proxy/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/anthropic_proxy/provider.py) supports private proxy deployments:

- `ANTHROPIC_PROXY_API_KEY` (required): The proxy authentication key.
- `ANTHROPIC_PROXY_ENDPOINT` (required): The full proxy endpoint URL.

Both must be present; otherwise the provider returns `None` and triggers authentication errors.

### NVIDIA Inference (NvBuild)

The `NvBuildProvider` in [`src/skillspector/providers/nv_build/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/nv_build/provider.py) connects to NVIDIA's hosted inference service:

- `NVIDIA_INFERENCE_KEY` (required): API key for NVIDIA Inference.
- Uses the hardcoded base URL `https://api.nvidia.com/v1` (exposed as `BUILD_BASE_URL`).

### Amazon Bedrock

The `BedrockProvider` in [`src/skillspector/providers/bedrock/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/bedrock/provider.py) handles AWS authentication differently:

- Requires standard AWS credentials: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_DEFAULT_REGION`.
- Deliberately returns `None` for the `(api_key, base_url)` tuple because LangChain's Bedrock client handles AWS Signature V4 signing internally.

## Configuration Examples

### Configuring OpenAI Authentication

Set the environment variables and run the CLI:

```bash
export OPENAI_API_KEY="sk-your-openai-key"
export OPENAI_BASE_URL="https://my-proxy.example.com/v1"

```

```python
from skillspector.cli import main

if __name__ == "__main__":
    main()

```

### Configuring Anthropic

```bash
export ANTHROPIC_API_KEY="sk-anthropic-key"

```

```python
from skillspector.providers.anthropic.provider import AnthropicProvider

provider = AnthropicProvider()
chat = provider.create_chat_model(
    model=provider.resolve_model(),
    max_tokens=512,
    timeout=120,
)

```

### Configuring Anthropic Proxy

```bash
export ANTHROPIC_PROXY_API_KEY="proxy-key"
export ANTHROPIC_PROXY_ENDPOINT="https://proxy.mycompany.com/v1"

```

```python
from skillspector.providers.anthropic_proxy.provider import AnthropicProxyProvider

provider = AnthropicProxyProvider()
chat = provider.create_chat_model(
    model="my-custom-model",
    max_tokens=1024,
)

```

### Configuring NVIDIA Inference

```bash
export NVIDIA_INFERENCE_KEY="nv-inference-key"

```

```python
from skillspector.providers.nv_build.provider import NvBuildProvider

provider = NvBuildProvider()
chat = provider.create_chat_model(
    model=provider.resolve_model(),
    max_tokens=256,
)

```

### Configuring Amazon Bedrock

```bash
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="wJalrXUtnF..."
export AWS_DEFAULT_REGION="us-east-1"

```

```python
from skillspector.providers.bedrock.provider import BedrockProvider

provider = BedrockProvider()
chat = provider.create_chat_model(
    model="anthropic.claude-v2",
    max_tokens=512,
)

```

Note that Bedrock does not require an API key in the SkillSpector credential tuple because the AWS SDK handles authentication via Signature V4.

## Summary

- SkillSpector uses a **provider abstraction** where each LLM vendor implements `resolve_credentials()` according to the interface in [`src/skillspector/providers/base.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/base.py).
- The `_PROVIDERS` registry in [`src/skillspector/providers/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/__init__.py) enables dynamic provider discovery and centralized error handling.
- **OpenAI** requires `OPENAI_API_KEY` with optional `OPENAI_BASE_URL` for custom endpoints.
- **Anthropic** uses `ANTHROPIC_API_KEY` with a fixed base URL constant.
- **Anthropic Proxy** requires both `ANTHROPIC_PROXY_API_KEY` and `ANTHROPIC_PROXY_ENDPOINT`.
- **NVIDIA Inference** uses `NVIDIA_INFERENCE_KEY` and a hardcoded NVIDIA base URL.
- **Amazon Bedrock** relies on standard AWS environment variables and returns `None` for the credential tuple, delegating signing to the AWS SDK.
- Missing credentials trigger `raise_no_llm_api_key_configured()` to prevent any LLM requests without proper authentication.

## Frequently Asked Questions

### How does SkillSpector validate that LLM credentials are properly configured?

Each provider's `resolve_credentials()` method checks for required environment variables. If any are missing, the method returns `None`, which causes the factory in [`src/skillspector/providers/__init__.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/__init__.py) to invoke `raise_no_llm_api_key_configured()`, raising an exception before any network request is attempted.

### Can I use a custom base URL with OpenAI-compatible providers?

Yes. The `OpenAIProvider` in [`src/skillspector/providers/openai/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/openai/provider.py) reads the optional `OPENAI_BASE_URL` environment variable. When set, this value overrides the default `https://api.openai.com/v1` endpoint, allowing connection to self-hosted or proxy OpenAI-compatible APIs.

### Why doesn't the Amazon Bedrock provider require an API key?

The `BedrockProvider` in [`src/skillspector/providers/bedrock/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/providers/bedrock/provider.py) returns `None` for the `(api_key, base_url)` tuple because AWS authentication uses Signature Version 4. The LangChain Bedrock client automatically retrieves credentials from the environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_DEFAULT_REGION`, handling the signing process internally without exposing an API key to SkillSpector's credential resolution system.

### How do I switch between different LLM providers in SkillSpector?

Switching providers requires changing the active provider configuration and setting the corresponding environment variables. The CLI looks up the desired provider in the `_PROVIDERS` registry, and the respective `resolve_credentials()` method handles vendor-specific authentication. No code changes are necessary—only environment variable updates.