Skip to content

feat(api): gate access token issuance behind feature flag - #3101

Merged
Kraci merged 3 commits into
mainfrom
disable-access-token-issuance-en-1110
Jun 26, 2026
Merged

feat(api): gate access token issuance behind feature flag#3101
Kraci merged 3 commits into
mainfrom
disable-access-token-issuance-en-1110

Conversation

@Kraci

@Kraci Kraci commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

What

Adds a feature flag that lets us stop issuing new E2B access tokens (sk_e2b_) via POST /access-tokens. When disable-access-token-issuance is on, the endpoint returns 403 with a message pointing users to E2B_API_KEY + the migration guide, before any token is generated.

Why

Backend half of EN-1110. E2B_ACCESS_TOKEN is deprecated in favor of E2B_API_KEY; the CLI now authenticates via Hydra JWTs (EN-1106/1107/1108), so issuance can be turned off

Changes

  • New DisableAccessTokenIssuanceFlag bool flag
  • 403 gate at the top of PostAccessTokens.
  • openapi.yml: marked POST /access-tokens deprecated: true + added 403

Scope / blast radius

  • This is stop issuing (July 1). Stop accepting existing tokens (Aug 1) is separate — disabling the central AccessTokenAuth authenticator.

@Kraci Kraci self-assigned this Jun 26, 2026
@linear-code

linear-code Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

EN-1110

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

@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 a feature flag to disable the creation of new access tokens, updating the API handler, OpenAPI specification, and tests accordingly. I have no feedback to provide.

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.

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@Kraci
Kraci marked this pull request as ready for review June 26, 2026 12:10
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

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

LGTM — small, default-off feature-flag gate with a unit test.

Extended reasoning...

Overview

The PR adds a new DisableAccessTokenIssuanceFlag (bool, default false) in packages/shared/pkg/featureflags/flags.go, gates the top of PostAccessTokens to return 403 with a migration hint when enabled, marks POST /access-tokens as deprecated: true in spec/openapi.yml and adds the 403 response. The two generated client files (api.gen.go and integration test generated.go) are mechanical regenerations from the spec, and a focused unit test verifies the 403 path via the LaunchDarkly test datasource.

Security risks

None introduced. This is a fail-closed gate that reduces the surface for new access token issuance; it does not touch the authenticator that validates existing tokens (that's an explicitly separate Aug 1 step per the PR description). The flag defaults to off, preserving current behavior, and the error message points to the migration path without leaking sensitive state.

Level of scrutiny

Low. This is a feature-flag-gated deprecation gate, default-off, behind LaunchDarkly with per-user context, fully reversible. The handler change is 5 lines; the rest is generated code and OpenAPI metadata. The unit test exercises the new branch correctly using ldtestdata.

Other factors

The 7 failing tests in CI (envd 502s on TestListDir, template build cancellation in TestTemplateBuildRUN) are clearly unrelated infrastructure flakes — none touch access token code. No bugs were found by the hunting system. The pattern matches existing bool flags in the same file and the existing feature-flag idiom across the codebase.

Comment thread packages/api/internal/handlers/accesstoken.go Outdated

@ben-fornefeld ben-fornefeld left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm otherwise

Kraci added 2 commits June 26, 2026 20:58
Regenerated api.gen.go + integration client from the merged spec
(resolves generated-file conflict; combines #3109 with the 410 change).
@Kraci
Kraci merged commit 2f7811e into main Jun 26, 2026
104 of 106 checks passed
@Kraci
Kraci deleted the disable-access-token-issuance-en-1110 branch June 26, 2026 20:04
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>
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>
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