Skip to content

Add vendor-neutral trusted proxy auth middleware examples for Node, Python, Rust, and Go#378

Closed
Copilot wants to merge 10 commits into
mainfrom
copilot/build-trusted-proxy-middleware
Closed

Add vendor-neutral trusted proxy auth middleware examples for Node, Python, Rust, and Go#378
Copilot wants to merge 10 commits into
mainfrom
copilot/build-trusted-proxy-middleware

Conversation

Copilot AI commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

This introduces a new proxy-auth-lib/ workspace for applications that sit behind an identity-aware proxy and need to trust signed identity assertions instead of raw forwarded headers. It provides a consistent MVP across Node.js, Python, Rust, and Go for header extraction, JWKS-backed JWT verification, issuer/audience/expiration checks, and verified identity propagation.

  • Multi-language middleware scaffold

    • Added proxy-auth-lib/ with language-specific implementations for:
      • Node.js: Express-style middleware
      • Python: ASGI middleware for FastAPI / Starlette-style apps
      • Rust: Axum middleware
      • Go: net/http middleware
    • Standardized the shared config model across all four implementations:
      • TRUSTED_PROXY_ASSERTION_HEADER
      • TRUSTED_PROXY_JWKS_URL
      • TRUSTED_PROXY_ISSUER
      • TRUSTED_PROXY_AUDIENCE
  • Verification model

    • Each implementation now handles:
      • configured assertion header lookup
      • JWKS key resolution
      • JWT/JWS signature verification
      • issuer validation
      • audience validation
      • expiration validation
      • verified identity extraction (subject, email, name, raw claims)
    • Invalid, missing, expired, malformed, or wrongly scoped assertions are rejected with a 401 without leaking token contents.
  • Shared fixtures and coverage

    • Added shared JWKS/JWT fixtures under proxy-auth-lib/testdata/
    • Added per-language coverage for:
      • valid assertion
      • missing assertion
      • expired assertion
      • invalid signature
      • wrong issuer
      • wrong audience
      • malformed token
  • Docs and repository structure

    • Added a dedicated docs page for the trusted proxy auth pattern
    • Updated navigation and repository layout references
    • Extended architecture docs to explicitly warn against trusting unsigned identity headers and to point readers at the new middleware examples
    • Kept vendor references neutral: Cloudflare, Pomerium, OAuth2 Proxy, Envoy, Traefik, and NGINX are described as examples of the same upstream-auth pattern, not special cases
  • Example

    • Node.js usage is intentionally minimal:
app.use(createTrustedProxyAuth(loadConfigFromEnv()));

app.get('/me', (req, res) => {
  res.json(req.trustedProxyIdentity);
});

Updates since initial draft

  • Hostname-derived config defaults

    • When env vars are unset, the auth domain defaults to auth.<parent-domain> of the host FQDN (e.g. web1.os.example.orgauth.os.example.org), with issuer/JWKS/audience derived from it. All vars remain optional overrides.
  • Static public-key verification (JWKS still preferred)

    • Added TRUSTED_PROXY_PUBLIC_KEY (inline PEM) and TRUSTED_PROXY_PUBLIC_KEY_FILE (path) across all four languages.
    • When a public key is configured, verification uses it directly and performs no network calls; otherwise JWKS is used (the default and recommended path for key rotation / OIDC providers).
    • Config validation now requires either a JWKS URL or a public key.
  • Algorithm pinning

    • Verification is pinned to RS256 in every implementation.
  • Fixtures & tests

    • Added shared proxy-auth-lib/testdata/public-key.pem (matches existing token fixtures) plus offline static-key tests in each language.

Copilot AI changed the title [WIP] Build vendor-neutral trusted proxy identity middleware Add vendor-neutral trusted proxy auth middleware examples for Node, Python, Rust, and Go Jun 23, 2026
Copilot AI requested a review from horner June 23, 2026 22:36
@horner

horner commented Jun 23, 2026

Copy link
Copy Markdown
Member

Deleted

horner added 2 commits June 24, 2026 03:17
…tname-derived config defaults

- Add Express/Fastify/Hono Node adapters and shared core module
- Add Flask/Django Python middleware
- Add mieweb:accounts-proxy-auth Meteor package (accounts-base login)
- Derive auth domain from host FQDN instead of hardcoding; all settings optional
- Update tests and docs
- Accept TRUSTED_PROXY_PUBLIC_KEY (inline PEM) or _FILE (path) across Node,
  Python, Go, and Rust; when set, verification skips JWKS and runs offline
- JWKS remains the preferred default for key rotation and OIDC providers
- Pin verification algorithm to RS256 in all implementations
- Require either a JWKS URL or a public key in config validation
- Add shared testdata/public-key.pem fixture and static-key tests
- Enable jsonwebtoken use_pem feature for PEM keys (Rust)
- Document the JWKS vs static-key choice
Comment thread proxy-auth-lib/python/tests/test_middleware.py Fixed
horner added 3 commits June 24, 2026 03:44
Addresses code-quality review: drop 'from unittest import mock' and
qualify usage as unittest.mock (with explicit submodule import).
Publish on a proxy-auth-lib-v<semver> tag to npm, JSR, PyPI (Trusted
Publishing), crates.io, Atmosphere (Meteor), and the Go module proxy as
independent jobs, plus a Bun/Deno install smoke test. Each job derives the
version from the tag and runs a matching script in proxy-auth-lib/scripts/
that is reproducible locally.

- Add scripts/ (stamp-version + per-registry publish + runtime smoke) and README
- Add nodejs/jsr.json for JSR publishing
- Fix Go module path to the monorepo subpath so it actually resolves; release
  tags proxy-auth-lib/go/v<version> and warms the Go proxy
- Add required crates.io metadata (license, description, repository)
- Ignore Python build artifacts
@horner horner closed this Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants