feat(api): add native MPP (Machine Payments Protocol) support#2398
feat(api): add native MPP (Machine Payments Protocol) support#2398decofe wants to merge 1 commit intoe2b-dev:mainfrom
Conversation
Add HTTP 402 payment support so AI agents can pay for sandbox usage with crypto (Tempo) instead of API keys. - Add PaymentAuth security scheme to OpenAPI spec - Add MPP config fields (MPP_ENABLED, MPP_SECRET_KEY, etc.) - Add PaymentAuthenticator for OpenAPI auth validation - Add MPP Gin middleware for 402 challenge/credential flow - Add TempoMethod implementing mpp-go server.Method interface - Add GetTeamByID to APIStore for MPP team lookup - Wire MPP into auth chain and middleware stack - Gate sandbox create, connect, kill, timeout, refresh behind 402 Uses github.com/tempoxyz/mpp-go for the payment protocol. Amp-Thread-ID: https://ampcode.com/threads/T-019d8d82-1698-749a-8b5b-92b6d5cd77fe
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 69db744f84
ℹ️ 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".
| // MPP (Machine Payments Protocol) middleware for 402 payment support. | ||
| if config.MPPEnabled { | ||
| tempoMethod := handlers.NewTempoMethod(config.MPPCurrency, config.MPPRecipient) | ||
| r.Use(customMiddleware.MPPMiddleware(customMiddleware.MPPConfig{ |
There was a problem hiding this comment.
Register MPP middleware before OpenAPI auth validation
In packages/api/main.go, the OAPI validator is installed before MPPMiddleware, so unauthenticated POST /sandboxes requests are rejected during security validation and never reach the middleware that generates WWW-Authenticate: Payment challenges. This breaks the first step of the documented 402 handshake (no-auth request -> challenge), because clients cannot obtain a challenge to construct a payment credential.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| // Skip if the request already has standard E2B auth. | ||
| if c.GetHeader("X-API-Key") != "" || hasBearer(c.GetHeader("Authorization")) { |
There was a problem hiding this comment.
Exempt Supabase-authenticated calls from MPP interception
The skip condition in packages/api/internal/middleware/mpp.go only recognizes X-API-Key and Authorization: Bearer, so requests authenticated via X-Supabase-Token/X-Supabase-Team are treated as unauthenticated and get challenged/charged by MPP when it is enabled. That regresses existing Supabase auth flows on billable sandbox endpoints despite valid credentials.
Useful? React with 👍 / 👎.
|
Closing per offline convo - will bring proxy repo instead. |
|
Thanks for the prototype. We are going to be implemeting this feature differently. |
Summary
Add native HTTP 402 payment support via the Machine Payments Protocol so AI agents can pay for E2B sandbox usage with crypto (Tempo USDC) instead of API keys.
Motivation
MPP enables no-signup, pay-per-use access to E2B sandboxes. An AI agent with a Tempo wallet can create and manage sandboxes by paying per request — no API key, no account, no billing setup. This is especially useful for autonomous agents that need compute on demand.
Changes
OpenAPI spec (
spec/openapi.yml)PaymentAuthsecurity scheme (http/payment)PaymentAuthas an alternative auth option on sandbox endpoints: create, kill, connect, timeout, refreshesConfig (
packages/api/internal/cfg/model.go)MPP_ENABLED,MPP_SECRET_KEY,MPP_REALM,MPP_CURRENCY,MPP_RECIPIENT,MPP_TEAM_IDenv varsAuth (
packages/api/internal/handlers/payment_auth.go)PaymentAuthenticatorimplementsauth.Authenticatorfor thePaymentAuthsecurity schemeMPP_TEAM_IDMiddleware (
packages/api/internal/middleware/mpp.go)WWW-Authenticate: Paymentchallenges when no auth is presentPayment-ReceiptheaderPayment method (
packages/api/internal/handlers/mpp_method.go)TempoMethod/TempoChargeIntentimplementingmpp-go/server.MethodinterfaceWiring (
packages/api/main.go)PaymentAuthenticatorto authenticator chain whenMPP_ENABLED=trueAccept-Paymentto CORS allowed headersStore (
packages/api/internal/handlers/store.go)GetTeamByIDusing existingGetTeamWithTierByTeamIDqueryDependency
github.com/tempoxyz/mpp-gotogo.modProtocol flow
Testing
This is gated behind
MPP_ENABLED=false(default), so existing behavior is unchanged. When enabled, requiresMPP_SECRET_KEY,MPP_REALM,MPP_CURRENCY,MPP_RECIPIENT, andMPP_TEAM_ID.Prompted by: georgios