Skip to content

feat: add workspace admin API foundations - #3314

Merged
ben-fornefeld merged 9 commits into
mainfrom
workspaces-m1-foundations
Jul 21, 2026
Merged

feat: add workspace admin API foundations#3314
ben-fornefeld merged 9 commits into
mainfrom
workspaces-m1-foundations

Conversation

@ben-fornefeld

@ben-fornefeld ben-fornefeld commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

This PR lays the groundwork for the Workspaces & Projects v1 admin surface and restructures the shared auth package behind a stable public facade.

  • Adds the dashboard-api /admin/v1 OpenAPI surface and generated handlers for workspace administration.
  • Adds AdminJWTAuth for short-lived service JWTs configured through ADMIN_AUTH_PROVIDER_CONFIG.
  • Keeps the consumer API under packages/auth/pkg/auth while moving implementation into focused Go internal packages.
  • Shares one ProviderConfig shape between AUTH_PROVIDER_CONFIG and ADMIN_AUTH_PROVIDER_CONFIG.

Motivation

The dashboard-api needs to verify service-to-service JWTs for workspace admin endpoints, while the API already verifies auth-provider tokens. Both flows need shared configuration and JWKS validation without exposing implementation packages or forcing consumers to import token internals.

The public auth package is now a facade, so callers continue using APIs such as auth.NewAuthService, auth.NewAdminVerifier, and the existing middleware constructors while implementation details remain protected by Go's internal boundary.

Changes

Auth package

  • Keeps packages/auth/pkg/auth as the stable consumer-facing facade.
  • Moves implementation into internal/authcontext, internal/middleware, internal/service, internal/team, internal/token, internal/token/jwks, and internal/token/oidc.
  • Re-exports the supported configuration, verifier, service, middleware, team-policy, context, error, and testing APIs through auth.
  • Prevents consumers from importing token, JWKS, OIDC, cache, store, and middleware internals directly.

JWT and JWKS verification

  • Adds auth.NewAdminVerifier for multi-issuer admin service JWT verification.
  • Loads admin keys directly from each issuer's /.well-known/jwks.json endpoint.
  • Requires every signing JWK to declare alg and derives accepted JWT signing methods from current JWKS storage.
  • Refreshes the valid-method allowlist together with JWKS key refreshes, allowing algorithm rotations without restarting the service.
  • Preserves OIDC discovery and identity resolution for auth-provider user tokens.

Configuration

  • AUTH_PROVIDER_CONFIG configures user auth-provider JWTs.
  • ADMIN_AUTH_PROVIDER_CONFIG configures admin service JWTs using the same ProviderConfig JSON shape.
  • Dashboard-api fails fast on invalid configured issuers and rejects AdminJWTAuth requests when no admin provider is configured.

Dashboard API

  • Adds the workspace-agnostic /admin/v1 OpenAPI operations and AdminJWTAuth security scheme.
  • Registers API-key and service-JWT admin authenticators through the public auth facade.
  • Keeps existing auth-provider bearer and team authentication flows unchanged.

Usage example

{
  "jwt": [
    {
      "issuer": {
        "url": "https://workspace-api.example.com",
        "audiences": ["e2b-dashboard-api"]
      },
      "cacheDuration": "5m"
    }
  ]
}

Set this JSON as ADMIN_AUTH_PROVIDER_CONFIG for admin service JWTs or as AUTH_PROVIDER_CONFIG for auth-provider JWTs.

Testing

  • go test ./packages/auth/...
  • go test ./packages/api/internal/cfg/...
  • go test ./packages/dashboard-api/...
  • golangci-lint run ./packages/auth/... ./packages/api/... ./packages/dashboard-api/...
  • go build ./packages/api/... ./packages/dashboard-api/...

Add /admin/v1 workspace-admin endpoints (project, member, limits, user
purge) to the dashboard OpenAPI contract with 501 stub handlers.

Introduce a generic pkg/auth/jwks package (issuer config, OIDC
discovery, JWKS-backed JWT verification) extracted from the oidc
package, which is now a thin identity-resolution layer. The new
AdminJWTAuth security scheme verifies EdDSA service JWTs configured
via ADMIN_AUTH_CONFIG, sharing the auth.ProviderConfig shape with
AUTH_PROVIDER_CONFIG.
- Move jwks, oidc, provider config parsing, admin verifier, and provider
  verifier from packages/auth/pkg/auth to packages/auth/pkg/token.
