feat(aicore): transparent proxy routing and BTP Destination Service mode (Option 3) - #271
Draft
tiagoek wants to merge 1 commit into
Draft
feat(aicore): transparent proxy routing and BTP Destination Service mode (Option 3)#271tiagoek wants to merge 1 commit into
tiagoek wants to merge 1 commit into
Conversation
…ce mode Implements Option 3 from the AFSDK-4306 security alignment meeting: SDK absorbs all routing complexity so agent code is identical in all environments. The deployer controls routing by choosing which env vars to inject. Two new modes in set_aicore_config(): Proxy mode (AICORE_PROXY_URL set): - Routes all LiteLLM calls through an external LiteLLM proxy - Sets litellm.api_base / litellm.api_key globally - Rewrites sap/<model> → litellm_proxy/<model> transparently in completion() and acompletion() wrappers (including on auth-error retry) - No AI Core credentials written to the process environment - JWT never reaches the agent process (proxy handles OAuth) Destination mode (AICORE_DESTINATION_NAME set): - Loads AI Core credentials at startup from a named BTP Destination Service destination via the existing sap_cloud_sdk.destination client - Deployer only injects Destination Service binding — AI Core client_secret is never in the K8s Secret, only in BTP Destination Service - Combined with _clear_client_secret() (PR #257), the secret is removed from env after the first successful LiteLLM call Direct mode (neither set): existing behaviour unchanged, including transparent TLS (AICORE_TRANSPARENT_TLS). Adds 30 unit tests covering both new modes and all edge cases. AFSDK-4306
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements Option 3 from the AFSDK-4306 security alignment meeting (Tiago Kochenborger + Thiago Bohn + Felipe Morais, 2026-08-14):
Stacked on: #257 (
feat/aicore-clear-client-secret)What changed
set_aicore_config()now detects the routing mode from environment variables (priority: proxy > destination > direct):Proxy mode —
AICORE_PROXY_URLsetRoutes all LiteLLM calls through an external LiteLLM proxy (e.g. ADR 0031):
litellm.api_baseandlitellm.api_key(virtual key) globallysap/<model>→litellm_proxy/<model>transparently incompletion()andacompletion(), including on auth-error retry# Deployer injects these; agent code unchanged AICORE_PROXY_URL=https://litellm-proxy.cluster.svc AICORE_PROXY_VIRTUAL_KEY=sk-virtual-xxxDestination mode —
AICORE_DESTINATION_NAMEsetLoads AI Core credentials at startup from a named BTP Destination Service destination:
sap_cloud_sdk.destinationclient — no new dependenciesAICORE_CLIENT_SECRETnever needs to be in the K8s Secret — it lives in BTP Destination Service_clear_client_secret()(PR feat(aicore): clear AICORE_CLIENT_SECRET after token acquisition (AFSDK-4291) #257), the secret is removed from env after the first successful LiteLLM callAuthenticationError,reload_aicore_credentials()re-fetches fresh credentials from the Destination ServiceThe destination must be configured with
OAuth2ClientCredentialsand the app must have the Destination Service technical-user scope so thatclientId/clientSecret/tokenServiceURLare returned by the API.Direct mode (unchanged)
Neither env var set → existing behaviour: load from mounted K8s secret or env vars.
AICORE_TRANSPARENT_TLSstill works within direct mode.Agent code — identical in all modes
Security coverage
CLIENT_SECRETin K8s SecretCLIENT_SECRETin process envTests
30 new unit tests across two new test classes in each file:
TestSetAICoreConfigProxyMode(7 tests) — mode detection, litellm globals, precedence, filtering still appliedTestSetAICoreConfigDestinationMode(9 tests) — URL extraction, credentials, resource group, error casesTestCompletionProxyModeAliasing(4 tests) — model rewrite on call and retry, no-op when inactiveTestACompletionProxyModeAliasing(2 tests) — async pathFull suite: 163 passed, 4 skipped (integration tests requiring real BTP).
Related