Skip to content

feat(api): Add workspace-scoped route aliases#2590

Merged
daryllimyt merged 6 commits intomainfrom
workspace-scoped-route-aliases
May 5, 2026
Merged

feat(api): Add workspace-scoped route aliases#2590
daryllimyt merged 6 commits intomainfrom
workspace-scoped-route-aliases

Conversation

@daryllimyt
Copy link
Copy Markdown
Contributor

@daryllimyt daryllimyt commented Apr 30, 2026

Summary

  • Add canonical /workspaces/{workspace_id}/... aliases for workspace-scoped public API routes while keeping the legacy flat routes registered as hidden compatibility aliases.
  • Move service account API key auth to Authorization: Bearer ... and keep it separate from executor bearer-token auth.
  • Add route-shape regression tests that verify canonical and legacy aliases share handlers and use the path-or-query workspace RoleACL path.
  • Regenerate the frontend API client for the new OpenAPI route shape.

API surface changes

Workspace-scoped public routes now expose the workspace in the path. The old flat routes still work at runtime, but they are hidden from OpenAPI so generated clients move to the canonical workspace-scoped shape.

Newly documented workspace aliases

This PR moves the public OpenAPI shape for these route prefixes under /workspaces/{workspace_id}:

/workspaces/{workspace_id}/actions
/workspaces/{workspace_id}/agent/channels/tokens
/workspaces/{workspace_id}/agent/presets
/workspaces/{workspace_id}/agent/sessions
/workspaces/{workspace_id}/agent/skills
/workspaces/{workspace_id}/agent/skills:upload
/workspaces/{workspace_id}/agent/workspace/providers/status
/workspaces/{workspace_id}/approvals
/workspaces/{workspace_id}/case-dropdowns
/workspaces/{workspace_id}/case-durations
/workspaces/{workspace_id}/case-fields
/workspaces/{workspace_id}/case-tags
/workspaces/{workspace_id}/cases
/workspaces/{workspace_id}/editor
/workspaces/{workspace_id}/folders
/workspaces/{workspace_id}/inbox
/workspaces/{workspace_id}/integrations
/workspaces/{workspace_id}/mcp-integrations
/workspaces/{workspace_id}/providers
/workspaces/{workspace_id}/schedules
/workspaces/{workspace_id}/secrets
/workspaces/{workspace_id}/tables
/workspaces/{workspace_id}/tags
/workspaces/{workspace_id}/variables
/workspaces/{workspace_id}/workflow-executions
/workspaces/{workspace_id}/workflows

The EE approval route is included in this migration: /approvals/{session_id} is now documented as /workspaces/{workspace_id}/approvals/{session_id}.

Existing workspace routes

These routes were already workspace-scoped before this PR and remain in OpenAPI as-is:

/workspaces
/workspaces/search
/workspaces/{workspace_id}
/workspaces/{workspace_id}/agent-models
/workspaces/{workspace_id}/invitations
/workspaces/{workspace_id}/members
/workspaces/{workspace_id}/memberships
/workspaces/{workspace_id}/service-accounts

Before and after examples

Before After
GET /workflows GET /workspaces/{workspace_id}/workflows
GET /cases/{case_id} GET /workspaces/{workspace_id}/cases/{case_id}
POST /workflow-executions POST /workspaces/{workspace_id}/workflow-executions
GET /workflow-executions/search?workspace_id=... GET /workspaces/{workspace_id}/workflow-executions/search
POST /approvals/{session_id} POST /workspaces/{workspace_id}/approvals/{session_id}
POST /agent/skills:upload POST /workspaces/{workspace_id}/agent/skills:upload
GET /secrets GET /workspaces/{workspace_id}/secrets
GET /integrations GET /workspaces/{workspace_id}/integrations

Workflow execution ID ergonomics

The old direct execution lookup took the full workflow execution ID as one path parameter:

GET /workflow-executions/{execution_id}

For canonical execution IDs like wf_abc/exec_def, clients had to treat the slash as part of the path parameter, so generated clients and manual callers needed to URL-encode the full ID, for example:

GET /workflow-executions/wf_abc%2Fexec_def

This PR adds a workflow-scoped read route that splits the workflow ID and execution suffix into separate path parameters:

GET /workspaces/{workspace_id}/workflows/{workflow_id}/executions/{execution_id}

Example:

GET /workspaces/ws_123/workflows/wf_abc/executions/exec_def

That route reconstructs the Temporal workflow execution ID as wf_abc/exec_def server-side, so clients no longer need to pass the slash-bearing full execution ID for the common read-by-workflow case. Direct execution routes still exist under the canonical workspace prefix for callers that already have the full execution ID.

Routes intentionally left flat

Some routes are not workspace-prefixed because they are callbacks, public entrypoints, organization-level APIs, platform/admin APIs, or internal APIs. Notable examples:

  • Callback and public entrypoints: /integrations/callback, /agent/channels/{channel_type}/{token}, /agent/channels/slack/oauth/callback, /webhooks/{workflow_id}/{secret}
  • Organization-level routes: /organization/..., /organization/service-accounts/..., /organization/secrets/..., /organization/vcs/...
  • Platform/ops routes: /admin/..., /settings/..., /registry/..., /feature-flags, /health, /ready
  • EE platform routes: /rbac/..., /watchtower/monitor/...
  • Internal routes: /internal/...

Validation

  • uv run ruff check ...
  • uv run ruff format --check ...
  • uv run basedpyright ...
  • TRACECAT__SERVICE_KEY=test-service-key TRACECAT__SIGNING_SECRET=test-signing-secret uv run pytest tests/unit/test_role_acl.py tests/unit/api
  • pnpm -C frontend check
  • pnpm -C frontend run typecheck

@daryllimyt daryllimyt temporarily deployed to internal-registry-ci April 30, 2026 21:35 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci April 30, 2026 21:36 — with GitHub Actions Inactive
@zeropath-ai
Copy link
Copy Markdown

zeropath-ai Bot commented Apr 30, 2026

No security or compliance issues detected. Reviewed everything up to 2dd2ab5.

Security Overview
Detected Code Changes

The diff is too large to display a summary of code changes.

@daryllimyt daryllimyt force-pushed the workspace-scoped-route-aliases branch from bf91168 to a527926 Compare May 2, 2026 21:03
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 2, 2026 21:03 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 2, 2026 21:03 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 2, 2026 21:05 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 2, 2026 21:05 — with GitHub Actions Inactive
@daryllimyt daryllimyt marked this pull request as ready for review May 2, 2026 21:06
@daryllimyt daryllimyt changed the title Add workspace-scoped route aliases feat(api): Add workspace-scoped route aliases May 2, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 41 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c28dc33b0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tracecat/workflow/executions/router.py
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 4, 2026 21:04 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 4, 2026 21:04 — with GitHub Actions Inactive
@daryllimyt daryllimyt force-pushed the workspace-scoped-route-aliases branch from bd8ed67 to a7268f8 Compare May 4, 2026 21:24
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 4, 2026 21:24 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 4, 2026 21:25 — with GitHub Actions Inactive
…RouteRole and WorkspaceActorRouteRole across the codebase for improved route authorization consistency.
@daryllimyt daryllimyt requested a review from jordan-umusu May 4, 2026 22:15
Copy link
Copy Markdown
Collaborator

@jordan-umusu jordan-umusu left a comment

Choose a reason for hiding this comment

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

skim lgtm, so long as the tests for the legacy version to guard against regression.

@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 4, 2026 22:31 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 4, 2026 22:31 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 5, 2026 03:10 — with GitHub Actions Inactive
@daryllimyt daryllimyt temporarily deployed to internal-registry-ci May 5, 2026 03:10 — with GitHub Actions Inactive
@daryllimyt daryllimyt merged commit e184b2c into main May 5, 2026
19 checks passed
@daryllimyt daryllimyt deleted the workspace-scoped-route-aliases branch May 5, 2026 03:52
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