Files
Abdul Rahman 4423973633 fix(ci): authenticate the app-dev test leg as the seeded admin user (#25028)
## Why

The `dockerhub-latest` app CI leg (the one that runs an app's
integration suite against the published
`twentycrm/twenty-app-dev:latest` image) authenticates with a hardcoded
**API_KEY** token. That broke for every app that executes deployed logic
functions in its tests.

Executing a logic function through `executeOneLogicFunction` now
requires a **user** context: the resolver reads `@AuthUser()` and
`@AuthUserWorkspaceId()`, both of which throw `ForbiddenException` for
an API key. The SDK CLI's api-client turns that `FORBIDDEN` into a
generic `Authentication failed: GraphQL auth error in response`. This
requirement was added in #24493 ("give handlers an execution context,
and a choice of whose access each call uses").

Evidence it's the image server, not app code: the leg passed on every
published image up to `2.32.0` and has failed on every image from
`2.35.0` on (the first images carrying #24493). A docs-only Slack PR
(#24882, a 2-line README change) failed the leg with the identical
error, while its `local` leg passed.

## What it does

Swap the action's `api-key` output from an API_KEY to an **ACCESS token
for Tim, the seeded admin**.

- Executing logic functions needs a **user** (Tim is one), so the
`executeOneLogicFunction` gate passes.
- The app test's global setup also **deploys the app** (`appDevOnce`),
which needs **admin** permissions. The image seeds with `--light`, where
the dev seeder makes **Tim** the admin and Jane a plain member (Jane is
the admin only in the non-light local seed). So the token must be Tim's,
not Jane's.

This mirrors the `local` leg, which already authenticates as its own
seeded admin. The token is signed with the app-dev `APP_SECRET` the same
way the previous API key was: `sha256(APP_SECRET + workspaceId +
'ACCESS')`.

## Scope and safety

- Only file changed:
`.github/actions/spawn-twenty-app-dev-test/action.yml`.
- Its only consumer is `spawn-twenty-server`, so this affects every
app's `dockerhub-latest` leg. That's the intent, they all hit the same
latent break.
- Safe: each app already authenticates as its seeded admin on its
`local` leg and passes, so the same identity on the `dockerhub-latest`
leg can't newly break a passing test; it only clears the user/admin
gates the API key could not.

## Verification

- The signing recipe was confirmed by reproducing the existing API_KEY's
signature exactly, then re-signed with `type=ACCESS`.
- Tim's ids are the dev-seeder constants; `seedCoreSchema` (users +
user-workspaces) and the `--light` admin assignment run for this
workspace.
- Confirmed green: the `slack (dockerhub-latest)` leg passes with this
token on the branch it was validated on.

---
_Generated by [Claude
Code](https://claude.ai/code/session_014rA1NFmPJS6RLjVkZoD4T4)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/25028?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-08-30 09:35:18 +00:00
..