- Rename Verifier/AdminJWTVerifier types to Provider/AdminVerifier.
- Update auth package service, middleware, and identity lookup to consume
  the new token package.
- Update api and dashboard-api config/model imports to use token package.
@cursor

cursor Bot commented Jul 20, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches authentication middleware and JWT/JWKS validation paths used at request time; misconfiguration or verifier bugs could deny admin traffic or weaken token checks, though behavior is covered by tests and unimplemented handlers limit data-plane impact.

Overview
Introduces workspace control-plane admin routes on the dashboard API secured by AdminJWTAuth, backed by a new ADMIN_AUTH_PROVIDER_CONFIG that reuses the same JSON shape as user auth-provider JWT settings. Shared auth is reorganized behind the public auth facade with implementation in internal packages, while JWT verification is split so admin service tokens validate via issuer /.well-known/jwks.json, require each JWK to declare alg, and refresh allowed signing methods with JWKS rotation; user OIDC tokens still use discovery plus identity lookup. The new /admin/v1 operations are wired in OpenAPI and routing but currently respond with 501 Not Implemented.

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

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/api/internal/cfg/model.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@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

This pull request introduces the AdminJWTAuth security scheme to secure workspace-agnostic /admin/v1 operations in the dashboard API. It refactors the authentication package by separating generic JWKS token verification into a new jwks package and OIDC-specific identity lookup into an oidc package. Additionally, it defines the new admin endpoints in the OpenAPI specification, registers the corresponding middleware, and adds placeholder handlers. Feedback is provided to add a defensive nil check in the OIDC verifier's Verify method to prevent potential nil pointer dereferences.

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/auth/internal/token/oidc/oidc.go

@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.

No bugs found, but I'd recommend a human review given this touches auth/JWT verification code and introduces a new admin API surface.

Extended reasoning...

Overview

This PR does two things: (1) extracts JWT/OIDC verification code from packages/auth/pkg/auth into a new packages/auth/pkg/token package (with jwks and oidc sub-packages), shared between api and dashboard-api; and (2) adds a new /admin/v1 OpenAPI surface to dashboard-api for workspace/project control-plane administration, authenticated via a new AdminJWTAuth scheme backed by token.AdminVerifier (multi-issuer EdDSA service JWTs). All six new admin handlers are stubbed to return 501 Not Implemented, so no real admin logic ships yet.

Security risks

This is squarely auth-adjacent code: JWT signature verification, audience validation, and a new bearer-auth scheme protecting future workspace-admin write operations (project upsert/delete, membership, limits, user purge). The refactor itself appears to preserve behavior (the old Verifier.Verify logic was split into a claims-only jwks.Verifier plus an OIDC identity-resolution wrapper, and tests were moved/updated accordingly), and AdminVerifier correctly restricts to EdDSA and forces expiration/leeway. Since the concrete handlers are all not-implemented stubs, there's no immediate authz-bypass surface live yet, but the shape of AdminJWTAuth (accepting any of a list of configured issuers, verified but with no further scoping shown in this PR) is worth a human's attention before real handler logic lands on top of it.

Level of scrutiny

Given this touches shared authentication/verification code used by both api and dashboard-api, and lands the auth scheme for a new administrative API, I'd apply high scrutiny — this is exactly the kind of change (auth, JWT handling) called out as warranting human review rather than automated approval, even though the bug-hunting pass found nothing and the moved code is well covered by existing/updated unit tests.

Other factors

No CODEOWNERS conflicts were surfaced, and the diff is large (28 files) mixing a mechanical rename/move with genuinely new security-relevant surface (new security scheme, new config env var ADMIN_AUTH_CONFIG). The bug-hunting system found no issues, and one candidate doc-consistency concern in ARCHITECTURE.md was already investigated and ruled out. Test coverage for the moved/new verifier code looks solid (audience matching, expiry, wrong-signing-method rejection, disabled-config nil-verifier handling).

…startup warning

- Add optional algorithm enum (EdDSA/ES256) to jwks.Issuer.

- Validate supported algorithms during config validation.

- Enforce the configured algorithm in jwks.Verifier.

- Default admin JWT issuers to EdDSA when no algorithm is set.

- Log a startup warning when dashboard-api ADMIN_AUTH_CONFIG is empty while /admin/v1 routes are compiled in.

