Skip to content

Add tutorial: OpenAI Workload Identity integration with Agent ID - #6281

Open
sajitha-tj wants to merge 3 commits into
wso2:masterfrom
sajitha-tj:docs/agent-id-openai-authentication
Open

Add tutorial: OpenAI Workload Identity integration with Agent ID#6281
sajitha-tj wants to merge 3 commits into
wso2:masterfrom
sajitha-tj:docs/agent-id-openai-authentication

Conversation

@sajitha-tj

Copy link
Copy Markdown

Purpose

Adding a step by step tutorial that describes how to integrate OpenAI Workload Identity Federation (WIF) with Agent ID and use that to call OpenAI APIs. Also fixed some issues in the Claude WIF integration tutorial.

Related Issues

Test environment

Security checks

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6abf729a-9299-478e-91d2-4c2eff0af9ab

📥 Commits

Reviewing files that changed from the base of the PR and between 654e963 and 12a8ba8.

📒 Files selected for processing (3)
  • en/identity-server/7.2.0/docs/tutorials/index.md
  • en/identity-server/next/docs/tutorials/index.md
  • en/includes/tutorials/agent-id-openai-authentication.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • en/identity-server/next/docs/tutorials/index.md
  • en/identity-server/7.2.0/docs/tutorials/index.md
  • en/includes/tutorials/agent-id-openai-authentication.md

📝 Walkthrough

Walkthrough

Changes

The documentation adds an OpenAI workload identity federation tutorial across Asgardeo and Identity Server versions, wires it into navigation, and updates Claude authentication examples and endpoint placeholders.

Agent authentication documentation

