Skip to content

Visit payloads inside system Nexus envelopes#290

Draft
dplyukhin wants to merge 4 commits into
mainfrom
go-deferred-encoding
Draft

Visit payloads inside system Nexus envelopes#290
dplyukhin wants to merge 4 commits into
mainfrom
go-deferred-encoding

Conversation

@dplyukhin

@dplyukhin dplyukhin commented Jun 23, 2026

Copy link
Copy Markdown

What

Teaches the payload visitor to handle system Nexus envelopes. When it
encounters a ScheduleNexusOperationCommandAttributes targeting the reserved
system Nexus endpoint (__temporal_system), the Input is not an opaque single
payload — it is a proto-binary-serialized request message whose own fields carry
the user payloads. The visitor now:

  1. Decodes the envelope into its proto message, using the payload's
    messageType metadata (resolved via protoregistry.GlobalTypes).
  2. Visits the inner payloads recursively (so external storage / codecs apply to
    the inner payloads, not the envelope).
  3. Re-serializes the message back into Input.

The envelope itself is never offloaded or codec-encoded. Ordinary Nexus
operations continue to have Input visited as a single opaque payload. Only
binary/protobuf envelopes are accepted; missing/unknown messageType errors.

A system Nexus envelope is identified solely by the __temporal_system
endpoint — every operation on that endpoint is a system Nexus operation, so no
service/operation matching or operation registry is required.

How

The dispatch (system-envelope vs. ordinary single-payload) is inlined into the
generated visitPayloads (ScheduleNexusOperationCommandAttributes case, via
the proxygenerator template). The envelope decode/visit/encode logic lives in a
hand-written proxy/system_nexus.go helper (visitSystemNexusEnvelope).

No generated registry or WIT is needed: the input proto type comes from the
payload's messageType metadata.

Test plan

  • make proxy && (cd cmd/proxygenerator && go run ./ -verifyOnly) (generated
    code is current)
  • go test -tags protolegacy ./...
  • proxy/system_nexus_test.go: nested-only visitation (sequential +
    concurrent), proto-binary round-trip, non-proto-binary rejection,
    unknown/missing message-type rejection, ordinary-Nexus single-payload
    fallback

@CLAassistant

CLAassistant commented Jun 23, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Comment thread Makefile Outdated
Comment thread proxy/system_nexus.go Outdated
Comment thread proxy/system_nexus.go Outdated
@github-actions

Copy link
Copy Markdown

Opengrep — new findings

Severity Location Rule Message
ERROR .github/workflows/check-sdk-compat.yml:31 security.gha.missing-explicit-permissions-temporal No explicit GITHUB_TOKEN permissions found at the workflow or job level. Add a permissions: block at the workflow root (applies to all jobs) or per job with least privilege (e.g., contents: read and only specific writes like pull-requests: write if needed).
ERROR .github/workflows/ci.yml:10 security.gha.missing-explicit-permissions-temporal No explicit GITHUB_TOKEN permissions found at the workflow or job level. Add a permissions: block at the workflow root (applies to all jobs) or per job with least privilege (e.g., contents: read and only specific writes like pull-requests: write if needed).
ERROR .github/workflows/create-release.yml:30 security.gha.missing-explicit-permissions-temporal No explicit GITHUB_TOKEN permissions found at the workflow or job level. Add a permissions: block at the workflow root (applies to all jobs) or per job with least privilege (e.g., contents: read and only specific writes like pull-requests: write if needed).
ERROR .github/workflows/delete-release.yml:22 security.gha.missing-explicit-permissions-temporal No explicit GITHUB_TOKEN permissions found at the workflow or job level. Add a permissions: block at the workflow root (applies to all jobs) or per job with least privilege (e.g., contents: read and only specific writes like pull-requests: write if needed).
ERROR .github/workflows/publish-release.yml:22 security.gha.missing-explicit-permissions-temporal No explicit GITHUB_TOKEN permissions found at the workflow or job level. Add a permissions: block at the workflow root (applies to all jobs) or per job with least privilege (e.g., contents: read and only specific writes like pull-requests: write if needed).
ERROR .github/workflows/update-proto.yml:22 security.gha.missing-explicit-permissions-temporal No explicit GITHUB_TOKEN permissions found at the workflow or job level. Add a permissions: block at the workflow root (applies to all jobs) or per job with least privilege (e.g., contents: read and only specific writes like pull-requests: write if needed).

Suppress findings

Add a noopengrep comment on the line before the finding:

# noopengrep: <rule-id>

When the payload visitor encounters a ScheduleNexusOperationCommandAttributes
targeting the system Nexus endpoint (__temporal_system) and the WorkflowService,
its Input is a proto-binary-serialized request whose own fields carry the user
payloads rather than an opaque single payload. Decode the envelope, visit the
inner payloads recursively (so external storage and codecs apply to the inner
payloads, not the envelope), and re-serialize -- leaving the envelope itself
un-offloaded and un-codec'd. Ordinary Nexus operations continue to visit Input
as a single opaque payload.

The (service, operation) -> input proto type mapping comes from a new,
dependency-free `nexussystem` registry package generated by nex-gen from a
checked-in WIT (nexussystem/wit), wired into the build via the
`nexus-system-registry` Make target. The envelope decode/visit/encode logic
lives in a hand-written proxy/system_nexus.go helper that the generated
interceptor calls; only binary/protobuf envelopes are accepted.
Simplify system Nexus envelope handling per review:

- Identify a system Nexus envelope solely by the reserved __temporal_system
  endpoint (all operations on that endpoint are system Nexus operations), instead
  of also matching the service name.
- Decode the envelope's proto message using the payload's "messageType"
  metadata via protoregistry.GlobalTypes, removing the need for the generated
  (service, operation) -> input-type registry. The nexussystem package, its
  checked-in WIT, and the nexus-system-registry Make target are deleted.
- Inline the system-vs-ordinary Input dispatch directly into the generated
  visitPayloads (the ScheduleNexusOperationCommandAttributes case) rather than a
  separate helper function; visitSystemNexusEnvelope remains as the envelope
  decode/visit/encode helper.

Envelopes still must be binary/protobuf; missing/unknown message types error.
@dplyukhin dplyukhin force-pushed the go-deferred-encoding branch from 392a187 to 105dddd Compare June 25, 2026 19:47
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