Skip to content

feat(temporal): add workload identity authentication - #561

Closed
aringuyen3 wants to merge 3 commits into
mainfrom
VULN-2040/temporal-authentication
Closed

aringuyen3 wants to merge 3 commits into
mainfrom
VULN-2040/temporal-authentication

Conversation

@aringuyen3

@aringuyen3 aringuyen3 commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

#560

RetriggerView in GreptileConfidence Score: 3/5

Default authenticated connections should use TLS before this PR merges.

Fix All in CursorFindings

  1. P1 Security Tokens travel without encryption ▶
  2. P2 Cancelled startup skips cleanup ▶
  3. P2 Old clients keep refreshing ▶
Fix with agent prompt
### Issue 1
src/agentex/lib/core/clients/temporal/auth.py:98-100
When `TEMPORAL_AUTH_SCOPE` is set, both client factories omit `tls`, so this branch sends the Azure bearer token with `tls=False`. If the network does not provide separate encryption, someone watching the traffic can copy and reuse the token until it expires. Default authenticated connections to TLS, and require an explicit choice for plaintext connections.

**How this was verified:** Both factories pass connection options without `tls`, and `connect_temporal_client` adds `tls=False` alongside the token in `api_key`.

### Issue 2
src/agentex/lib/core/clients/temporal/auth.py:101-103
Cancelling startup during `credential.get_token` or `Client.connect` skips this cleanup because `asyncio.CancelledError` is not an `Exception`. No refresh session exists yet to close the credential, so startup timeouts can leave its HTTP resources open. Close the credential on cancellation as well, then re-raise it.

### Issue 3
src/agentex/lib/core/clients/temporal/auth.py:105-111
Each authenticated connection starts a task that holds its client and credential forever. Callers receive only the client and have no supported way to stop that task. Creating and discarding clients in the same event loop leaves every old session refreshing tokens and holding resources. Expose an async close operation and call it when the worker or application shuts down.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds Azure Workload Identity authentication when TEMPORAL_AUTH_SCOPE is set.

  • Temporal clients can use renewable Azure identity tokens.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Temporal client factory] --> B{TEMPORAL_AUTH_SCOPE set?}
    B -->|No| C[Connect with existing options]
    B -->|Yes| D[Get Azure token]
    D --> E[Connect with token; missing TLS becomes false]
    E --> F[Return client and start refresh task]
    F --> G[Wait until refresh time]
    G --> H{Get valid token?}
    H -->|Yes| I[Update client.api_key]
    H -->|No| J[Retry after 30 seconds]
    I --> G
    J --> H
Loading

Reviews (1) · Last reviewed commit: "test(temporal): import TLSConfig from te..." · Reviewed by Greptile

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​azure-identity@​1.27.097100100100100

View full report

@aringuyen3

Copy link
Copy Markdown
Contributor Author

Close because the test for #560 was triggered

@aringuyen3 aringuyen3 closed this Nov 2, 2026
Comment on lines +98 to +100
if authenticated_options.get("tls") is None:
authenticated_options["tls"] = False
client = await Client.connect(api_key=token.token, **authenticated_options)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 security Tokens travel without encryption

When TEMPORAL_AUTH_SCOPE is set, both client factories omit tls, so this branch sends the Azure bearer token with tls=False. If the network does not provide separate encryption, someone watching the traffic can copy and reuse the token until it expires. Default authenticated connections to TLS, and require an explicit choice for plaintext connections.

How this was verified: Both factories pass connection options without tls, and connect_temporal_client adds tls=False alongside the token in api_key.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/core/clients/temporal/auth.py
Line: 98-100

Comment:
**Tokens travel without encryption**

When `TEMPORAL_AUTH_SCOPE` is set, both client factories omit `tls`, so this branch sends the Azure bearer token with `tls=False`. If the network does not provide separate encryption, someone watching the traffic can copy and reuse the token until it expires. Default authenticated connections to TLS, and require an explicit choice for plaintext connections.

**How this was verified:** Both factories pass connection options without `tls`, and `connect_temporal_client` adds `tls=False` alongside the token in `api_key`.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Cursor Fix in Claude Code Fix in Codex

Comment on lines +101 to +103
except Exception:
await credential.close()
raise

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Cancelled startup skips cleanup

Cancelling startup during credential.get_token or Client.connect skips this cleanup because asyncio.CancelledError is not an Exception. No refresh session exists yet to close the credential, so startup timeouts can leave its HTTP resources open. Close the credential on cancellation as well, then re-raise it.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/core/clients/temporal/auth.py
Line: 101-103

Comment:
**Cancelled startup skips cleanup**

Cancelling startup during `credential.get_token` or `Client.connect` skips this cleanup because `asyncio.CancelledError` is not an `Exception`. No refresh session exists yet to close the credential, so startup timeouts can leave its HTTP resources open. Close the credential on cancellation as well, then re-raise it.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Cursor Fix in Claude Code Fix in Codex

Comment on lines +105 to +111
TemporalTokenSession(
client=client,
credential=credential,
scope=scope,
token=token,
).start()
return client

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Old clients keep refreshing

Each authenticated connection starts a task that holds its client and credential forever. Callers receive only the client and have no supported way to stop that task. Creating and discarding clients in the same event loop leaves every old session refreshing tokens and holding resources. Expose an async close operation and call it when the worker or application shuts down.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agentex/lib/core/clients/temporal/auth.py
Line: 105-111

Comment:
**Old clients keep refreshing**

Each authenticated connection starts a task that holds its client and credential forever. Callers receive only the client and have no supported way to stop that task. Creating and discarding clients in the same event loop leaves every old session refreshing tokens and holding resources. Expose an async close operation and call it when the worker or application shuts down.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Cursor Fix in Claude Code Fix in Codex

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.

2 participants