Skip to content

feat(dashboard-api): populate Ory identity external_id on admin bootstrap - #3062

Merged
ben-fornefeld merged 1 commit into
mainfrom
feat/dashboard-bootstrap-ory-external-id
Jun 22, 2026
Merged

feat(dashboard-api): populate Ory identity external_id on admin bootstrap#3062
ben-fornefeld merged 1 commit into
mainfrom
feat/dashboard-bootstrap-ory-external-id

Conversation

@ben-fornefeld

@ben-fornefeld ben-fornefeld commented Jun 22, 2026

Copy link
Copy Markdown
Member

What

During OIDC admin user bootstrap, set the Ory identity's external_id to the canonical public.users.id UUID after the user row has been committed.

Details

  • Added SetIdentityExternalID(ctx, subject, externalID) to the userprofile.Provider interface.
  • Implemented it on oryProvider via Ory PatchIdentity (JSON patch replace /external_id).
  • bootstrapUserWithIdentity calls the setter after each commit (existing-team and new-team paths), only for OIDC bootstrap (identity present). If the Ory update fails, bootstrap hard-fails and returns the error.

@cla-bot cla-bot Bot added the cla-signed label Jun 22, 2026
@cursor

cursor Bot commented Jun 22, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Ory is updated before the database transaction commits, so a successful patch followed by a rollback or commit failure can leave external_id set in Ory without a matching committed user row. Bootstrap failure on Ory errors also makes signup depend on Ory admin API availability.

Overview
During OIDC admin user bootstrap, the API sets each Ory identity’s external_id to the canonical public.users.id once the user and identity rows exist in the open bootstrap transaction. A new SetIdentityExternalID on userprofile.Provider is implemented for Ory with a JSON Patch add on /external_id so first-time and repeat bootstraps stay idempotent. Bootstrap calls this step only when an OIDC identity is present and fails the whole bootstrap if Ory rejects the patch; handler and Ory provider tests cover the wiring and patch shape.

Reviewed by Cursor Bugbot for commit 0bc61ea. Bugbot is set up for automated code reviews on this repo. Configure here.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

Calling setOIDCIdentityExternalID after committing the transaction but before provisioning the team can block team provisioning permanently if the Ory update fails, as subsequent retries will skip provisioning due to the team's age. Additionally, returning an error when setOIDCIdentityExternalID fails for an existing user unnecessarily blocks the bootstrap process and prevents login, even though the user and team are already successfully committed. Logging these errors instead of returning them ensures the critical path of team provisioning and user login is not blocked.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/dashboard-api/internal/handlers/utils_team_provisioning.go Outdated
Comment thread packages/dashboard-api/internal/handlers/utils_team_provisioning.go Outdated
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
2980 4 2976 6
View the top 3 failed test(s) by shortest run time
github.com/e2b-dev/infra/tests/integration/internal/tests/api/templates::TestTemplateBuildRUN
Stack Traces | 0s run time
=== RUN   TestTemplateBuildRUN
=== PAUSE TestTemplateBuildRUN
=== CONT  TestTemplateBuildRUN
--- FAIL: TestTemplateBuildRUN (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/templates::TestTemplateBuildRUN/Single_RUN_command
Stack Traces | 166s run time
=== RUN   TestTemplateBuildRUN/Single_RUN_command
=== PAUSE TestTemplateBuildRUN/Single_RUN_command
=== CONT  TestTemplateBuildRUN/Single_RUN_command
    build_template_test.go:133: test-ubuntu-run: [info] Building template ycgywmapzs8fu35fnw3g/778c622a-d853-4ef4-a03b-c08adc55a042
    build_template_test.go:133: test-ubuntu-run: [info] [base] FROM ubuntu:22.04 [905bb9b1f7b3e631aa9d97d25385b3bb55c45687cb0f33deab700d7906575727]
    build_template_test.go:133: test-ubuntu-run: [info] Base Docker image size: 30 MB
    build_template_test.go:133: test-ubuntu-run: [info] Creating file system and pulling Docker image
    build_template_test.go:133: test-ubuntu-run: [info] Uncompressing layer sha256:40d16f30db405106ef8074779bdf41f012465c2a785bbeaa2eab9f2081099b47 30 MB
    build_template_test.go:133: test-ubuntu-run: [info] Uncompressing layer sha256:fa07423710b93b4cc200e9b5a1edb9026010c9d1c8b0853912047779e227d7f9 13 MB
    build_template_test.go:133: test-ubuntu-run: [info] Uncompressing layer sha256:8c4b1b28875140ed3abacaf16ad0d696f6bef912f52d2148f261a23e3349465b 168 B
    build_template_test.go:133: test-ubuntu-run: [info] Layers extracted
    build_template_test.go:133: test-ubuntu-run: [info] Root filesystem structure: bin, boot, dev, etc, home, lib, lib32, lib64, libx32, media, mnt, opt, proc, root, run, sbin, srv, sys, tmp, usr, var
    build_template_test.go:133: test-ubuntu-run: [info] Provisioning sandbox template
    build_template_test.go:133: test-ubuntu-run: [info] Provisioning was successful, cleaning up
    build_template_test.go:133: test-ubuntu-run: [info] Sandbox template provisioned
    build_template_test.go:133: test-ubuntu-run: [info] [base] DEFAULT USER user [ea1d9e9a4e5e72b3edd251b28ade9fa6aa5a91811560507694d4964fdbac723b]
    build_template_test.go:133: test-ubuntu-run: [info] [builder 1/1] RUN echo 'Hello, World!' [3a7c1b087bdada710574e91a5484a97044150a027127d59c9b2df2bec44bdd33]
    build_template_test.go:133: test-ubuntu-run: [info] [builder 1/1] [stdout]: Hello, World!
    build_template_test.go:133: test-ubuntu-run: [info] [finalize] Finalizing template build [bf952c855fff6cfdd2ac81baf7c186afcaf50eaeee6b2a47b347408b7390e652]
    build_template_test.go:133: test-ubuntu-run: [error] Build failed: build was cancelled
    build_template_test.go:166: Build failed: {<nil> build was cancelled <nil>}
--- FAIL: TestTemplateBuildRUN/Single_RUN_command (166.46s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/templates::TestTemplateBuildCOPY
Stack Traces | 182s run time
=== RUN   TestTemplateBuildCOPY
=== PAUSE TestTemplateBuildCOPY
=== CONT  TestTemplateBuildCOPY
    build_template_test.go:133: test-ubuntu-copy: [info] Building template ph3z5hm0d06klj6milgj/6d2a6337-5270-4622-8b75-413afe87542a
    build_template_test.go:133: test-ubuntu-copy: [info] [base] FROM ubuntu:24.04 [c39b5437504679a3bf3ba259cd432b64e76eb59a37a904738b53964916ce30d5]
    build_template_test.go:133: test-ubuntu-copy: [info] Base Docker image size: 30 MB
    build_template_test.go:133: test-ubuntu-copy: [info] Creating file system and pulling Docker image
    build_template_test.go:133: test-ubuntu-copy: [info] Uncompressing layer sha256:cb259a83ac3dd9fea0b394df41df2b298adf0df938fef5999475af18a751c257 30 MB
    build_template_test.go:133: test-ubuntu-copy: [info] Uncompressing layer sha256:fa07423710b93b4cc200e9b5a1edb9026010c9d1c8b0853912047779e227d7f9 13 MB
    build_template_test.go:133: test-ubuntu-copy: [info] Uncompressing layer sha256:8c4b1b28875140ed3abacaf16ad0d696f6bef912f52d2148f261a23e3349465b 168 B
    build_template_test.go:133: test-ubuntu-copy: [info] Layers extracted
    build_template_test.go:133: test-ubuntu-copy: [info] Root filesystem structure: bin, boot, dev, etc, home, lib, lib64, media, mnt, opt, proc, root, run, sbin, srv, sys, tmp, usr, var
    build_template_test.go:133: test-ubuntu-copy: [info] Provisioning sandbox template
    build_template_test.go:133: test-ubuntu-copy: [info] Provisioning was successful, cleaning up
    build_template_test.go:133: test-ubuntu-copy: [info] Sandbox template provisioned
    build_template_test.go:133: test-ubuntu-copy: [info] [base] DEFAULT USER user [3da537a117dca86581b7ada95bd60bd622d9251689edd72ea31f576d71870989]
    build_template_test.go:133: test-ubuntu-copy: [info] [builder 1/2] COPY . /app/ [b68d7028b17386e4debf2f779f7e9fe80a664e3401f338e37621c8e9a1339c9e]
    build_template_test.go:133: test-ubuntu-copy: [info] [builder 2/2] RUN cat /app/hello.txt | grep 'Hello from COPY!' [42c96f33b688b5977efb52758632c7a749a455bd99d156205eafc5d884f8ffbc]
    build_template_test.go:133: test-ubuntu-copy: [info] [builder 2/2] [stdout]: Hello from COPY!
    build_template_test.go:133: test-ubuntu-copy: [info] [finalize] Finalizing template build [297e24b5987786ae506bda0af96675039461afed1fcd4ec7a1f51572f618eed3]
    build_template_test.go:133: test-ubuntu-copy: [error] Build failed: build was cancelled
    build_template_test.go:1156: Build failed: {<nil> build was cancelled <nil>}
--- FAIL: TestTemplateBuildCOPY (181.99s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestCommandKillNextApp
Stack Traces | 260s run time
=== RUN   TestCommandKillNextApp
=== PAUSE TestCommandKillNextApp
=== CONT  TestCommandKillNextApp
    process_test.go:30: Build failed: {<nil> build was cancelled <nil>}
--- FAIL: TestCommandKillNextApp (260.14s)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

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

Copy link
Copy Markdown

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: 4ccab566f5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/dashboard-api/internal/userprofile/ory.go Outdated
Comment thread packages/dashboard-api/internal/handlers/utils_team_provisioning.go Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be6327f. Configure here.

Comment thread packages/dashboard-api/internal/handlers/utils_user_provisioning.go Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Additional findings (outside current diff — PR may have been updated during review):

  • 🔴 packages/dashboard-api/internal/handlers/utils_team_provisioning.go:230-232 — On the new-team path, setOIDCIdentityExternalID runs between tx.Commit and ProvisionTeam (lines 226-242). If the Ory PATCH fails transiently, the user/identity/team/membership rows are durably committed but billing provisioning is never invoked. Recovery is bounded by the existing-team path's 30s bootstrapProvisionRetryAge window — if Ory is degraded for >30s the team is permanently half-bootstrapped without billing. Suggest swapping the order on the new-team path so ProvisionTeam (already error-ignored via _ =) runs first, preserving the "billing is always attempted at least once" invariant the retry window relies on.

    Extended reasoning...

    The regression. Before this PR the new-team path was: tx.Commit_ = teamProvisionSink.ProvisionTeam(...) (fire-and-forget). After this PR the order is: tx.CommitsetOIDCIdentityExternalID (hard-fail) → ProvisionTeam. The Ory PATCH was inserted between the commit and the (already error-swallowed) provision call, so any transient PATCH failure short-circuits provisioning entirely.

    Why the 30s retry window doesn't save us. The existing-team path at lines 171-200 was designed to recover silent ProvisionTeam failures: it re-invokes ProvisionTeam, but only when time.Since(existingTeam.CreatedAt) < bootstrapProvisionRetryAge (30 seconds). That window was sized around the implicit invariant that ProvisionTeam was attempted at least once on initial bootstrap. The PR breaks that invariant: now an Ory PATCH failure can prevent the first attempt entirely. Worse, on retry the existing-team path also calls setOIDCIdentityExternalID (line 177) before checking the 30s window — so if Ory's admin API stays degraded, every retry returns early and never even reaches the ProvisionTeam call.

    Plausibility of the trigger. Ory's admin API (where PatchIdentity lives) is operationally separate from the self-service auth APIs that issue tokens. A partial Ory outage, rate-limit blip, or admin-token rotation can leave the admin endpoint unreachable while OIDC auth keeps succeeding — exactly the conditions that fire a bootstrap. greping the repo confirms bootstrapProvisionRetryAge is used nowhere else and there is no async reconciler — ProvisionTeam is only called from synchronous request-path sites in utils_team_provisioning.go, so a missed call is unrecoverable without manual intervention.

    Step-by-step proof.

    1. New user starts OIDC bootstrap. bootstrapUserWithIdentity runs the new-team path.
    2. Line 226: tx.Commit succeeds. public.users, identity, team, and users_teams row are durable.
    3. Line 230: setOIDCIdentityExternalID calls oryProvider.SetIdentityExternalIDory.PatchIdentity returns a transient error (502 from admin API).
    4. Line 231: function returns provisionedTeam{}, err. The teamProvisionSink.ProvisionTeam call at line 242 is never reached.
    5. The user retries 60s later. The existing-team path runs.
    6. Line 177: setOIDCIdentityExternalID is called again. If Ory recovered, it succeeds; if still degraded, it errors and we loop.
    7. Once setOIDCIdentityExternalID finally succeeds, line 181 checks time.Since(existingTeam.CreatedAt) < 30s. Because the team was created >30s ago, the condition is false and ProvisionTeam is never called.
    8. Result: team and membership exist in our DB, identity has external_id set in Ory, but the billing sink was never invoked. No reconciler will fix this.

    Fix. Swap the two calls on the new-team path so ProvisionTeam runs before setOIDCIdentityExternalID. The operations are independent: ProvisionTeam doesn't need external_id, and the Ory PATCH doesn't need billing state. Since the ProvisionTeam call is already _ = (errors swallowed), this is a one-line reordering that costs nothing and restores the "always attempt billing once per new team" invariant the existing-team retry window depends on. The existing-team path (lines 174-180) has the same shape but is less load-bearing because the path only runs when a team already exists; still, applying the same swap there is consistent.

Comment thread packages/dashboard-api/internal/handlers/team_handlers_test.go
ben-fornefeld added a commit that referenced this pull request Jun 22, 2026
Address review feedback on PR #3062: on the new-team bootstrap path, the
Ory external_id patch ran after the transaction committed and before
billing provisioning, so a transient Ory failure left a persisted default
team that never got provisioned and could be permanently stranded once the
30s retry window elapsed.

Move setOIDCIdentityExternalID before CreateTeam inside the transaction,
so an Ory failure rolls public.users/identity/team back together and no
orphan team is created. On the existing-team path (team already committed),
log the external_id error instead of returning it so login and retry
provisioning are not blocked. Also fix a dead test assertion.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…trap

Set the Ory identity external_id to the canonical public.users id once the
user row is created during OIDC admin bootstrap, before the default team is
created. Uses a JSON Patch "add" op so it works for identities that do not
yet have an external_id (Ory omits the field when unset). An Ory failure
aborts bootstrap and rolls the user/identity back.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@ben-fornefeld
ben-fornefeld force-pushed the feat/dashboard-bootstrap-ory-external-id branch from dfa39be to 0bc61ea Compare June 22, 2026 20:55
@ben-fornefeld
ben-fornefeld merged commit 6c51232 into main Jun 22, 2026
54 checks passed
@ben-fornefeld
ben-fornefeld deleted the feat/dashboard-bootstrap-ory-external-id branch June 22, 2026 21:31
charlie-e2b added a commit that referenced this pull request Jul 30, 2026
🤖 I have created a release *beep* *boop*
---


## 0.0.1 (2026-07-30)


### Features

* add workspace admin API foundations
([#3314](#3314))
([0f72030](0f72030))
* **api:** LD-gated ClickHouse read switcher
([#3061](#3061))
([29e74ca](29e74ca))
* **api:** soft-delete build layers in DB on user delete
([#3121](#3121))
([ee88776](ee88776))
* **auth:** support admin token team auth
([#2934](#2934))
([5496666](5496666))
* **auth:** verifiers on one axis, and a reusable authenticator
constructor ([#3423](#3423))
([923b99b](923b99b))
* **dashboard-api:** add internal admin route for deleting a user
([#2986](#2986))
([ecc1291](ecc1291))
* **dashboard-api:** add internal team creation
([#2824](#2824))
([375051b](375051b))
* **dashboard-api:** add OIDC admin user bootstrap endpoint
([#2841](#2841))
([6a7a59e](6a7a59e))
* **dashboard-api:** add Ory user profile provider and auth middleware
fix ([#2840](#2840))
([30d40d2](30d40d2))
* **dashboard-api:** add template tags handlers
([#2885](#2885))
([bf52a4b](bf52a4b))
* **dashboard-api:** batch member sync route, and unenumerate
project_type ([#3427](#3427))
([cc16acf](cc16acf))
* **dashboard-api:** expose auth profile admin routes
([#2743](#2743))
([b673a10](b673a10))
* **dashboard-api:** flag sandboxes past data retention
([#3102](#3102))
([9b162bf](9b162bf))
* **dashboard-api:** implement upsertProjectLimits
([#3438](#3438))
([ec1ed29](ec1ed29))
* **dashboard-api:** include build resources in /builds response
([#3009](#3009))
([bf49c32](bf49c32))
* **dashboard-api:** map Ory SSO organizations to E2B teams
([#3094](#3094))
([dbd098f](dbd098f))
* **dashboard-api:** populate Ory identity external_id on admin
bootstrap ([#3062](#3062))
([6c51232](6c51232))
* **dashboard-api:** project upsert, member sync and user purge
([#3442](#3442))
([f997c39](f997c39))
* **dashboard-api:** templates list pagination
([#2904](#2904))
([6882463](6882463))
* **db:** add project_limits, an override the limits owner can write
([#3429](#3429))
([021c2a4](021c2a4))
* improve templates list sorting
([#2983](#2983))
([51ad7ff](51ad7ff))
* **otel:** instrument auth service HTTP client with otelhttp
([#2722](#2722))
([69b085d](69b085d))
* per-team events TTL limit (tier + addons)
([#3181](#3181))
([f76b2cb](f76b2cb))


### Bug Fixes

* added api and orch
([#3454](#3454))
([fda5e45](fda5e45))
* **api:** copy auth/internal into api and dashboard-api image builds
([#3323](#3323))
([bda1fee](bda1fee))
* **api:** invalidate auth cache on API key deletion
([#3324](#3324))
([8b02910](8b02910))
* correct 3 CVES ([#3218](#3218))
([076823b](076823b))
* **dashboard-api:** avoid repeated Ory bootstrap provisioning
([#2940](#2940))
([da5ce59](da5ce59))
* **dashboard-api:** drop removed read-replica accessor in provisioning
tests ([#3340](#3340))
([6addc91](6addc91))
* **dashboard-api:** pass signup metadata to billing provisioning
([#2978](#2978))
([d0ea5b4](d0ea5b4))
* **dashboard-api:** set Ory external_id only after the bootstrap commit
([#3133](#3133))
([00ad04b](00ad04b))
* push client-proxy, dashboard-api, and docker-reverse-proxy image…
([#2953](#2953))
([1d930ee](1d930ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: e2b-release-please[bot] <298072688+e2b-release-please[bot]@users.noreply.github.com>
Co-authored-by: Charlie Wyse <charlie.wyse@e2b.dev>
charlie-e2b pushed a commit that referenced this pull request Jul 31, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.0](dashboard-api-v0.0.1...dashboard-api-v0.1.0)
(2026-07-31)


### Features

* add workspace admin API foundations
([#3314](#3314))
([0f72030](0f72030))
* **api:** LD-gated ClickHouse read switcher
([#3061](#3061))
([29e74ca](29e74ca))
* **api:** soft-delete build layers in DB on user delete
([#3121](#3121))
([ee88776](ee88776))
* **auth:** support admin token team auth
([#2934](#2934))
([5496666](5496666))
* **auth:** verifiers on one axis, and a reusable authenticator
constructor ([#3423](#3423))
([923b99b](923b99b))
* **dashboard-api:** add internal admin route for deleting a user
([#2986](#2986))
([ecc1291](ecc1291))
* **dashboard-api:** add internal team creation
([#2824](#2824))
([375051b](375051b))
* **dashboard-api:** add OIDC admin user bootstrap endpoint
([#2841](#2841))
([6a7a59e](6a7a59e))
* **dashboard-api:** add Ory user profile provider and auth middleware
fix ([#2840](#2840))
([30d40d2](30d40d2))
* **dashboard-api:** add template tags handlers
([#2885](#2885))
([bf52a4b](bf52a4b))
* **dashboard-api:** batch member sync route, and unenumerate
project_type ([#3427](#3427))
([cc16acf](cc16acf))
* **dashboard-api:** expose auth profile admin routes
([#2743](#2743))
([b673a10](b673a10))
* **dashboard-api:** flag sandboxes past data retention
([#3102](#3102))
([9b162bf](9b162bf))
* **dashboard-api:** implement upsertProjectLimits
([#3438](#3438))
([ec1ed29](ec1ed29))
* **dashboard-api:** include build resources in /builds response
([#3009](#3009))
([bf49c32](bf49c32))
* **dashboard-api:** map Ory SSO organizations to E2B teams
([#3094](#3094))
([dbd098f](dbd098f))
* **dashboard-api:** populate Ory identity external_id on admin
bootstrap ([#3062](#3062))
([6c51232](6c51232))
* **dashboard-api:** project upsert, member sync and user purge
([#3442](#3442))
([f997c39](f997c39))
* **dashboard-api:** templates list pagination
([#2904](#2904))
([6882463](6882463))
* **db:** add project_limits, an override the limits owner can write
([#3429](#3429))
([021c2a4](021c2a4))
* improve templates list sorting
([#2983](#2983))
([51ad7ff](51ad7ff))
* **otel:** instrument auth service HTTP client with otelhttp
([#2722](#2722))
([69b085d](69b085d))
* per-team events TTL limit (tier + addons)
([#3181](#3181))
([f76b2cb](f76b2cb))


### Bug Fixes

* added api and orch
([#3454](#3454))
([fda5e45](fda5e45))
* **api:** copy auth/internal into api and dashboard-api image builds
([#3323](#3323))
([bda1fee](bda1fee))
* **api:** invalidate auth cache on API key deletion
([#3324](#3324))
([8b02910](8b02910))
* correct 3 CVES ([#3218](#3218))
([076823b](076823b))
* creating whitespace to test publish
([#3476](#3476))
([5158cc9](5158cc9))
* **dashboard-api:** avoid repeated Ory bootstrap provisioning
([#2940](#2940))
([da5ce59](da5ce59))
* **dashboard-api:** drop removed read-replica accessor in provisioning
tests ([#3340](#3340))
([6addc91](6addc91))
* **dashboard-api:** pass signup metadata to billing provisioning
([#2978](#2978))
([d0ea5b4](d0ea5b4))
* **dashboard-api:** set Ory external_id only after the bootstrap commit
([#3133](#3133))
([00ad04b](00ad04b))
* push client-proxy, dashboard-api, and docker-reverse-proxy image…
([#2953](#2953))
([1d930ee](1d930ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: e2b-release-please[bot] <298072688+e2b-release-please[bot]@users.noreply.github.com>
jakubno pushed a commit that referenced this pull request Aug 3, 2026
🤖 I have created a release *beep* *boop*
---


## 0.0.1 (2026-07-30)


### Features

* add workspace admin API foundations
([#3314](#3314))
([0f72030](0f72030))
* **api:** LD-gated ClickHouse read switcher
([#3061](#3061))
([29e74ca](29e74ca))
* **api:** soft-delete build layers in DB on user delete
([#3121](#3121))
([ee88776](ee88776))
* **auth:** support admin token team auth
([#2934](#2934))
([5496666](5496666))
* **auth:** verifiers on one axis, and a reusable authenticator
constructor ([#3423](#3423))
([f68e713](f68e713))
* **dashboard-api:** add internal admin route for deleting a user
([#2986](#2986))
([ecc1291](ecc1291))
* **dashboard-api:** add internal team creation
([#2824](#2824))
([375051b](375051b))
* **dashboard-api:** add OIDC admin user bootstrap endpoint
([#2841](#2841))
([6a7a59e](6a7a59e))
* **dashboard-api:** add Ory user profile provider and auth middleware
fix ([#2840](#2840))
([30d40d2](30d40d2))
* **dashboard-api:** add template tags handlers
([#2885](#2885))
([bf52a4b](bf52a4b))
* **dashboard-api:** batch member sync route, and unenumerate
project_type ([#3427](#3427))
([6d8dc38](6d8dc38))
* **dashboard-api:** expose auth profile admin routes
([#2743](#2743))
([b673a10](b673a10))
* **dashboard-api:** flag sandboxes past data retention
([#3102](#3102))
([9b162bf](9b162bf))
* **dashboard-api:** implement upsertProjectLimits
([#3438](#3438))
([f4ee390](f4ee390))
* **dashboard-api:** include build resources in /builds response
([#3009](#3009))
([bf49c32](bf49c32))
* **dashboard-api:** map Ory SSO organizations to E2B teams
([#3094](#3094))
([dbd098f](dbd098f))
* **dashboard-api:** populate Ory identity external_id on admin
bootstrap ([#3062](#3062))
([6c51232](6c51232))
* **dashboard-api:** project upsert, member sync and user purge
([#3442](#3442))
([8c90702](8c90702))
* **dashboard-api:** templates list pagination
([#2904](#2904))
([6882463](6882463))
* **db:** add project_limits, an override the limits owner can write
([#3429](#3429))
([5ab6259](5ab6259))
* improve templates list sorting
([#2983](#2983))
([51ad7ff](51ad7ff))
* **otel:** instrument auth service HTTP client with otelhttp
([#2722](#2722))
([69b085d](69b085d))
* per-team events TTL limit (tier + addons)
([#3181](#3181))
([f76b2cb](f76b2cb))


### Bug Fixes

* added api and orch
([#3454](#3454))
([d56e0a8](d56e0a8))
* **api:** copy auth/internal into api and dashboard-api image builds
([#3323](#3323))
([bda1fee](bda1fee))
* **api:** invalidate auth cache on API key deletion
([#3324](#3324))
([8b02910](8b02910))
* correct 3 CVES ([#3218](#3218))
([076823b](076823b))
* **dashboard-api:** avoid repeated Ory bootstrap provisioning
([#2940](#2940))
([da5ce59](da5ce59))
* **dashboard-api:** drop removed read-replica accessor in provisioning
tests ([#3340](#3340))
([6addc91](6addc91))
* **dashboard-api:** pass signup metadata to billing provisioning
([#2978](#2978))
([d0ea5b4](d0ea5b4))
* **dashboard-api:** set Ory external_id only after the bootstrap commit
([#3133](#3133))
([00ad04b](00ad04b))
* push client-proxy, dashboard-api, and docker-reverse-proxy image…
([#2953](#2953))
([1d930ee](1d930ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: e2b-release-please[bot] <298072688+e2b-release-please[bot]@users.noreply.github.com>
Co-authored-by: Charlie Wyse <charlie.wyse@e2b.dev>
jakubno pushed a commit that referenced this pull request Aug 3, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.0](dashboard-api-v0.0.1...dashboard-api-v0.1.0)
(2026-07-31)


### Features

* add workspace admin API foundations
([#3314](#3314))
([0f72030](0f72030))
* **api:** LD-gated ClickHouse read switcher
([#3061](#3061))
([29e74ca](29e74ca))
* **api:** soft-delete build layers in DB on user delete
([#3121](#3121))
([ee88776](ee88776))
* **auth:** support admin token team auth
([#2934](#2934))
([5496666](5496666))
* **auth:** verifiers on one axis, and a reusable authenticator
constructor ([#3423](#3423))
([f68e713](f68e713))
* **dashboard-api:** add internal admin route for deleting a user
([#2986](#2986))
([ecc1291](ecc1291))
* **dashboard-api:** add internal team creation
([#2824](#2824))
([375051b](375051b))
* **dashboard-api:** add OIDC admin user bootstrap endpoint
([#2841](#2841))
([6a7a59e](6a7a59e))
* **dashboard-api:** add Ory user profile provider and auth middleware
fix ([#2840](#2840))
([30d40d2](30d40d2))
* **dashboard-api:** add template tags handlers
([#2885](#2885))
([bf52a4b](bf52a4b))
* **dashboard-api:** batch member sync route, and unenumerate
project_type ([#3427](#3427))
([6d8dc38](6d8dc38))
* **dashboard-api:** expose auth profile admin routes
([#2743](#2743))
([b673a10](b673a10))
* **dashboard-api:** flag sandboxes past data retention
([#3102](#3102))
([9b162bf](9b162bf))
* **dashboard-api:** implement upsertProjectLimits
([#3438](#3438))
([f4ee390](f4ee390))
* **dashboard-api:** include build resources in /builds response
([#3009](#3009))
([bf49c32](bf49c32))
* **dashboard-api:** map Ory SSO organizations to E2B teams
([#3094](#3094))
([dbd098f](dbd098f))
* **dashboard-api:** populate Ory identity external_id on admin
bootstrap ([#3062](#3062))
([6c51232](6c51232))
* **dashboard-api:** project upsert, member sync and user purge
([#3442](#3442))
([8c90702](8c90702))
* **dashboard-api:** templates list pagination
([#2904](#2904))
([6882463](6882463))
* **db:** add project_limits, an override the limits owner can write
([#3429](#3429))
([5ab6259](5ab6259))
* improve templates list sorting
([#2983](#2983))
([51ad7ff](51ad7ff))
* **otel:** instrument auth service HTTP client with otelhttp
([#2722](#2722))
([69b085d](69b085d))
* per-team events TTL limit (tier + addons)
([#3181](#3181))
([f76b2cb](f76b2cb))


### Bug Fixes

* added api and orch
([#3454](#3454))
([d56e0a8](d56e0a8))
* **api:** copy auth/internal into api and dashboard-api image builds
([#3323](#3323))
([bda1fee](bda1fee))
* **api:** invalidate auth cache on API key deletion
([#3324](#3324))
([8b02910](8b02910))
* correct 3 CVES ([#3218](#3218))
([076823b](076823b))
* creating whitespace to test publish
([#3476](#3476))
([6b4177f](6b4177f))
* **dashboard-api:** avoid repeated Ory bootstrap provisioning
([#2940](#2940))
([da5ce59](da5ce59))
* **dashboard-api:** drop removed read-replica accessor in provisioning
tests ([#3340](#3340))
([6addc91](6addc91))
* **dashboard-api:** pass signup metadata to billing provisioning
([#2978](#2978))
([d0ea5b4](d0ea5b4))
* **dashboard-api:** set Ory external_id only after the bootstrap commit
([#3133](#3133))
([00ad04b](00ad04b))
* push client-proxy, dashboard-api, and docker-reverse-proxy image…
([#2953](#2953))
([1d930ee](1d930ee))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: e2b-release-please[bot] <298072688+e2b-release-please[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants