Skip to content

Conversation

@carlydf
Copy link
Contributor

@carlydf carlydf commented Oct 30, 2025

What changed?

Add workflow update-options identity to history event

Why?

So that users can use the event as an audit log to find out who set an override

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

Note

Add identity to WORKFLOW_EXECUTION_OPTIONS_UPDATED history event and propagate through APIs, batcher, NDC, and tests.

  • History events:
    • Add identity to WorkflowExecutionOptionsUpdated attributes and wire through EventFactory, HistoryBuilder, and MutableState (AddWorkflowExecutionOptionsUpdatedEvent).
  • APIs:
    • UpdateWorkflowOptions.MergeAndApply now accepts identity and passes it to mutable state.
    • updateworkflowoptions handler uses req.GetIdentity(); startworkflow passes empty identity for attach-only updates.
  • NDC/Reset:
    • Reapplier and workflow resetter pass through/propagate event identity.
  • Worker batcher:
    • Batch update-workflow-options forwards Identity in requests.
  • Tests:
    • Update mocks and unit tests to include identity in expectations.
    • Add functional checks to assert event identity in history for direct and batch updates.

Written by Cursor Bugbot for commit 8958b2f. This will update automatically on new commits. Configure here.

@carlydf carlydf requested review from a team as code owners October 30, 2025 23:06
requestID,
completionCallbacks,
links,
"",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

start workflow request does not provide identity, so we don't have anything to put here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is for nexus callbacks and not versioning override anyway

requestID,
callbacks,
event.Links,
attr.GetIdentity(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

reapply the identity that was already on the update-options event

switch op := operation.GetVariant().(type) {
case *workflowpb.PostResetOperation_UpdateWorkflowOptions_:
_, _, err := updateworkflowoptions.MergeAndApply(resetMS, op.UpdateWorkflowOptions.GetWorkflowExecutionOptions(), op.UpdateWorkflowOptions.GetUpdateMask())
_, _, err := updateworkflowoptions.MergeAndApply(resetMS, op.UpdateWorkflowOptions.GetWorkflowExecutionOptions(), op.UpdateWorkflowOptions.GetUpdateMask(), "")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

don't apply an identity for post-reset-operations update-options, because even if we applied the identity of the reset request, the reset code paths are used in a lot of places and I don't want to accidentally have inconsistencies on the passive cluster or something. Better to just be consistent and not have an identity if the update-options was part of a reset operation (for now at least)

Copy link
Contributor

Choose a reason for hiding this comment

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

with state-based replication this code might not run on the passive side.

Ideally we should put the reset requester in the event but I'm fine doing it later. But please add this explanation in the code as a comment so the future contributor can understand the reasoning.

@carlydf carlydf changed the title populate workflow update-options identity Add workflow update-options identity to history event Oct 30, 2025
cursor[bot]

This comment was marked as outdated.

carlydf added a commit to temporalio/api that referenced this pull request Oct 31, 2025
_**READ BEFORE MERGING:** All PRs require approval by both Server AND
SDK teams before merging! This is why the number of required approvals
is "2" and not "1"--two reviewers from the same team is NOT sufficient.
If your PR is not approved by someone in BOTH teams, it may be summarily
reverted._

<!-- Describe what has changed in this PR -->
Ddd identity to workflow update-options


<!-- Tell your future self why have you made these changes -->
So that the history event can serve as an audit log as to who set
versioning overrides on the workflow


<!-- Are there any breaking changes on binary or code level? -->
None

<!-- If this breaks the Server, please provide the Server PR to merge
right after this PR was merged. -->
temporalio/temporal#8576
temporal-cicd bot pushed a commit to temporalio/api-go that referenced this pull request Oct 31, 2025
_**READ BEFORE MERGING:** All PRs require approval by both Server AND
SDK teams before merging! This is why the number of required approvals
is "2" and not "1"--two reviewers from the same team is NOT sufficient.
If your PR is not approved by someone in BOTH teams, it may be summarily
reverted._

<!-- Describe what has changed in this PR -->
Ddd identity to workflow update-options

<!-- Tell your future self why have you made these changes -->
So that the history event can serve as an audit log as to who set
versioning overrides on the workflow

<!-- Are there any breaking changes on binary or code level? -->
None

<!-- If this breaks the Server, please provide the Server PR to merge
right after this PR was merged. -->
temporalio/temporal#8576
requestID,
completionCallbacks,
links,
"",
Copy link

Choose a reason for hiding this comment

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

Bug: Audit Gap: Workflow Option Identity Missing

The AddWorkflowExecutionOptionsUpdatedEvent call passes an empty string for the identity parameter when attaching options to an existing workflow during conflict resolution. However, s.request.StartRequest.GetIdentity() is available and used elsewhere in the same file to access the workflow starter's identity. This results in missing audit log information about who set the workflow options when using OnConflictOptions during start workflow conflicts.

Fix in Cursor Fix in Web

Copy link
Contributor

@ShahabT ShahabT left a comment

Choose a reason for hiding this comment

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

Approved with a comment

switch op := operation.GetVariant().(type) {
case *workflowpb.PostResetOperation_UpdateWorkflowOptions_:
_, _, err := updateworkflowoptions.MergeAndApply(resetMS, op.UpdateWorkflowOptions.GetWorkflowExecutionOptions(), op.UpdateWorkflowOptions.GetUpdateMask())
_, _, err := updateworkflowoptions.MergeAndApply(resetMS, op.UpdateWorkflowOptions.GetWorkflowExecutionOptions(), op.UpdateWorkflowOptions.GetUpdateMask(), "")
Copy link
Contributor

Choose a reason for hiding this comment

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

with state-based replication this code might not run on the passive side.

Ideally we should put the reset requester in the event but I'm fine doing it later. But please add this explanation in the code as a comment so the future contributor can understand the reasoning.

@carlydf carlydf enabled auto-merge (squash) November 20, 2025 02:14
@carlydf carlydf merged commit 5f2b8cd into main Nov 20, 2025
96 of 98 checks passed
@carlydf carlydf deleted the update-options-id branch November 20, 2025 19:30
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.

3 participants