agentmailgateway

package
v1.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: Apache-2.0 Imports: 33 Imported by: 0

README

Agent Mail identity gateway

This module exposes the authenticated OCTO route:

/v1/mail-gateway/webapi/v0/*

It derives the subject from the OCTO login session and the Space from SpaceMiddleware, then replaces caller credentials with a one-minute HMAC assertion bound to the exact upstream method, URI, and body.

Configuration

Both variables are required to enable the gateway:

OCTO_MAIL_GATEWAY_URL=http://octo-mail:8090
OCTO_MAIL_GATEWAY_SECRET=<at least 32 bytes>

The optional OCTO_MAIL_GATEWAY_TIMEOUT is a Go duration and defaults to 30s. The value must not exceed 2m. It bounds each no-progress phase rather than the whole browser request:

  • reading the browser request body;
  • connecting to octo-mail and completing the TLS handshake;
  • uploading the buffered request body and waiting for response headers;
  • reading the upstream response body; and
  • writing each response chunk to the browser.

Each successful body read resets the relevant progress timer, so a large transfer that continues making progress is not cut off by a whole-request deadline. The browser request context remains the outer cancellation boundary.

The same secret must be configured as OCTO_MAIL_GATEWAY_SECRET in octo-mail. The secret is an internal service credential and must not be sent to the browser or used as an account API key.

Only the octo-mail /webapi/v0 surface is reachable. Browser Authorization, token, cookies, caller identity headers, and hop-by-hop headers are not forwarded. X-Octo-Mailbox-ID is the only mailbox selection header and is validated again by octo-mail against the mapped owner.

Every proxied response is marked Cache-Control: private, no-store and varies on the session token, validated Space, and selected mailbox headers. This prevents a shared cache from reusing one caller's mail response for another caller even though their gateway URLs are otherwise identical.

Streaming and memory bounds

  • Known-length responses retain the upstream Content-Length; a short transfer is therefore visible to the client.
  • The gateway requests Accept-Encoding: identity from octo-mail instead of forwarding browser compression preferences. This prevents Go's transport from transparently turning a known-length gzip response into an unknown-length response that HTTP/2 cannot safely truncate. If an upstream still returns a compressed representation, its encoding and known length are preserved for the browser.
  • HTTP/1.1 chunked responses stream immediately. A read failure, progress timeout, or the 64 MiB response limit aborts the HTTP/1.1 client connection so it cannot end as a clean chunked success.
  • HTTP/1.x close-delimited responses are rejected before their status is committed because EOF cannot distinguish completion from truncation. Unknown-length responses remain rejected for HTTP/1.0 downstream clients.
  • When the downstream hop reaching this handler uses HTTP/2, unknown-length responses are fully validated before status commit and then forwarded with a computed Content-Length. The gateway retains them in 256 KiB chunks to avoid geometric whole-body reallocations. Each response reserves its full 64 MiB allowance from a process-wide 256 MiB budget until the buffered body is written downstream, allowing at most four such responses concurrently. A request that cannot obtain a reservation within five seconds receives the localized 503 err.server.agent_mail_gateway.unavailable response.
  • Request and response bodies each have a 64 MiB per-request limit. Four slots bound concurrent large request-body buffering. Request bodies over 1 MiB additionally use a 256 MiB weighted budget until the upstream transport closes its request body. Closing that body drops the transport-visible reference to the buffered bytes before releasing the reservation, so a slow browser response cannot retain unrelated upload capacity. Smaller bodies bypass that large-body budget. Requests without a declared length reserve the full 64 MiB allowance and are still bounded by the four slots and progress timeout. An over-limit unknown-length request is rejected with 413 and its connection is made non-reusable before the unread body is closed, preventing net/http's connection-reuse drain from retaining those reservations.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Gateway

type Gateway struct {
	log.Log
	// contains filtered or unexported fields
}

Gateway authenticates browser mail requests through OCTO and proxies only the octo-mail WebAPI surface using a short-lived request-bound assertion.

func New

func New(ctx *config.Context) *Gateway

func (*Gateway) Route

func (g *Gateway) Route(r *wkhttp.WKHttp)

Route requires the standard authenticated UID and validated Space before the request can reach the proxy trust boundary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL