Skip to content

feat(llms): add OCI Generative AI API key authentication for OciGenAiConfig - #266

Open
fede-kamel wants to merge 2 commits into
oracle:mainfrom
fede-kamel:feat/oci-genai-api-key-auth
Open

fede-kamel wants to merge 2 commits into
oracle:mainfrom
fede-kamel:feat/oci-genai-api-key-auth

Conversation

@fede-kamel

Copy link
Copy Markdown
Member

Closes #265.

Adds a fifth OciClientConfig authentication type for OciGenAiConfig: an OCI Generative AI API key, sent as a bearer token to the OpenAI-compatible API of the service. Today the four OciClientConfig specialisations all describe OCI IAM principals whose requests the OCI SDK signs, so an agent meant to run with a Generative AI API key (the credential shape used by the stock openai SDK, LiteLLM, opencode / models.dev provider entries and OpenRouter-style routers) cannot be expressed in Agent Spec, and falling back to OpenAiCompatibleConfig loses the OCI semantics (compartment_id, serving_mode, provider, api_type).

Changes

class OciClientConfigWithGenAiApiKey(OciClientConfig):
    api_key: SensitiveField[Optional[str]] = None   # runtimes may read OCI_GENAI_API_KEY instead
    auth_type: Literal["GENAI_API_KEY"] = "GENAI_API_KEY"
  • service_endpoint is inherited (the regional Generative AI inference endpoint); the base auth_type literal gains "GENAI_API_KEY".
  • api_key is a sensitive field, exported as a $component_ref placeholder like GeminiAIStudioAuthConfig.api_key, and optional so runtimes can load it from OCI_GENAI_API_KEY.
  • Minimum Agent Spec version 26.4.0, with accepted and rejected export-version tests.
  • Registered in _component_registry.py; language specification (component and sensitive-fields table), regenerated 26.4.0 JSON schema, API reference, changelog, provider how-to and security guidance.
  • OciAgent rejects this client configuration with a clear error: Generative AI API keys only authorize model inference, not the Agents service.
  • The LangGraph adapter rejects it with NotImplementedError pointing to the OpenAI-compatible runtimes (langchain-oci has no bearer path).
  • TypeScript parity in tsagentspec: zod schema, factory, registry entries, sensitive field, version gate, tests.

Adapter execution is not part of this PR: the shared OpenAI-compatible client helper of #264 (AutoGen, Agent Framework, OpenAI Agents) is the natural place to turn this configuration into a plain bearer openai client with no request signing and no oci-genai-auth dependency, and a follow-up commit there adds it once this component exists.

Behaviour of the credential, verified live

The design follows what the service does, checked against OCI Generative AI (us-chicago-1) with the stock openai SDK and a Generative AI API key:

  • Authorization: Bearer <key> against <service_endpoint>/openai/v1/chat/completions works for Meta Llama, xAI Grok and OpenAI gpt-oss models with no opc-compartment-id header (the key is compartment-scoped): plain completions with usage, streaming and tool calls all succeed.
  • Keys are regional and compartment-scoped; Oracle documents them for testing and early development and IAM principals for production, which the security guide now states.
  • A key created before an IAM policy authorized it kept returning 401 long after the policy existed, while a key created after the policy worked immediately. The how-to therefore says to create the policy first, then the key.

Tests

  • tests/test_ocigenaiconfig.py, tests/test_ociagent.py, tests/serialization/test_oci_genai_models.py, tests/serialization/test_sensitive_fields.py, tests/adapters/langgraph/llms/test_ocigenai_conversion.py: round trip, sensitive-field placeholder, version gating, OciAgent and LangGraph rejection.
  • tsagentspec: oci-client-config, sensitive-fields, version-gates suites.
  • black, isort, flake8 copyright rule, mypy (strict) and the core suite in CI form (SKIP_LLM_TESTS=1) pass locally on Python 3.12.

@fede-kamel
fede-kamel requested a review from a team September 14, 2026 20:51
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Sep 14, 2026
@cesarebernardis

Copy link
Copy Markdown
Member

Hi @fede-kamel, thank you for the contribution. This looks like a relevant addition to the language spec, I will discuss a couple of minor details with the team, and I'll get back to you as soon as possible with our feedback.

@cesarebernardis

Copy link
Copy Markdown
Member

