Skip to content

feat(aicore): clear AICORE_CLIENT_SECRET after token acquisition (AFSDK-4291) - #257

Draft
tiagoek wants to merge 1 commit into
feat/aicore-transparent-tlsfrom
feat/aicore-clear-client-secret
Draft

feat(aicore): clear AICORE_CLIENT_SECRET after token acquisition (AFSDK-4291)#257
tiagoek wants to merge 1 commit into
feat/aicore-transparent-tlsfrom
feat/aicore-clear-client-secret

Conversation

@tiagoek

@tiagoek tiagoek commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Disclaimer: Do not include SAP-internal or customer-specific information in this PR (e.g. internal system URLs, customer names, tenant IDs, or confidential configurations). This is a public repository.

Description

Stacked on #256 — merge that PR first, then retarget this one to main.

Tracking: AFSDK-4413 / HASI2026203 (CVE 9.9)

After the first successful litellm.completion() / litellm.acompletion() call, AICORE_CLIENT_SECRET is removed from os.environ. At that point LiteLLM has already captured the secret inside its token creator closure and no longer reads it from the environment. Removing it minimises the window of exposure to child processes and container introspection APIs.

Behaviour details


⚠️ BREAKING CHANGE

AICORE_CLIENT_SECRET is removed from os.environ after the first successful completion call.

Code that reads os.environ["AICORE_CLIENT_SECRET"] after calling completion() or acompletion() will receive a KeyError (or empty string via .get()).

Affected pattern:

set_aicore_config()
completion(...)                              # secret cleared here
secret = os.environ["AICORE_CLIENT_SECRET"]  # ❌ KeyError after this PR

Known affected agents — migration required before this PR merges:

Agent File Pattern
PMDRA / skills agent PMDRA/skills_agent.py reads AICORE_CLIENT_SECRET from env post-completion()
Billing anomaly agent billing-anomaly/_credentials.py reads AICORE_CLIENT_SECRET from env post-completion()
Finance agent file path TBD (scan in progress) manual AI Core credential rewrite, bypasses SDK

Issues have been opened in the respective repos with the migration path below. This PR stays draft until all three confirm migration or provide a timeline.

Migration path:

Remove any code that reads AICORE_CLIENT_SECRET directly from os.environ after set_aicore_config() / completion(). The secret is an implementation detail of the LiteLLM integration — application code should not depend on it.

# Before (breaks after this PR)
set_aicore_config()
response = completion(model="sap/gpt-4o", messages=[...])
secret = os.environ["AICORE_CLIENT_SECRET"]  # ❌

# After (correct pattern)
set_aicore_config()
response = completion(model="sap/gpt-4o", messages=[...])
# Do not read AICORE_CLIENT_SECRET — let the SDK manage it

If the secret is needed for a purpose outside LiteLLM (e.g. a separate HTTP call), read it directly from the mounted secret volume at /etc/secrets/appfnd/aicore/<instance>/clientsecret before calling set_aicore_config().


Related Issues

  • AFSDK-4413 — clear client_secret BLI
  • HASI2026203 (CVE 9.9 — internal tracking)

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Bug fix
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Dependency update

How to Test

python -m pytest tests/aicore/unit/ -v
# Expected: 73 passed

Manual verification:

  1. Call set_aicore_config() followed by a successful completion() call
  2. Assert os.environ.get("AICORE_CLIENT_SECRET") is None
  3. Make a second completion() call — verify it succeeds (LiteLLM uses its cached token)
  4. Simulate credential rotation: secret file updated, next call triggers AuthenticationError
  5. Verify completion() recovers: reloads credentials, clears secret again after retry

Checklist

  • I have read the Contributing Guidelines
  • I have verified that my changes solve the issue
  • I have added/updated automated tests to cover my changes
  • All tests pass locally
  • I have verified that my code follows the Code Guidelines
  • I have added type hints for all public APIs
  • My code does not contain sensitive information (credentials, tokens, etc.)
  • I have followed Conventional Commits for commit messages

Additional Notes

This is the second in a series of stacked PRs addressing credential exposure in the aicore module:

  1. feat(aicore): transparent TLS mode and reactive credential reload #256 — transparent TLS mode + reactive reload on AuthenticationError
  2. This PR — clear CLIENT_SECRET from env after token acquisition
  3. feat(aicore): transparent proxy routing and BTP Destination Service mode (Option 3) #271 — Option 3: proxy routing + BTP Destination Service mode

When #256 is merged to main, this PR should be retargeted from feat/aicore-transparent-tls to main before merging.

… acquisition

After the first successful litellm.completion() call, AICORE_CLIENT_SECRET is
removed from os.environ. LiteLLM has captured the secret inside its token
creator closure at that point and no longer reads from the environment. Removing
it minimises the exposure window to child processes and container introspection
APIs (AFSDK-4291 / HASI2026203 SEC-309).

The flag is reset when credentials are reloaded (credential rotation flow) so
the secret is cleared again after the retry succeeds. No-op in transparent TLS
mode where the secret was never written.

Relates-to: AFSDK-4291
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