Skip to content

Workshopctl instance context - #1019

Open
tlm wants to merge 3 commits into
system-sdk-secret-providerfrom
workshopctl-instance-context
Open

Workshopctl instance context#1019
tlm wants to merge 3 commits into
system-sdk-secret-providerfrom
workshopctl-instance-context

Conversation

@tlm

@tlm tlm commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is stacked on #1017, which adds the authenticated user and workshop instance ID to the HTTP request context.

It propagates that request context through workshopctl command execution and resolves an appropriate hook context for both hook-driven and ordinary workshop requests. This prepares get-secret to determine securely which workshop made a request without coupling command execution directly to the HTTP layer.

Context propagation

The internal command interface now accepts a standard context.Context, and the workshopctl endpoint passes r.Context() into command execution.

Request identity belongs in context.Context because it is request-scoped metadata. Passing it this way avoids adding workshop identity parameters to every command and allows future commands to consume request metadata without further changing the command interface.

go-flags only invokes commands implementing Execute([]string) error. Since that signature cannot carry a context, the parser now uses a command handler that calls the project's context-aware command interface explicitly.

Hook context resolution

Workshopctl commands still require a hookstate.Context, but requests can originate through two different paths.

When a request supplies a hook cookie, the handler resolves the existing active hook context. This preserves the established behavior for commands executed during a hook, including access to the hook task and its context data.

Ordinary SDK wrapper calls do not execute inside a hook and therefore do not have a hook cookie. For these requests, the handler uses the workshop instance ID propagated by #1017.

The instance ID is not trusted by itself. Before creating a context, the workshop manager verifies that the authenticated user owns a workshop with that instance ID. This prevents a caller from presenting another workshop's identifier and using it to obtain that workshop's context.

After ownership is established, the hook manager creates a taskless ephemeral context. This provides the interface expected by workshopctl commands without fabricating a hook task or persisting context data beyond the request.

The cookie and instance-ID paths are kept in separate helpers so their different trust models and lifecycle requirements remain explicit.

Error handling

Unknown or unowned instance IDs are rejected without creating a context.

Backend and state lookup failures are logged server-side, while callers receive a generic internal error response. Returning the underlying error could expose project names, filesystem details, state contents, or other implementation information through an untrusted endpoint.

Tests

Tests cover:

  • Propagation of request-scoped values into command execution.
  • Resolution of existing cookie-backed hook contexts.
  • Cookie-less resolution using an owned workshop instance ID.
  • Rejection of missing, unknown, and unowned instance IDs.
  • Workshop ownership lookup across the user's projects.
  • Creation of taskless ephemeral contexts.
  • Logging and sanitization of internal lookup failures.
  • Help requests relying on the propagated workshop identity.

Self-review quick check

  • Make decisions that cost a lot to reverse explicit in the PR description.
  • Avoid nested conditions.
  • Delete dead code and redundant comments.
  • Normalise symmetries by sticking to doing identical things identically.
  • Check that coupled code elements, files, and directories are adjacent.
  • Put variable declaration and initialisation together.
  • Divide large expressions into digestible and self-explanatory ones.
  • Put a blank line between two logically different chunks of code.
  • Follow the style guide for new error messages.

Docs

  • I confirm the PR has no implications for documentation.

@tlm tlm closed this Sep 4, 2026
@tlm
tlm force-pushed the workshopctl-instance-context branch from 6c629a2 to d7624be Compare September 4, 2026 03:49
@tlm
tlm deleted the workshopctl-instance-context branch September 4, 2026 03:51
@tlm
tlm restored the workshopctl-instance-context branch September 4, 2026 03:51
tlm added 3 commits September 4, 2026 03:58
Pass a standard context.Context to workshopctl commands so request-scoped values can be made available during command execution. This prepares get-secret to access the requesting workshop's instance identity.

Use the go-flags command handler because its native Execute interface does not support context propagation.
Accept a context.Context in ctlcmd.Run and pass it to the selected command during execution. This allows request-scoped values, including the workshop instance ID, to reach get-secret.

Pass the HTTP request context from the workshopctl API handler and verify the propagation contract through the mock command's Execute callback.
Use an existing hook context when a workshopctl request supplies a cookie. For cookie-less requests, verify that the requesting user owns the workshop instance ID before creating a taskless ephemeral hook context.

Log internal lookup failures while returning a generic error response to avoid exposing backend details to callers.
@tlm tlm reopened this Sep 4, 2026
@tlm tlm self-assigned this Sep 4, 2026
@tlm
tlm requested a review from dmitry-lyfar September 4, 2026 03:59
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.

1 participant