> For the complete documentation index, see [llms.txt](https://docs.xygeni.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xygeni.io/xygeni-products/scan-management/ai-agents-configuration.md).

# AI Agents Configuration

Xygeni features that use AI — [AI Triage](/xygeni-administration/platform-administration/projects-management/ai-triage.md) and the [Xygeni Bot](/xygeni-products/scan-management/xygeni-bot.md) auto-remediation flow — share the same set of supported AI providers and the same configuration keys. Two locations are accepted:

* **`xygenibot.yml`** — the Xygeni Bot configuration file (`sast.ai-agents` and `sast.ai-remediation-agent` under the `sast` block). Primary location, consulted first.
* **`xygeni.yml`** — the main scanner configuration file (top-level `ai-agents` and `ai-agent` keys). Used as a fallback when the corresponding field is not declared in `xygenibot.yml`. Useful for projects that prefer to keep their scanner configuration consolidated in `xygeni.yml`.

## Supported providers

The same list applies to both files:

* **Xygeni** — managed Xygeni-hosted agent. Default when nothing is configured.
* **Anthropic**
* **Google Gemini**
* **Groq**
* **OpenAI**
* **OpenRouter**
* **Microsoft Foundry** (also covers Azure OpenAI)
* **Custom / OpenAI-compatible** — your own model behind an OpenAI-compatible API

For each provider you can declare `host`, `token`, `model`, and free-form `options`. Values support environment-variable indirection with the standard `${ENV_VAR}` and `${ENV_VAR:-default}` patterns.

## Schema in `xygeni.yml`

Add the two top-level keys to your `xygeni.yml`:

```yaml
# conf/xygeni.yml

# ... existing scanner configuration ...

ai-agent: ${XYGENI_AI_AGENT:openai}                 # selected agent

ai-agents:
  anthropic:
    host:  ${ANTHROPIC_HOST:https://api.anthropic.com}
    token: ${ANTHROPIC_API_KEY}
    model: claude-sonnet-4-6

  openai:
    host:  ${OPENAI_HOST:https://api.openai.com/v1}
    token: ${OPENAI_API_KEY}
    model: gpt-4o

  gemini:
    host:  ${GEMINI_HOST:https://generativelanguage.googleapis.com/v1beta}
    token: ${GEMINI_TOKEN}
    model: gemini-2.5-flash

  groq:
    host:  ${GROQ_HOST:https://api.groq.com/openai/v1}
    token: ${GROQ_TOKEN}
    model: llama-3.1-8b-instant

  openrouter:
    host:  ${OPENROUTER_HOST:https://openrouter.ai/api/v1}
    token: ${OPENROUTER_TOKEN}
    model: openai/gpt-4o

  foundry:
    host:       https://<resource>.services.ai.azure.com   # bare resource endpoint
    deployment: gpt-4o                                     # the deployment name IS the model
    token:      ${FOUNDRY_API_KEY}                         # api-key auth

  openai-compatible:
    host:  https://llm.example.com/v1                      # required, base URL with the version path
    model: llama-3.3-70b                                   # required
    token: ${OPENAI_COMPATIBLE_API_KEY}                    # optional

  xygeni: {}                                         # use Xygeni-hosted agent
```

`ai-agent` accepts any of the provider names listed above (`openai_compatible` for the Custom / OpenAI-compatible provider) plus `global` (use the agent globally configured for your account).

Both keys are optional. A `xygeni.yml` that does not declare them remains valid.

## Schema in `xygenibot.yml`

In `xygenibot.yml` the same configuration lives under the `sast` block:

```yaml
sast:
  ai-agents:
    openai:
      host:  ${OPENAI_HOST:-https://api.openai.com/v1}
      token: ${OPENAI_TOKEN}
      model: ${OPENAI_MODEL:-gpt-4o}
    # ... other providers ...

  ai-remediation-agent: openai
```

See [Xygeni Bot](/xygeni-products/scan-management/xygeni-bot.md) for the full `xygenibot.yml` reference, including the rest of the SAST and SCA remediation settings.

## Microsoft Foundry (Azure OpenAI)

The `foundry` provider covers both a dedicated Azure OpenAI resource (`*.openai.azure.com`) and a multi-model Microsoft Foundry resource (`*.services.ai.azure.com`). Its fields differ slightly from the other providers:

* **`host`** — the **bare** resource endpoint, e.g. `https://my-resource.services.ai.azure.com`. Do not include the portal's `/api/projects/<name>` path.
* **`deployment`** — the deployment name from your Azure/Foundry portal. On Azure the deployment name *is* the model, so no separate `model` field is needed.

Two authentication modes are supported, and the mode is **auto-detected** from the credentials you provide:

| Mode              | Fields to set                             |
| ----------------- | ----------------------------------------- |
| API key           | `token`                                   |
| Service principal | `tenant-id`, `client-id`, `client-secret` |

```yaml
  foundry:
    host: https://<resource>.services.ai.azure.com
    deployment: gpt-4o
    # API key:
    token: ${FOUNDRY_API_KEY}
    # or service principal (set these instead of token):
    tenant-id:     ${AZURE_TENANT_ID}
    client-id:     ${AZURE_CLIENT_ID}
    client-secret: ${AZURE_CLIENT_SECRET}
```

For service-principal auth the application needs a role assignment on the resource (`Cognitive Services User` or `Azure AI User`). Entra ID / managed-identity authentication is not yet supported.

## Custom / OpenAI-compatible

The Custom / OpenAI-compatible provider uses your own model, as long as it is reachable through an OpenAI-compatible API. Use it for a corporate gateway (LiteLLM, Azure API Management…) or a self-hosted server (vLLM, Ollama…). The real OpenAI integration stays under `openai`.

Select it with `ai-agent: openai_compatible` (underscore) and configure it in the `openai-compatible` block (hyphen):

| Field                                  | Required | Description                                                                                                                            |
| -------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `host`                                 | Yes      | Base URL, ending in the version path (e.g. `https://llm.example.com/v1`).                                                              |
| `model`                                | Yes      | Model name as the server expects it.                                                                                                   |
| `token`                                | No       | API key. Sent as `Authorization: Bearer <token>`.                                                                                      |
| `api`                                  | No       | `chat` (`/chat/completions`, default) or `responses` (OpenAI Responses API). Most gateways and self-hosted servers only expose `chat`. |
| `auth-header`, `auth-scheme`           | No       | Header that carries the token (default `Authorization`) and the prefix before it (default `Bearer`; `""` sends the token alone).       |
| `headers`                              | No       | Extra headers sent with every request.                                                                                                 |
| `query`                                | No       | Extra query parameters added to every request URL.                                                                                     |
| `max-tokens`, `temperature`, `timeout` | No       | Max tokens in the answer, temperature (not sent unless set) and read timeout in seconds.                                               |

A missing `host` or `model` stops the AI command with an error that names the missing field.

Corporate gateway (Azure OpenAI behind Azure API Management):

```yaml
ai-agent: openai_compatible
ai-agents:
  openai-compatible:
    host:  https://my-apim.azure-api.net/openai/deployments/gpt-4o
    model: gpt-4o
    auth-header: api-key
    auth-scheme: ""
    token: ${AZURE_OPENAI_API_KEY}
    headers:
      Ocp-Apim-Subscription-Key: ${APIM_SUBSCRIPTION_KEY}
    query:
      api-version: "2024-10-21"
```

Self-hosted server (Ollama; for vLLM use its `/v1` URL the same way):

```yaml
ai-agent: openai_compatible
ai-agents:
  openai-compatible:
    host:  http://ollama.internal:11434/v1
    model: llama3.1:70b
```

### Platform integration

You can also configure it for your account in **Settings → Integrations → AI Models** by selecting **Custom / OpenAI-compatible**. The endpoint URL and model are required; the API key, API flavour, auth header and scheme, extra headers, query parameters, max tokens, temperature and timeout are optional. Values must be literals (environment-variable references are not accepted), and the API key and extra headers are stored encrypted. Use the connection test to check the settings, and `ai-agent: global` in the scanner to use the integration.

The platform only accepts hosts that resolve to public addresses. In on-premise deployments, the operator can allow models inside the private network by listing them in the `integrations.allowlist.ai_models` server property (in `override.properties`), as a comma-separated list of IPs, CIDR networks, host names and `*.domain` patterns:

```properties
integrations.allowlist.ai_models=10.0.0.0/8,llm.corp.local,*.ai.corp.local
```

Private hosts that are not on the list are rejected. Tenant administrators cannot change this setting.

For **AI Triage**, both files are consulted on a **per-field** basis:

| Source                                                          | Precedence               |
| --------------------------------------------------------------- | ------------------------ |
| `xygenibot.yml` — `sast.ai-agents`, `sast.ai-remediation-agent` | Higher (consulted first) |
| `xygeni.yml` — `ai-agents`, `ai-agent`                          | Lower (fallback)         |
| Defaults shipped with the scanner                               | Lowest                   |

When both files declare the same field, the value in `xygenibot.yml` wins. The corresponding field in `xygeni.yml` is consulted only if `xygenibot.yml` does not declare it (or does not exist). Resolution is per field: a project that declares `sast.ai-remediation-agent` in `xygenibot.yml` but no `sast.ai-agents` block can still rely on `ai-agents` in `xygeni.yml` for the per-provider settings, and vice versa.

For **Xygeni Bot auto-remediation** (`xygeni scan --auto-remediate`), `xygenibot.yml` remains the source of truth — `xygeni.yml` is not consulted for that flow.

## Moving AI Triage configuration to `xygeni.yml`

To keep all scanner configuration in a single file, you can move the AI Triage settings to `xygeni.yml`. Because `xygenibot.yml` takes precedence, the move requires both steps:

1. **Remove** `sast.ai-agents` and `sast.ai-remediation-agent` from `xygenibot.yml` (or remove `xygenibot.yml` entirely if it is not needed for auto-remediation).
2. **Add** the equivalent top-level `ai-agents` block and `ai-agent` key to `xygeni.yml`.

If `xygenibot.yml` still declares the fields, AI Triage will continue to read them from there even after `xygeni.yml` is updated.

If you keep both files (for example, because Xygeni Bot auto-remediation is in use), `xygenibot.yml` remains the effective source of truth for AI Triage and there is no need to duplicate the values in `xygeni.yml`.

## Environment-variable indirection

Tokens, hosts, and models can reference environment variables in either file. The same resolution applies:

```yaml
token: ${OPENAI_API_KEY}                        # required env var
host:  ${OPENAI_HOST:https://api.openai.com/v1} # optional, with default
```

Tokens are resolved through Xygeni's secure token-fetch helper; do not commit raw tokens to either file.

## Validation

When the resolved agent (`sast.ai-remediation-agent` from `xygenibot.yml`, or `ai-agent` from `xygeni.yml` when falling back) maps to a provider whose `ai-agents.<provider>` block is missing required fields — for example, the resolved agent is `openai` but `ai-agents.openai.token` is empty after env-var expansion — AI Triage fails fast with an error pointing at the file and field that should have been present.

## Related

* [AI Triage](/xygeni-administration/platform-administration/projects-management/ai-triage.md) — feature overview, UI flows, scan-time and CLI usage.
* [AI Triage (CLI)](/xygeni-scanner-cli/xygeni-cli-overview/cli-utils/ai-triage.md) — `xygeni util ai-triage` reference, including the `--bot-config` flag.
* [Xygeni Bot](/xygeni-products/scan-management/xygeni-bot.md) — auto-remediation flow and full `xygenibot.yml` reference.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.xygeni.io/xygeni-products/scan-management/ai-agents-configuration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