Layer / File(s) Summary
OpenAI tutorial setup and authentication flow
en/includes/tutorials/agent-id-openai-authentication.md
Documents agent registration, application setup, OpenAI workload identity provider configuration, service account mapping, and JWT token exchange.
OpenAI shell and Python examples
en/includes/tutorials/agent-id-openai-authentication.md
Adds shell and Python SDK examples with token caching, refresh, OpenAI client wiring, and follow-on guidance.
OpenAI page wrappers and navigation
en/asgardeo/docs/tutorials/..., en/identity-server/*/docs/tutorials/..., en/asgardeo/mkdocs.yml, en/identity-server/*/mkdocs.yml
Adds templated tutorial pages and index/navigation entries across supported product versions.
Claude authentication example corrections
en/includes/tutorials/agent-id-claude-authentication.md, en/identity-server/*/docs/tutorials/agent-id-claude-authentication.md
Updates configuration and token-provider examples, adds the HTTPS prerequisite, corrects terminology, and replaces localhost endpoint values with a domain placeholder.

Suggested reviewers: ayshsandu

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description misses the required Related PRs section, leaves Test environment blank, and leaves security checks unchecked. Add a Related PRs section, fill in the test environment used, and complete the security checklist items.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the new tutorial and its Agent ID/OpenAI Workload Identity focus.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md`:
- Line 2: Update api_base_path in
en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md:2,
en/identity-server/7.3.0/docs/tutorials/agent-id-claude-authentication.md:2, and
en/identity-server/next/docs/tutorials/agent-id-claude-authentication.md:2 to
use the complete HTTPS placeholder https://<your-domain>.

In `@en/includes/tutorials/agent-id-openai-authentication.md`:
- Around line 147-183: Update token_provider to support Python 3.9 by importing
Optional and replacing the str | None annotation for cached_token with
Optional[str]. Replace the scopes list default with None, annotate it
appropriately, and initialize the scopes list inside token_provider when no
value is provided.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 198de691-2796-489f-8912-25c8b8062b8e

📥 Commits

Reviewing files that changed from the base of the PR and between c0ffcc9 and 654e963.

📒 Files selected for processing (17)
  • en/asgardeo/docs/tutorials/agent-id-openai-authentication.md
  • en/asgardeo/docs/tutorials/index.md
  • en/asgardeo/mkdocs.yml
  • en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md
  • en/identity-server/7.2.0/docs/tutorials/agent-id-openai-authentication.md
  • en/identity-server/7.2.0/docs/tutorials/index.md
  • en/identity-server/7.2.0/mkdocs.yml
  • en/identity-server/7.3.0/docs/tutorials/agent-id-claude-authentication.md
  • en/identity-server/7.3.0/docs/tutorials/agent-id-openai-authentication.md
  • en/identity-server/7.3.0/docs/tutorials/index.md
  • en/identity-server/7.3.0/mkdocs.yml
  • en/identity-server/next/docs/tutorials/agent-id-claude-authentication.md
  • en/identity-server/next/docs/tutorials/agent-id-openai-authentication.md
  • en/identity-server/next/docs/tutorials/index.md
  • en/identity-server/next/mkdocs.yml
  • en/includes/tutorials/agent-id-claude-authentication.md
  • en/includes/tutorials/agent-id-openai-authentication.md

@@ -1,4 +1,4 @@
{% set product_name = "WSO2 Identity Server" %}
{% set api_base_path = "https://localhost:9443" %}
{% set api_base_path = "<your-domain>" %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use a complete HTTPS URL for api_base_path.

The shared tutorial uses this value for Python base_url and OAuth/JWKS endpoint construction. The current hostname-only placeholder generates invalid URLs; use https://<your-domain> in every Identity Server wrapper.

  • en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md#L2-L2: change the placeholder to https://<your-domain>.
  • en/identity-server/7.3.0/docs/tutorials/agent-id-claude-authentication.md#L2-L2: change the placeholder to https://<your-domain>.
  • en/identity-server/next/docs/tutorials/agent-id-claude-authentication.md#L2-L2: change the placeholder to https://<your-domain>.
Proposed fix
-{% set api_base_path = "<your-domain>" %}
+{% set api_base_path = "https://<your-domain>" %}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{% set api_base_path = "<your-domain>" %}
{% set api_base_path = "https://<your-domain>" %}
📍 Affects 3 files
  • en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md#L2-L2 (this comment)
  • en/identity-server/7.3.0/docs/tutorials/agent-id-claude-authentication.md#L2-L2
  • en/identity-server/next/docs/tutorials/agent-id-claude-authentication.md#L2-L2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md` at
line 2, Update api_base_path in
en/identity-server/7.2.0/docs/tutorials/agent-id-claude-authentication.md:2,
en/identity-server/7.3.0/docs/tutorials/agent-id-claude-authentication.md:2, and
en/identity-server/next/docs/tutorials/agent-id-claude-authentication.md:2 to
use the complete HTTPS placeholder https://&lt;your-domain&gt;.

Comment on lines +147 to +183
import asyncio
import time
from asgardeo import AsgardeoConfig
from asgardeo_ai import AgentAuthManager, AgentConfig
from openai import OpenAI
from openai.auth import SubjectTokenProvider

# {{product_name}} configuration
config = AsgardeoConfig(
base_url="{{ api_base_path }}",
client_id="<your-client-id>",
client_secret="<your-client-secret>",
redirect_uri="<your-redirect-uri>",
)

# Agent credentials
agent_config = AgentConfig(
agent_id="<your-agent-id>",
agent_secret="<your-agent-secret>",
)

def token_provider(
identity_provider_config: AsgardeoConfig,
agent_cfg: AgentConfig,
scopes=["openid", "profile"]
) -> SubjectTokenProvider:
"""
Provide JWT access token from {{product_name}} to OpenAI WIF.

It caches the token and refreshes automatically when expired.
The OpenAI SDK calls this function whenever it needs a
new token for the WIF exchange.
"""

EXPIRY_BUFFER_SECONDS = 60
cached_token : str | None = None
token_expiry : float = 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix Python 3.9 compatibility and mutable default argument.

  1. The str | None union type syntax requires Python 3.10+ (PEP 604), but the prerequisites state Python 3.9+. Using this in Python 3.9 will cause a SyntaxError. Please use Optional[str] from the typing module instead.
  2. Avoid using mutable objects (like lists) as default arguments in Python. Because the default object is evaluated once and shared across all calls, it can lead to unexpected behavior. Use None instead and initialize the list inside the function.
💡 Proposed fixes
 import asyncio
 import time
+from typing import Optional
 from asgardeo import AsgardeoConfig
 from asgardeo_ai import AgentAuthManager, AgentConfig
 from openai import OpenAI
 from openai.auth import SubjectTokenProvider
 
 # ... [snip] ...
 
 def token_provider(
         identity_provider_config: AsgardeoConfig,
         agent_cfg: AgentConfig,
-        scopes=["openid", "profile"]
+        scopes=None
     ) -> SubjectTokenProvider:
     """
     Provide JWT access token from {{product_name}} to OpenAI WIF.
 
     It caches the token and refreshes automatically when expired.
     The OpenAI SDK calls this function whenever it needs a
     new token for the WIF exchange.
     """
+    if scopes is None:
+        scopes = ["openid", "profile"]
 
     EXPIRY_BUFFER_SECONDS = 60
-    cached_token : str | None = None
+    cached_token : Optional[str] = None
     token_expiry : float = 0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import asyncio
import time
from asgardeo import AsgardeoConfig
from asgardeo_ai import AgentAuthManager, AgentConfig
from openai import OpenAI
from openai.auth import SubjectTokenProvider
# {{product_name}} configuration
config = AsgardeoConfig(
base_url="{{ api_base_path }}",
client_id="<your-client-id>",
client_secret="<your-client-secret>",
redirect_uri="<your-redirect-uri>",
)
# Agent credentials
agent_config = AgentConfig(
agent_id="<your-agent-id>",
agent_secret="<your-agent-secret>",
)
def token_provider(
identity_provider_config: AsgardeoConfig,
agent_cfg: AgentConfig,
scopes=["openid", "profile"]
) -> SubjectTokenProvider:
"""
Provide JWT access token from {{product_name}} to OpenAI WIF.
It caches the token and refreshes automatically when expired.
The OpenAI SDK calls this function whenever it needs a
new token for the WIF exchange.
"""
EXPIRY_BUFFER_SECONDS = 60
cached_token : str | None = None
token_expiry : float = 0
import asyncio
import time
from typing import Optional
from asgardeo import AsgardeoConfig
from asgardeo_ai import AgentAuthManager, AgentConfig
from openai import OpenAI
from openai.auth import SubjectTokenProvider
# {{product_name}} configuration
config = AsgardeoConfig(
base_url="{{ api_base_path }}",
client_id="<your-client-id>",
client_secret="<your-client-secret>",
redirect_uri="<your-redirect-uri>",
)
# Agent credentials
agent_config = AgentConfig(
agent_id="<your-agent-id>",
agent_secret="<your-agent-secret>",
)
def token_provider(
identity_provider_config: AsgardeoConfig,
agent_cfg: AgentConfig,
scopes=None
) -> SubjectTokenProvider:
"""
Provide JWT access token from {{product_name}} to OpenAI WIF.
It caches the token and refreshes automatically when expired.
The OpenAI SDK calls this function whenever it needs a
new token for the WIF exchange.
"""
if scopes is None:
scopes = ["openid", "profile"]
EXPIRY_BUFFER_SECONDS = 60
cached_token : Optional[str] = None
token_expiry : float = 0
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@en/includes/tutorials/agent-id-openai-authentication.md` around lines 147 -
183, Update token_provider to support Python 3.9 by importing Optional and
replacing the str | None annotation for cached_token with Optional[str]. Replace
the scopes list default with None, annotate it appropriately, and initialize the
scopes list inside token_provider when no value is provided.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant