Workflow records the service account as the actor, not the caller

Table of Contents

This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.

1. What

The workflow engine stamps created_by and modified_by with its own service account, so a workflow a person started is recorded as having been changed by ores_<env>_workflow_service. The actor should come from the caller's bearer token, which is the house pattern: iam's handlers validate the bearer and take claims->username, and the iam provisioning path already sends an impersonation token on this very call.

2. Why

modified_by is the actor and performed_by is the service that executed – the insert trigger stamps the latter itself from ores_iam_current_service_fn(). Setting both to the service account collapses that distinction and loses the only record of who asked for the change.

It is not a small change, which is why it is recorded rather than done: start_workflow_message carries no identity field, the workflow engine holds no verifier at all, and the workflow service wires no JWT key – only iam holds the private key, and other services fetch the public one from iam.v1.auth.public-key. The engine also starts workflows with no caller at all, on recovery and self-dispatch, so a fallback is needed whatever the caller story is.

3. References

  • Found on 2026-09-26 while fixing No workflow can start once the system has an account; the surgical fix set modified_by to the service account so the pipeline could work at all, and this is the attribution it leaves behind.
  • projects/ores.workflow/core/src/service/workflow_engine.cpp — the four creation sites, and the comment recording the limitation.
  • projects/ores.iam/core/include/ores.iam.core/messaging/tenant_provisioning_handler.hpp — signer_.validate(bearer) and claims->username, the pattern to follow.
  • projects/ores.nats/src/service/jwks.cpp — the public-key fetch a verifier would use.

4. See also

  • Component Clean Standard — the provenance fields are part of every entity's shape, so attribution is a house-wide question rather than this engine's alone.

Emacs 29.3 (Org mode 9.6.15)