@fede-kamel we agreed that the proposal is good.

We would just ask for one small modification: the OciClientConfig is used also in the OciAgent, that does not seem to accept a GenAI API key as authentication at the moment. Therefore, we think it's a good idea to forbid/reject configurations that have an OciClientConfigWithGenAiApiKey in an OciAgent in the SDKs, and to clarify this constraint in the language specification.

…Config

Add the OciClientConfigWithGenAiApiKey client configuration (auth_type
GENAI_API_KEY): an OCI Generative AI API key sent as a bearer token to the
OpenAI-compatible API of the service, with no OCI configuration file and no
request signing. The key is a sensitive field that runtimes may also read
from the OCI_GENAI_API_KEY environment variable.

- register the component, extend the OciClientConfig auth_type literal and
  require Agent Spec 26.4.0 (accepted and rejected version tests)
- reject the configuration in OciAgent (keys only authorize inference) and
  in the LangGraph adapter (langchain-oci has no bearer path)
- language specification, JSON schema, changelog, API reference, how-to and
  security guidance
- TypeScript mirror: zod schema, factory, registry, sensitive field, version
  gate and tests

Refs oracle#265

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
…igurations

The OciAgent section of the language specification now requires an
IAM-based OciClientConfig and declares OciClientConfigWithGenAiApiKey
invalid for OciAgent, matching the validator in pyagentspec. The
changelog entry mentions the constraint.

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
@fede-kamel

Copy link
Copy Markdown
Member Author

Thanks @cesarebernardis. The rejection is already in this PR, and bba2ae6 makes the constraint explicit in the language specification:

  • SDK: OciAgent._validate_client_config_can_reach_the_agents_service (pyagentspec/src/pyagentspec/ociagent.py) raises a ValidationError when client_config is an OciClientConfigWithGenAiApiKey, covered by tests/test_ociagent.py::test_oci_agent_rejects_genai_api_key_client_config. tsagentspec has no OciAgent component, so there is nothing to enforce on that side.
  • Language spec: the OciAgent section now states that client_config must use one of the IAM-based authentication types (SECURITY_TOKEN, INSTANCE_PRINCIPAL, RESOURCE_PRINCIPAL, API_KEY) and that OciClientConfigWithGenAiApiKey is invalid for an OciAgent and must be rejected by SDKs. This complements the note already present in the OciClientConfigWithGenAiApiKey section. The changelog entry mentions the constraint too.

The branch is also rebased on main.

One side note: loading such a configuration through AgentSpecDeserializer is rejected as well, but today the failure surfaces as TypeError: ValueError: 'error' required in context from the deserializer instead of the validator's message. That is a pre-existing issue in how the deserializer rebuilds value_error entries (it affects every @model_validator_with_error_accumulation error), unrelated to this PR; I will open a separate fix for it.

@fede-kamel
fede-kamel force-pushed the feat/oci-genai-api-key-auth branch from 7fd7df2 to bba2ae6 Compare October 1, 2026 14:00
@fede-kamel

Copy link
Copy Markdown
Member Author

LGTM. Adding OCI Generative AI API key auth to is well-documented with live verification. TypeScript and Python parity is consistent. Ready for maintainer review.

@fede-kamel fede-kamel left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Clean feature addition for OCI Generative AI API key auth.

Design is correct

  • New OciClientConfigWithGenAiApiKey with api_key: SensitiveField[Optional[str]] and auth_type: Literal["GENAI_API_KEY"] — consistent with existing auth types.
  • Optional api_key so runtimes can load from OCI_GENAI_API_KEY env var — good for CI/CD and containers.
  • Proper sensitive field handling with $component_ref placeholder in exports.
  • OciAgent correctly rejects this config (API keys can't do Agents service IAM auth).
  • LangGraph adapter rejects with NotImplementedError pointing to OpenAI-compatible runtimes.

TypeScript parity is present with zod schema, factory, registry entries, sensitive field, version gate, and tests.

Version gating at 26.4.0 with accepted/rejected tests — correct approach for spec evolution.

Scope is clear: execution in adapters is deferred to the follow-up PR (#264), which is the right place since the shared OpenAI-compatible client helper is where the bearer token actually gets sent.

No blockers.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OciClientConfig: support OCI Generative AI API keys (Bearer) as an authentication type

2 participants