- Add tests for algorithm validation and ES256 admin JWT verification.
@ben-fornefeld ben-fornefeld changed the title Workspace admin foundations: admin API skeleton + auth token package refactor feat: add workspace admin API foundations Jul 21, 2026
Comment thread packages/auth/internal/token/admin.go
Comment thread packages/auth/internal/token/jwks/verifier.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.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

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

Reviewed by Cursor Bugbot for commit b1f4a77. Configure here.

Comment thread packages/auth/internal/token/jwks/verifier.go Outdated
@ben-fornefeld
ben-fornefeld merged commit 0f72030 into main Jul 21, 2026
47 checks passed
@ben-fornefeld
ben-fornefeld deleted the workspaces-m1-foundations branch July 21, 2026 11:44
tomassrnka added a commit that referenced this pull request Jul 21, 2026
…3323)

## Problem

`Build and upload images` has been failing on main for every environment
since #3314 merged (first red run:
[29827113375](https://github.com/e2b-dev/infra/actions/runs/29827113375),
still red on the next push:
[29827995997](https://github.com/e2b-dev/infra/actions/runs/29827995997)).
No images have shipped since ~07:04 UTC and the staging envd promote
hasn't run.

#3314 refactored `packages/auth` so the public `pkg/auth` package
re-exports from new `packages/auth/internal/*` packages (`service`,
`team`, `token`, `token/jwks`, `middleware`, `authcontext`). The api
image build copies the auth module selectively — `COPY ./auth/pkg
./auth/pkg` only — so `make build` inside the container fails:

```
../auth/pkg/auth/service.go:9:2: no required module provides package github.com/e2b-dev/infra/packages/auth/internal/service
```

PR CI can't catch this class of breakage: unit/integration tests build
from a full checkout, and the image Dockerfiles only build post-merge in
`build-and-upload-images.yml`.

## Fix

Add `COPY ./auth/internal ./auth/internal` next to the existing
`auth/pkg` copy in:

- `packages/api/Dockerfile` (actively failing)
- `packages/dashboard-api/Dockerfile` (same bug, latent — fails as soon
as that image is built)

`auth/internal` only imports `db/pkg` and `shared/pkg`, which both
Dockerfiles already copy, so nothing else is needed.

## Verification

Replicated the exact Docker build context (only the `COPY`'d paths, no
`go.work`) in a clean directory with go 1.26.5 and `CGO_ENABLED=0
GOOS=linux`:

- **With this fix**: `go build` succeeds for both api and dashboard-api
- **Without `auth/internal`** (negative control): reproduces the exact
CI error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/e2b-dev/codesmith/infra/pr/3323"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img
alt="View with Codesmith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787227846&installation_model_id=14389&pr_number=3323&repository=e2b-dev%2Finfra&return_to=https%3A%2F%2Fgithub.com%2Fe2b-dev%2Finfra%2Fpull%2F3323&signature=64edf20a2f3d46ecdbaf5674ca6dcc1d5ebd7d5c5ea1ad87289c0dc652162483"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img
alt="Autofix with Codesmith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>
<sup>Need help on this PR? Tag <code>/codesmith</code> with what you
need. Autofix is disabled.</sup>

<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
ben-fornefeld added a commit that referenced this pull request Jul 22, 2026
…facade

External consumers (belt) previously imported pkg/auth/oidc directly
(oidc.NewVerifier, oidc.IdentityLookup, oidc.ErrIdentityNotFound) and used
auth.Verifier/auth.NewVerifier from the old facade. Both surfaces were
removed in #3314, which breaks belt's daily infra sync at go mod tidy
(module found, but does not contain package .../pkg/auth/oidc) and at
compile time in argus-api.

Expose the equivalents on the auth facade so all consumers use auth.*:

- IdentityLookup, ErrIdentityNotFound
- OIDCVerifier, NewOIDCVerifier (single issuer)
- ProviderVerifier, NewProviderVerifier (multi-issuer, keeps the
  (nil, nil) no-provider semantics of the old auth.NewVerifier)

Config/issuer types were already re-exported as JWTConfig/JWTIssuer.
ben-fornefeld added a commit that referenced this pull request Jul 22, 2026
Move packages/auth/internal/* to packages/auth/pkg/auth/internal/* so the
implementation lives inside the consumer-facing pkg tree. Consumers keep
importing the stable facade at .../packages/auth/pkg/auth.

Go's internal visibility now scopes the implementation to pkg/auth alone
(pkg/types and pkg/tests can no longer reach it), and image builds that
COPY ./auth/pkg pick up the implementation for free — drop the separate
./auth/internal COPY that #3323 added to unbreak image builds after #3314.
ben-fornefeld added a commit that referenced this pull request Jul 22, 2026
…facade (#3339)

## Summary

Restores the auth surface external consumers lost in #3314, without
touching the package layout.

Belt imports this module and used `pkg/auth/oidc` (`oidc.NewVerifier`,
`oidc.IdentityLookup`, `oidc.ErrIdentityNotFound`) plus the old facade's
`auth.Verifier`/`auth.NewVerifier`. #3314 moved both behind Go
`internal` packages, so belt's daily `sync-infra-repo` workflow fails at
`go mod tidy`:

> module …/packages/auth found, but does not contain package
…/packages/auth/pkg/auth/oidc

This PR re-exports the equivalents through the `auth.*` facade with
identical signatures:

- `auth.IdentityLookup`, `auth.ErrIdentityNotFound`
- `auth.OIDCVerifier` / `auth.NewOIDCVerifier` (single issuer)
- `auth.ProviderVerifier` / `auth.NewProviderVerifier` (multi-issuer;
keeps the `(nil, nil)` no-provider semantics of the old
`auth.NewVerifier`)

Config/issuer types were already exposed as
`auth.JWTConfig`/`auth.JWTIssuer`.

Companion belt PR migrating its imports to the facade:
e2b-dev/belt#1145. A follow-up PR (#3338) restructures the auth package
layout separately.

## Testing

- `go build ./… && go vet ./… && go test ./…` in `packages/auth`
- `golangci-lint run ./packages/auth/…` — 0 issues
- Belt compiled and tested against this commit (all 16 workspace modules
build; `shared/pkg/auth`, `billing-server/internal/auth`,
`argus-api/internal/handlers` green with `-race`)

<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/e2b-dev/codesmith/infra/pr/3339"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img
alt="View with Codesmith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787336953&installation_model_id=14389&pr_number=3339&repository=e2b-dev%2Finfra&return_to=https%3A%2F%2Fgithub.com%2Fe2b-dev%2Finfra%2Fpull%2F3339&signature=5551f98aca8e66952d8160dd7d79e3502f3e6cd0cc1c464e571035de4efef169"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img
alt="Autofix with Codesmith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>
<sup>Need help on this PR? Tag <code>/codesmith</code> with what you
need. Autofix is disabled.</sup>

<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
tvi pushed a commit that referenced this pull request Jul 22, 2026
## Summary

Stacked on #3339 (facade re-exports — the belt unblocker); this PR is
the layout change only. Retarget to `main` after #3339 merges.

Moves `packages/auth/internal/*` → `packages/auth/pkg/auth/internal/*`
(history-preserving renames; import paths and otel tracer names
updated). Consumers keep using the stable facade at
`github.com/e2b-dev/infra/packages/auth/pkg/auth` — nothing outside the
auth module changes except two Dockerfile lines.

Also removes the `COPY ./auth/internal ./auth/internal` lines from the
api and dashboard-api Dockerfiles that #3323 added: with the
implementation nested under `pkg/auth`, the existing `COPY ./auth/pkg`
carries it, and the stale COPY would fail on a now-missing path.

## Motivation

#3314 placed implementation packages at `packages/auth/internal`,
outside `pkg/`. The api/dashboard-api image builds copy the auth module
selectively (`COPY ./auth/pkg`), so post-merge image builds broke and
#3323 hot-fixed them with an extra COPY. This class of breakage is only
detectable post-merge (PR CI builds from a full checkout; Dockerfiles
build only in `build-and-upload-images.yml`), so every current and
future `pkg`-only copier must remember the extra line. Nesting internals
under `pkg/auth` makes any `pkg`-only copy self-contained and deletes
the failure mode structurally.

It also tightens Go's internal boundary: only the `pkg/auth` facade can
reach the implementation now (previously any package under
`packages/auth/`, e.g. `pkg/types`/`pkg/tests`, could).

## Testing

- `go build ./… && go vet ./… && go test ./…` in `packages/auth`;
`golangci-lint run ./packages/auth/…` — 0 issues
- `go build ./packages/api/… ./packages/dashboard-api/…`
- Replicated both Docker build contexts (only COPY'd paths, no
`go.work`, `CGO_ENABLED=0 GOOS=linux`): api and dashboard-api build OK —
the exact scenario that broke after #3314
- Simulated an external module consumer (`GOWORK=off`, path replaces):
facade import builds; direct import of `pkg/auth/internal/…` is rejected
by the compiler as intended
ben-fornefeld added a commit that referenced this pull request Jul 28, 2026
…_type (#3427)

Completes the `/v1/management` contract against its one caller, `belt`'s
`workspace-api`. Every operation it invokes now has a definition here.
Two did not line up.

## 1. The missing route

`POST /v1/management/projects/{teamID}/members/batch` — the bulk path
behind group and directory fan-outs, where the per-member routes cost
one request each.

The caller already sends this. Its client is hand-written precisely
because there was nothing here to generate from, so the schema is taken
from the bytes it puts on the wire rather than designed fresh:

```json
[{"user_id": "…", "present": true}, {"user_id": "…", "present": false}]
```

Presence is **stated** rather than implied by inclusion, so one request
carries both additions and removals and entries converge in any order.
`maxItems: 1024` matches the chunk size the caller already uses. Stubbed
`501` like its five siblings — serving it is separate work.

## 2. The mismatch that was breaking provisioning

`AdminControlPlaneProjectType` enumerated `development | staging |
production`, from the scaffolding in #3314 — written before any caller
existed.

The caller sends tier names (`base_v1`, `pro_v1`) and gates on the
generated `Valid()` *before opening a connection*:

```go
projectType := managementapi.AdminControlPlaneProjectType(project.ProjectType)
if !projectType.Valid() {
    return fmt.Errorf("%q: %w", project.ProjectType, ErrInvalidProjectType)
}
```

So **every project upsert failed client-side and no request ever arrived
here.** Signup's default type is `base_v1`, so this was every project.

The enum is now gone. Nothing on this side reads the value — there is no
column for it, and limits arrive in full and explicitly through
`upsertProjectLimits`. Enumerating a field we only record would make
adding a tier a cross-repo change to a value we never interpret, so the
caller keeps its vocabulary and this keeps a `string` with `minLength:
1`.

## Tests

The batch caller is hand-written, so nothing but a test keeps the two
sides in step:

- The batch request decodes from the literal JSON that caller emits.
- An upsert decodes with real tier names, which fails if someone
reintroduces a closed set guessing at the caller's vocabulary.
- `/members/batch` is not swallowed by the `/members/{userId}` parameter
beside it — driven through the real router, asserting which handler ran.

The first is mutation-verified: renaming the property in the spec breaks
the build.

## Coordination

**This needs a companion `belt` change before the spec syncs.**
`Valid()` does not exist on a plain string, which is one compile error
at `controlplanes/management.go:76`. Verified by regenerating belt's
client against this spec:

```
internal/controlplanes/management.go:76:18: projectType.Valid undefined
```

Loud and single-line, which is the right failure mode — but it should
land alongside.

## Verification

Builds, vets, tests and `golangci-lint` clean in `dashboard-api`.
Contract diff confirms 1:1 coverage: seven caller operations, seven
definitions, no orphans either direction.

No `ARCHITECTURE.md` change — it describes the `/v1/management` surface
and its auth without enumerating operations, and neither is altered.
charlie-e2b pushed 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:** add admin team API key routes
([#2825](#2825))
([4a1e083](4a1e083))
* **api:** add feature flag to stop accepting E2B access tokens
([#3240](#3240))
([2cf489b](2cf489b))
* **api:** add sandbox fork endpoint
([#3202](#3202))
([643d726](643d726))
* **api:** add sandbox IAM workload token configuration
([13ddb3d](13ddb3d))
* **api:** add sandbox workload identity permission
([#3319](#3319))
([13ddb3d](13ddb3d))
* **api:** add user agent integration attribution to PostHog events
([#3303](#3303))
([d83be18](d83be18))
* **api:** discover orchestrators via nomad service
([#3176](#3176))
([32af250](32af250))
* **api:** e2b access token deprecation feature flag rename
([#3110](#3110))
([ebc2daa](ebc2daa))
* **api:** enforce blocked-team restrictions at mutating API endpoints
([#2659](#2659))
([db848ab](db848ab))
* **api:** filter snapshots by name
([#3184](#3184))
([6fa1bc7](6fa1bc7))
* **api:** gate access token issuance behind feature flag
([#3101](#3101))
([2f7811e](2f7811e))
* **api:** LD-gated ClickHouse read switcher
([#3061](#3061))
([29e74ca](29e74ca))
* **api:** limit template build name to 128 characters
([#3109](#3109))
([84aa186](84aa186))
* **api:** paginated GET /v2/templates (EN-603)
([#3059](#3059))
([91e02e4](91e02e4))
* **api:** per-region volume type defaults from node-derived region
([#3435](#3435))
([baf5559](baf5559))
* **api:** pin resume retries to the node a previous resume timed out on
([#3066](#3066))
([a4fd0f2](a4fd0f2))
* **api:** SOCKS5 egress proxy on sandbox network config (BYOP)
([#2642](#2642))
([1fc3820](1fc3820))
* **api:** soft-delete build layers in DB on user delete
([#3121](#3121))
([ee88776](ee88776))
* **auth:** support admin token team auth
([#2934](#2934))
([5496666](5496666))
* dynamic sandbox log routing and ClickHouse-backed log reads
([#3236](#3236))
([1b19a3b](1b19a3b))
* **evictor:** make max concurrent evictions a feature flag
([#2727](#2727))
([0b33013](0b33013))
* **metrics:** distinguish joined from regular requests (ENG-4072)
([#2699](#2699))
([390e296](390e296))
* **observability:** add kill_reason to sandbox.lifecycle.killed
([#2833](#2833))
([e45418f](e45418f))
* **observability:** include kill_reason in kill-path structured logs
([#2846](#2846))
([33c49f7](33c49f7))
* **orchestrator:** add dummy orchestrator binary for local API dev
([#2744](#2744))
([ab56e25](ab56e25))
* **orchestrator:** report hugepage metrics to API
([#3182](#3182))
([7735bae](7735bae))
* **orchestrator:** track and report last status change timestamp
([#2980](#2980))
([f79be77](f79be77))
* **otel:** instrument auth service HTTP client with otelhttp
([#2722](#2722))
([69b085d](69b085d))
* per-team events TTL limit (tier + addons)
([#3181](#3181))
([f76b2cb](f76b2cb))
* **storage:** stamp provenance custom metadata on uploaded objects
(incl. headers) ([#3033](#3033))
([ba8604e](ba8604e))


### Bug Fixes

* added api and orch
([#3454](#3454))
([fda5e45](fda5e45))
* **api:** check template alias tags in exists endpoint
([#2916](#2916))
([9574cdf](9574cdf))
* **api:** copy auth/internal into api and dashboard-api image builds
([#3323](#3323))
([bda1fee](bda1fee))
* **api:** discover the local orchestrator as a template builder
([#3386](#3386))
([9ea005a](9ea005a))
* **api:** expose pagination headers via CORS
([#3388](#3388))
([e832b1e](e832b1e))
* **api:** handle corrupted data in sandbox stop time
([#3203](#3203))
([a98a178](a98a178))
* **api:** include exhaustion reason in "Node exhausted" placement
warning ([#3279](#3279))
([eb3797b](eb3797b))
* **api:** invalidate auth cache on API key deletion
([#3324](#3324))
([8b02910](8b02910))
* **api:** keep API alive until in-flight requests finish
([#2708](#2708))
([06378c7](06378c7))
* **api:** let the analytics collector address carry a port
([#3394](#3394))
([6d41cb5](6d41cb5))
* **api:** parse the pause body regardless of Content-Length
([#3056](#3056))
([d66aab8](d66aab8))
* **api:** prevent uint64 underflow in node allocated metrics
([#3216](#3216))
([fed38e1](fed38e1))
* **api:** push api and db-migrator images to both latest and commit S…
([#2951](#2951))
([6f010fc](6f010fc))
* **api:** reject non-positive timeout on sandbox create, resume, and
fork ([#3419](#3419))
([b672bd1](b672bd1))
* **api:** report invalid tag errors as bad requests
([#2799](#2799))
([10085a1](10085a1))
* **api:** stop evicting the local node during sync
([#2881](#2881))
([5455905](5455905))
* **api:** use correct error variable in processCustomErrors
([#3135](#3135))
([a131a00](a131a00))
* **auth:** rename X-Team-Id header to X-Team-ID
([#2723](#2723))
([f92ecc0](f92ecc0))
* correct 3 CVES ([#3218](#3218))
([076823b](076823b))
* **orchestrator:** reject standby while draining
([#3325](#3325))
([475a7ee](475a7ee))
* Support snapshots for non-default clusters
([#2947](#2947))
([28eeb72](28eeb72))


### Performance Improvements

* **api:** wake reservation waiters via pub/sub instead of 20ms polling
[ENG-4070] ([#2729](#2729))
([2944d06](2944d06))

---
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>
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
…_type (#3427)

Completes the `/v1/management` contract against its one caller, `belt`'s
`workspace-api`. Every operation it invokes now has a definition here.
Two did not line up.

## 1. The missing route

`POST /v1/management/projects/{teamID}/members/batch` — the bulk path
behind group and directory fan-outs, where the per-member routes cost
one request each.

The caller already sends this. Its client is hand-written precisely
because there was nothing here to generate from, so the schema is taken
from the bytes it puts on the wire rather than designed fresh:

```json
[{"user_id": "…", "present": true}, {"user_id": "…", "present": false}]
```

Presence is **stated** rather than implied by inclusion, so one request
carries both additions and removals and entries converge in any order.
`maxItems: 1024` matches the chunk size the caller already uses. Stubbed
`501` like its five siblings — serving it is separate work.

## 2. The mismatch that was breaking provisioning

`AdminControlPlaneProjectType` enumerated `development | staging |
production`, from the scaffolding in #3314 — written before any caller
existed.

The caller sends tier names (`base_v1`, `pro_v1`) and gates on the
generated `Valid()` *before opening a connection*:

```go
projectType := managementapi.AdminControlPlaneProjectType(project.ProjectType)
if !projectType.Valid() {
    return fmt.Errorf("%q: %w", project.ProjectType, ErrInvalidProjectType)
}
```

So **every project upsert failed client-side and no request ever arrived
here.** Signup's default type is `base_v1`, so this was every project.

The enum is now gone. Nothing on this side reads the value — there is no
column for it, and limits arrive in full and explicitly through
`upsertProjectLimits`. Enumerating a field we only record would make
adding a tier a cross-repo change to a value we never interpret, so the
caller keeps its vocabulary and this keeps a `string` with `minLength:
1`.

## Tests

The batch caller is hand-written, so nothing but a test keeps the two
sides in step:

- The batch request decodes from the literal JSON that caller emits.
- An upsert decodes with real tier names, which fails if someone
reintroduces a closed set guessing at the caller's vocabulary.
- `/members/batch` is not swallowed by the `/members/{userId}` parameter
beside it — driven through the real router, asserting which handler ran.

The first is mutation-verified: renaming the property in the spec breaks
the build.

## Coordination

**This needs a companion `belt` change before the spec syncs.**
`Valid()` does not exist on a plain string, which is one compile error
at `controlplanes/management.go:76`. Verified by regenerating belt's
client against this spec:

```
internal/controlplanes/management.go:76:18: projectType.Valid undefined
```

Loud and single-line, which is the right failure mode — but it should
land alongside.

## Verification

Builds, vets, tests and `golangci-lint` clean in `dashboard-api`.
Contract diff confirms 1:1 coverage: seven caller operations, seven
definitions, no orphans either direction.

No `ARCHITECTURE.md` change — it describes the `/v1/management` surface
and its auth without enumerating operations, and neither is altered.
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:** add admin team API key routes
([#2825](#2825))
([4a1e083](4a1e083))
* **api:** add feature flag to stop accepting E2B access tokens
([#3240](#3240))
([2cf489b](2cf489b))
* **api:** add sandbox fork endpoint
([#3202](#3202))
([643d726](643d726))
* **api:** add sandbox IAM workload token configuration
([13ddb3d](13ddb3d))
* **api:** add sandbox workload identity permission
([#3319](#3319))
([13ddb3d](13ddb3d))
* **api:** add user agent integration attribution to PostHog events
([#3303](#3303))
([d83be18](d83be18))
* **api:** discover orchestrators via nomad service
([#3176](#3176))
([32af250](32af250))
* **api:** e2b access token deprecation feature flag rename
([#3110](#3110))
([ebc2daa](ebc2daa))
* **api:** enforce blocked-team restrictions at mutating API endpoints
([#2659](#2659))
([db848ab](db848ab))
* **api:** filter snapshots by name
([#3184](#3184))
([6fa1bc7](6fa1bc7))
* **api:** gate access token issuance behind feature flag
([#3101](#3101))
([2f7811e](2f7811e))
* **api:** LD-gated ClickHouse read switcher
([#3061](#3061))
([29e74ca](29e74ca))
* **api:** limit template build name to 128 characters
([#3109](#3109))
([84aa186](84aa186))
* **api:** paginated GET /v2/templates (EN-603)
([#3059](#3059))
([91e02e4](91e02e4))
* **api:** per-region volume type defaults from node-derived region
([#3435](#3435))
([1bded44](1bded44))
* **api:** pin resume retries to the node a previous resume timed out on
([#3066](#3066))
([a4fd0f2](a4fd0f2))
* **api:** SOCKS5 egress proxy on sandbox network config (BYOP)
([#2642](#2642))
([1fc3820](1fc3820))
* **api:** soft-delete build layers in DB on user delete
([#3121](#3121))
([ee88776](ee88776))
* **auth:** support admin token team auth
([#2934](#2934))
([5496666](5496666))
* dynamic sandbox log routing and ClickHouse-backed log reads
([#3236](#3236))
([1b19a3b](1b19a3b))
* **evictor:** make max concurrent evictions a feature flag
([#2727](#2727))
([0b33013](0b33013))
* **metrics:** distinguish joined from regular requests (ENG-4072)
([#2699](#2699))
([390e296](390e296))
* **observability:** add kill_reason to sandbox.lifecycle.killed
([#2833](#2833))
([e45418f](e45418f))
* **observability:** include kill_reason in kill-path structured logs
([#2846](#2846))
([33c49f7](33c49f7))
* **orchestrator:** add dummy orchestrator binary for local API dev
([#2744](#2744))
([ab56e25](ab56e25))
* **orchestrator:** report hugepage metrics to API
([#3182](#3182))
([7735bae](7735bae))
* **orchestrator:** track and report last status change timestamp
([#2980](#2980))
([f79be77](f79be77))
* **otel:** instrument auth service HTTP client with otelhttp
([#2722](#2722))
([69b085d](69b085d))
* per-team events TTL limit (tier + addons)
([#3181](#3181))
([f76b2cb](f76b2cb))
* **storage:** stamp provenance custom metadata on uploaded objects
(incl. headers) ([#3033](#3033))
([ba8604e](ba8604e))


### Bug Fixes

* added api and orch
([#3454](#3454))
([d56e0a8](d56e0a8))
* **api:** check template alias tags in exists endpoint
([#2916](#2916))
([9574cdf](9574cdf))
* **api:** copy auth/internal into api and dashboard-api image builds
([#3323](#3323))
([bda1fee](bda1fee))
* **api:** discover the local orchestrator as a template builder
([#3386](#3386))
([9ea005a](9ea005a))
* **api:** expose pagination headers via CORS
([#3388](#3388))
([e832b1e](e832b1e))
* **api:** handle corrupted data in sandbox stop time
([#3203](#3203))
([a98a178](a98a178))
* **api:** include exhaustion reason in "Node exhausted" placement
warning ([#3279](#3279))
([eb3797b](eb3797b))
* **api:** invalidate auth cache on API key deletion
([#3324](#3324))
([8b02910](8b02910))
* **api:** keep API alive until in-flight requests finish
([#2708](#2708))
([06378c7](06378c7))
* **api:** let the analytics collector address carry a port
([#3394](#3394))
([6d41cb5](6d41cb5))
* **api:** parse the pause body regardless of Content-Length
([#3056](#3056))
([d66aab8](d66aab8))
* **api:** prevent uint64 underflow in node allocated metrics
([#3216](#3216))
([fed38e1](fed38e1))
* **api:** push api and db-migrator images to both latest and commit S…
([#2951](#2951))
([6f010fc](6f010fc))
* **api:** reject non-positive timeout on sandbox create, resume, and
fork ([#3419](#3419))
([5a4b631](5a4b631))
* **api:** report invalid tag errors as bad requests
([#2799](#2799))
([10085a1](10085a1))
* **api:** stop evicting the local node during sync
([#2881](#2881))
([5455905](5455905))
* **api:** use correct error variable in processCustomErrors
([#3135](#3135))
([a131a00](a131a00))
* **auth:** rename X-Team-Id header to X-Team-ID
([#2723](#2723))
([f92ecc0](f92ecc0))
* correct 3 CVES ([#3218](#3218))
([076823b](076823b))
* **orchestrator:** reject standby while draining
([#3325](#3325))
([475a7ee](475a7ee))
* Support snapshots for non-default clusters
([#2947](#2947))
([28eeb72](28eeb72))


### Performance Improvements

* **api:** wake reservation waiters via pub/sub instead of 20ms polling
[ENG-4070] ([#2729](#2729))
([2944d06](2944d06))

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