Skip to content

feat(api): add OrcaRouter Cyber Inference as a named BYOK provider with live model catalog - #35

Open
putraperdana1207-pixel wants to merge 1 commit into
awarexone:mainfrom
putraperdana1207-pixel:orcarouter/task-11766
Open

putraperdana1207-pixel wants to merge 1 commit into
awarexone:mainfrom
putraperdana1207-pixel:orcarouter/task-11766

Conversation

@putraperdana1207-pixel

Copy link
Copy Markdown

What this adds

AXGuard's local Security Intelligence API already has a real BYOK provider seam (engines/api/providers/factory.py: PROVIDER_BASE_URLS + OpenAICompatProvider) consumed by the one model call in the tree — enrichment=llm in engines/api/services/pipeline.py — plus the GitHub bot's ai.provider config. There was no first-class provider for teams that run authorized, scoped security inference. This PR adds OrcaRouter Cyber Inference as a named provider (own adapter, own config, own docs), not an any-endpoint passthrough.

Provider and auth

AXGuard is a CLI + local FastAPI/MCP tool with no OAuth/PKCE login seam (GitHub App auth is a private key; there is no browser-embedded UI), so this integration is API key only, following the repo's existing credential rules: key from AXGUARD_AI_API_KEY (or ai.api_key_env) only, never from repo files, never logged. orcarouter is also a literal name in PROVIDER_BASE_URLS next to openai, groq, … so the user-selected provider is visible in config and axguard api status.

Surface Change
engines/api/providers/orcarouter.py OrcaRouterProvider — base https://api.orcarouter.ai/v1, default orcarouter/auto, fallback orcarouter/fusion, cyber tier orcacyber-ultra-1.0 / orcacyber-zero-1.5 / orcacyber-zero-1.0; credential masking (sk-orca-t…gh), error scrubbing so keys never reach logs or raw, degraded catalog with a 6-entry verified seed
engines/api/providers/catalog.py live GET /v1/models + capability filters
engines/api/routes GET /v1/models?capability=&modality= — key stays server-side; /v1/health gains display_name, base_url, masked credential_hint
engines/api/cli.py axguard api models [--capability] [--modality] [--check]
engines/github/config.py ai.provider: orcarouter → OrcaRouter base URL + orcarouter/auto defaults; explicit AXGUARD_AI_BASE_URL / ai.model win; literal keys in .axguard.yml are still ignored
docs docs/api/orcarouter.md, provider tables in docs/api/providers.md, docs/github/ai-providers.md, docs/api/overview.md

API endpoints touched: POST /v1/projects/{id}/scans (enrichment gate + the only completion call) and the new GET /v1/models. The GitHub bot path (resolve_ai_credentials) is wired but still inert in engines/github/pipeline.py (_ = ai — no model call today); this PR does not invent one. The CLI and MCP surfaces make no model calls themselves.

Model dropdown from the real catalog

The selector is GET /v1/models, fetched per capability from {base_url}/models; ids keep their vendor/model namespace. Filters use directory metadata only:

  • chat (default): supported_endpoint_types ∩ {openai, anthropic, gemini, openai-response}; image-generation, openai-video, jina-rerank and embeddings endpoints are excluded; unknown endpoint types (e.g. systemone) fail closed, and entries with no endpoint metadata at all are treated as chat only when nothing marks them as a non-text generator.
  • chat&modality=image|audio|video: additionally requires architecture.input_modalities to declare the modality; undeclared models are excluded (fail closed).
  • embedding / image / video / rerank: exact embeddings / image-generation / openai-video / jina-rerank endpoint types.

On fetch failure the response is "degraded": true, "catalog_source": "seed" with the small verified seed above (GPT-5.5 keeps low/medium/high/xhigh); a successful live result is never mixed with the seed, and the seed is never a free-text fallback. axguard api models --check exits non-zero when degraded.

This repo has no multimodal input path (findings enrichment sends text summaries only), so no multimodal dropdown is required; the modality filter exists and is tested for callers that add one.

Evidence

Tests (tests/test_orcarouter_provider.py, tests/test_orcarouter_api.py, 39 tests incl. one opt-in live):

  • registry: get_provider(provider="orcarouter") returns OrcaRouterProvider, default orcarouter/auto, base https://api.orcarouter.ai/v1; status masks the key.
  • catalog: fixture covering text-only, image-input chat, embedding, image generation, video and rerank → each capability filter; missing-modality chat models excluded from the image dropdown; unknown endpoint types excluded from chat, structured {type: …} endpoint entries accepted.
  • API: /v1/models from the live (local fake server) path, Authorization: Bearer used and key absent from the response; 422 on unknown capability; 404 for providers without a catalog; degraded seed on 401/network.
  • completion: POST /v1/chat/completions through the provider with orcarouter/auto and an explicit cyber model id; 401 body scrubbed.
  • live: with the verification key, GET https://api.orcarouter.ai/v1/models returned a live catalog (190 chat-capable models) and a completion succeeded through the provider. The key is not yet unlocked for the cyber tier (orcacyber-ultra-1.0, orcacyber-zero-1.5, orcarouter/auto returned model_access_denied), so the wiring proof used a public model the key can call. That is a key-entitlement result, not a wiring result.

Local run: pytest -q tests/test_orcarouter_provider.py tests/test_orcarouter_api.py tests/test_api.py tests/test_github_security.py → 63 passed; python scripts/validate_skills.py → OK. Full-suite context under Python 3.11 in this environment: engines/report.py uses an f-string form that only parses on newer interpreters, so 8 modules that import it fail to collect plus 2 CLI smoke tests — unchanged on base, and CI pins Python 3.12; the separate live result above was verified independently on the same code. The opt-in live test timed out once during the full run on a cold connection.

Why this provider

Cyber models for your red team, gateway controls for your blue team: red-side adversary and attack-path work on OrcaCyber Ultra / Zero, blue-side pre-ship review, triage and fix verification on the same endpoint. It lets verified security teams send authorized, scoped security-inference requests that general gateways tend to reject or silently downgrade. Provider page: https://www.orcarouter.ai/cyber · cyber catalog: https://www.orcarouter.ai/models?tier=cyber


OrcaRouter is an OpenAI-compatible AI gateway that routes many providers behind one endpoint. It also runs gateway-level, zero-trust security for AI agents on the same endpoint — screening every prompt/response and governing every tool call on a default-deny basis, with no application code changes.

I'm an engineer on the OrcaRouter team.

…th live model catalog

Signed-off-by: putraperdana1207-pixel <putraperdana1207-pixel@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.

1 participant