feat(middleware): user identity verification pipeline (RFC) - #48
Merged
Conversation
syucream
force-pushed
the
feat/user-identity-verification
branch
3 times, most recently
from
July 22, 2026 05:39
d501382 to
985a06f
Compare
Bumps to 2.4.0. Middlewares that have shipped in prior 2.x releases are
reshaped here — the option surface, some option names, and the file
layout change — but the middleware system itself is still stabilizing,
so this is not called out as a semver-major.
Three middlewares that let any deployment authenticate callers via
signed id_tokens, without hardcoding Google as the sole issuer:
Server (verifies inbound):
- oauth-verify — verifies the incoming Authorization: Bearer
through a pluggable `IdTokenVerifier`
interface. `GoogleTokeninfoVerifier` ships
as the reference implementation; other
issuers plug in their own verifier via
`options.verifier`.
- impersonator-verify — verifies a side-channel id_token
(`X-Impersonator-Id-Token` by default),
only when the bearer principal is in an
explicit trusted list.
Client (rewrites outbound):
- impersonator-token — attaches a user-owned id_token as a side
header. Token sources are pluggable:
`env` (default) / `static` / `adc`
(Google gcloud ADC, kept behind an
explicit selector).
`src/middleware/auth/types.ts` — `IdTokenVerifier` interface and the
neutral `VerifiedClaim` shape both middlewares consume.
`src/middleware/auth/google-tokeninfo.ts` — Google's tokeninfo
reference implementation of `IdTokenVerifier`. Kept in its own file
so non-Google users never accidentally import it.
`src/middleware/builtin/impersonator-token/adc-user-token-source.ts`
— Google-specific ADC user token source, separated from the generic
`UserTokenSource` interface so it isn't the silent default.
- Cache expiry is now capped at the token's own `exp` — expired
tokens can no longer replay past their rated lifetime just because
the local cache TTL was longer.
- Rejection responses no longer echo the received `aud` value to the
caller (small info-disclosure hardening).
- The ADC token source no longer memoizes an initial read failure —
users who start the CLI before running `application-default login`
can now recover without restarting the process.
- Dockerfile build stage switched to the debian-based `oven/bun`
image so the runtime distroless/debian12 image can actually exec
the compiled binary (was cross-libc before).
Trimmed to the fields that materially affect a deployment; tunable
knobs (timeouts, cache TTLs, custom endpoints) stay programmatic-only
for test injection. Renamed `trustedServiceAccounts` →
`trustedPrincipals` (both the option name and the corresponding
`--oauth-verify-trusted-principals` / `N8N_OAUTH_VERIFY_TRUSTED_PRINCIPALS`
CLI and env surface) so the vocabulary doesn't presume Google service
accounts.
`bun run typecheck` clean; `bun test tests/middleware/` passes 170/170;
`bun run lint` exit 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
syucream
force-pushed
the
feat/user-identity-verification
branch
from
July 22, 2026 05:42
985a06f to
d5113a5
Compare
syucream
marked this pull request as ready for review
July 22, 2026 05:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds five middlewares that let a Cloud Run / IAP-fronted deployment attribute proxy calls to the actual human running the CLI — cryptographically, without trusting client-side claims.
New middlewares
Server-side (ingress):
oauth-verify— verifiesAuthorization: Bearervia Googletokeninfo; pins iss / aud allowlist /email_verifiedimpersonator-verify— verifies a side header (X-Impersonator-Id-Token) as the human user's own Google id_token; only honored when the primary bearer is a pre-registered trusted SA (spoof prevention)caller-authz— generic external-authz gate resolving the effective identity to a group list via a configurable HTTP endpointClient-side (egress):
impersonator-token— mints the current user's Google id_token via ADC refresh-token grant and attaches it asX-Impersonator-Id-TokenAlso included
TokeninfoVerifierundersrc/middleware/auth/Dockerfile(distroless, multi-stage build)N8N_*env-var surface, consistent with PR feat(proxy): add ClientMiddleware pipeline with iap-auth and api-key-inject #47Test plan
bun run typecheck— 0 errorsbun test— 971 pass / 0 fail (baseline 914 + 57 new)bun run lint— exit 0bun run build— produces working binaryStatus
Draft / RFC — posted to solicit review before finalizing.
🤖 Generated with Claude Code