A lightweight HTTP reverse proxy for Sentry that authenticates outgoing requests with a Sentry API token. Designed for internal use — sits between Sentry clients and the Sentry API, handling token management transparently.
- Token-aware proxying — Automatically injects
Authorization: Bearer <token>into proxied requests. - Dual token modes:
- Static token — A pre-configured Sentry API token.
- System token — Fetches the Sentry internal system token directly from the Sentry PostgreSQL database and renews it automatically in the background.
- Request isolation — Each request gets a fresh connection; no keep-alives. Simplifies resource management for an internal proxy.
- Header sanitization — Strips potentially problematic request/response headers to ensure isolation between client and upstream.
- JSON-aware error responses — Returns JSON errors when the client
Acceptheader indicates JSON preference; falls back to plain text otherwise. - Alias tokens — When configured, only requests with matching bearer tokens go through the proxy client (with Sentry token injection); all other requests are forwarded as-is without additional authentication enforcement. When no alias tokens are configured, every request goes through the proxy client with the Sentry token. Useful for restricting which clients can access the Sentry API with elevated credentials.
| Flag | Default | Description |
|---|---|---|
--listen |
0.0.0.0:8080 |
Listen endpoint (addr:port). |
--sentry-uri |
http://sentry-web:9000 |
Upstream Sentry base URI. |
--token |
system |
Sentry API token, or "system" for DB-fetched token. |
--pgx-conn |
(empty) | PostgreSQL connection string (used only with system token). |
--alias-token |
(empty) | Semicolon-separated list of alias bearer tokens. |
Notes:
-
--pgx-connmay be empty -pgxwill then use environment variables, see for details:pgxParseConfig()pgxpgconn.ParseConfig()libpqconnection stringslibpqenvironment variables
-
when using PgBouncer, set
--pgx-connwith thedefault_query_exec_modeoption set toexecorsimple_protocol, e.g.postgres://user:pass@host:5432/sentry?default_query_exec_mode=exec.See for details:
pgxPgBouncerpgxQueryExecMode
Each flag has a corresponding environment variable:
| Variable | Equivalent Flag |
|---|---|
LISTEN |
--listen |
SENTRY_URI |
--sentry-uri |
SENTRY_TOKEN |
--token |
PGX_CONN |
--pgx-conn |
ALIAS_TOKENS |
--alias-token |
Using a static token:
sentry-api-proxy \
--listen 0.0.0.0:8080 \
--sentry-uri http://sentry:9000 \
--token sntry_abc123...Using the Sentry system token (fetched from PostgreSQL):
sentry-api-proxy \
--listen 0.0.0.0:8080 \
--sentry-uri http://sentry-web:9000 \
--token system \
--pgx-conn "postgres://sentry:sentry@localhost:5432/sentry"With alias tokens (only allowed tokens get Sentry authentication):
sentry-api-proxy \
--listen 0.0.0.0:8080 \
--sentry-uri http://sentry:9000 \
--token sntry_abc123... \
--alias-token "app-token-1;app-token-2"makeThe binary is statically linked with CGO disabled. HTTP/2 support is stripped
from the build (nethttpomithttp2 build tag) to reduce binary size.
docker build -t sentry-api-proxy .The Docker image is based on gcr.io/distroless/static-debian13:nonroot and runs
as a non-root user.
| Tag | Effect |
|---|---|
nethttpomithttp2 |
Excludes HTTP/2 from net/http. |
nopgxregisterdefaulttypes |
Reduces binary size (see pgx docs). |
Enables the race detector and CGO:
make dev-build┌────────┐ ┌──────────────────┐ ┌────────┐
│ Client │────▶│ sentry-api-proxy │────▶│ Sentry │
└────────┘ └──────────────────┘ └────────┘
│
▼
┌────────────┐
│ PostgreSQL │
│ (optional) │
└────────────┘
- Client sends request to the proxy.
- Proxy checks for alias tokens — if alias tokens are configured, only requests with a matching bearer token go through the proxy client (with Sentry token injection). All other requests go through the bypass client (forwarded as-is, without additional authentication enforcement). If no alias tokens are configured, every request goes through the proxy client.
- The proxy client injects the Sentry
Authorizationheader and forwards the request to the upstream Sentry instance. - On
401 Unauthorized, the proxy automatically renews the token and retries once (only when using the system token — static tokens are not renewable). - Response headers are sanitized and the upstream response is relayed back to the client.
Common request headers:
| Header | Reason |
|---|---|
Accept-Encoding |
Prevent client-specific encoding. |
Accept-Language |
Prevent client-specific language. |
Connection |
Managed by the proxy (set to close). |
Expect |
Not supported for proxied requests. |
Forwarded |
Cleared to avoid conflicts. |
Host |
Set by the upstream URL. |
Proxy-Authorization |
Proxy authentication, not forwarded. |
Te |
Trailer encoding, not used. |
Upgrade |
Protocol upgrades not supported. |
Via |
Cleared to avoid conflicts. |
X-Forwarded-For |
Cleared to avoid conflicts. |
X-Forwarded-Host |
Cleared to avoid conflicts. |
X-Forwarded-Proto |
Cleared to avoid conflicts. |
Common response headers:
None currently. The list will be expanded as needed.
Request headers specific to proxy:
| Header | Reason |
|---|---|
Authentication |
Cleared to avoid conflicts. |
Authorization |
Replaced by proxy's own token. |
Cookie |
Session isolation. |
Response headers specific to proxy:
| Header | Reason |
|---|---|
Set-Cookie |
Prevent upstream cookies leaking to client. |
Www-Authenticate |
Strip upstream authentication challenges from proxied responses. |
| Timeout | Value |
|---|---|
ReadTimeout |
25s |
ReadHeaderTimeout |
10s |
WriteTimeout |
25s |
Keep-alives are disabled — each request gets a new connection.
| Provider | Source | Renewable | Background refresh |
|---|---|---|---|
StaticToken |
Pre-configured string | No | No |
SystemToken |
PostgreSQL query | Yes | Yes (every ~15 min) |
The system token is fetched from Sentry's own database:
SELECT value FROM sentry_option WHERE key = 'sentry:system-token';It is refreshed in the background when its lifetime exceeds half of
systemTokenLifeTime (30 minutes).
Apache 2.0 | spdx.org | opensource.org