Skip to content

fix(auth): allow API keys to manage workspace variables and case attachments#2759

Open
mcm wants to merge 1 commit into
TracecatHQ:mainfrom
mcm:mcm/workspace-variables-attachments-actor-role
Open

fix(auth): allow API keys to manage workspace variables and case attachments#2759
mcm wants to merge 1 commit into
TracecatHQ:mainfrom
mcm:mcm/workspace-variables-attachments-actor-role

Conversation

@mcm
Copy link
Copy Markdown
Contributor

@mcm mcm commented May 23, 2026

Summary

The /variables/* and /cases/{id}/attachments/* routes are declared with WorkspaceUserRouteRole, which sets allow_api_key=False. The auth dispatcher in tracecat/auth/credentials.py:892-907 raises 403 Forbidden when a bearer token comes in as an API key but the route doesn't accept API keys — before any scope check runs. Service accounts can never reach these routes, regardless of granted scopes.

This blocks downstream integrations from:

  • writing per-workspace connection variables via API key (the original symptom that surfaced this)
  • listing / uploading / downloading / deleting case attachments via API key

The case:read/case:update scopes the attachments router requires were already in WORKSPACE_SERVICE_ACCOUNT_ASSIGNABLE_SCOPES, so attachments was an obvious oversight. The variable:* scopes were absent from the allowlist, so this PR adds them too.

Changes

  • tracecat/variables/router.py — swap WorkspaceUserRouteRoleWorkspaceActorRouteRole on all 6 endpoints.
  • tracecat/cases/attachments/router.py — swap WorkspaceUserRouteRoleWorkspaceActorRouteRole on all 4 endpoints.
  • tracecat/service_accounts/constants.py — add variable:{read,create,update,delete} to WORKSPACE_SERVICE_ACCOUNT_ASSIGNABLE_SCOPES (the org allowlist inherits via union).
  • tests/unit/test_service_accounts_validation.py — move variable:* scopes from the "rejects user-only scopes" parametrize lists into the "allows supported API-key scopes" lists for both workspace and org variants.

Compatibility

  • User sessions are unaffected — WorkspaceActorRouteRole is a superset of WorkspaceUserRouteRole (both have allow_user=True, this one just also has allow_api_key=True).
  • Existing service accounts won't auto-gain the new variable:* scopes; admins need to grant them per service account.
  • Workspace membership is still required (unchanged require_workspace="yes").

Test plan

  • ruff check clean on touched files
  • ruff format --diff clean on touched files
  • basedpyright --warnings clean on touched files
  • CI unit/registry/temporal test groups (no local docker stack to run them against)
  • Manual verification: create + read + update a workspace variable via API key with the new variable:* scopes
  • Manual verification: list + upload + download + delete a case attachment via API key

Related

Follows the same pattern as #2755 ("fix: allow API keys to fetch workflow details").

There are a few other WorkspaceUserRouteRole routes whose required scopes are already in the service-account assignable allowlist (cases/rows/router.py, several agent/* routers, three webhook endpoints in workflow/management/router.py, POST /workflow-executions/draft, parts of integrations/router.py). Those weren't flipped here since I have no immediate use case for them — happy to follow up in separate PRs if the team agrees they should also be Actor-role.


Summary by cubic

Fixes 403s for API-key requests to workspace variables and case attachments by allowing service accounts on those routes. Integrations can now manage variables and upload/download attachments with API keys.

  • Bug Fixes

    • Switched /variables/* and /cases/{id}/attachments/* to WorkspaceActorRouteRole so API keys are accepted.
    • Added variable:{read,create,update,delete} to WORKSPACE_SERVICE_ACCOUNT_ASSIGNABLE_SCOPES and updated tests.
  • Migration

    • Grant variable:* scopes to service accounts that need variable access.

Written for commit b496fff. Summary will update on new commits. Review in cubic

…chments

The /variables/* and /cases/{id}/attachments/* routes were declared with
WorkspaceUserRouteRole, which sets allow_api_key=False — so even service
accounts holding the right scopes were 403'd before scope checks ran. This
blocks downstream integrations from writing per-workspace connection
variables or syncing case attachments via API key.

- Swap WorkspaceUserRouteRole -> WorkspaceActorRouteRole on both routers
- Add variable:{read,create,update,delete} to the workspace service-account
  assignable-scope allowlist (the case:* scopes were already in it)
- Move variable:* scopes between the parametrized allow/reject test lists
@zeropath-ai
Copy link
Copy Markdown

zeropath-ai Bot commented May 23, 2026

No security or compliance issues detected. Reviewed everything up to b496fff.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► tests/unit/test_service_accounts_validation.py
    Add variable scopes to allowed list for service accounts
    Remove variable scopes from disallowed list for service accounts
► tracecat/cases/attachments/router.py
    Use WorkspaceActorRouteRole instead of WorkspaceUserRouteRole
► tracecat/service_accounts/constants.py
    Add variable read, create, update, and delete scopes
► tracecat/variables/router.py
    Use WorkspaceActorRouteRole instead of WorkspaceUserRouteRole

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 4 files

Confidence score: 5/5

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

Re-trigger cubic

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