feat(auth): add 'none' auth type for reverse-proxy injected credentials#190
Conversation
Adds a new --auth-type/CONFLUENCE_AUTH_TYPE value 'none' that builds a client sending no Authorization or Cookie header, for environments where a local reverse proxy injects authentication on the wire.
pchuri
left a comment
There was a problem hiding this comment.
Thanks for the PR — really clean, well-scoped change. Approving.
Verified locally: npm test passes (689/689) and npm run lint is clean on this branch.
What I liked
- Explicit by design:
normalizeAuthTypenever infersnone— it has to be selected on purpose. Good safety property for an auth-bypass mode. - Validation short-circuit: the early return in
validateAuthConfig(lib/config.js:128-131) is placed before the!auth.tokencheck, sononecorrectly skips the "Bearer or basic authentication requires a token" path that would otherwise misfire. - Header path is airtight:
buildAuthHeader()→nullandbuildAuthHeaders()→{}fornone, so the reusedbuildAuthHeaders()call insidedownloadAttachment(lib/confluence-client.js:1056) can't leak credentials in this mode either. - Docs are consistent: the README profile example, env var example, flag listing, and the new explanatory paragraph all match the existing
mtls/cookiesections — easy to discover.
Non-blocking suggestions (happy to merge as-is)
-
401 hint ordering — in the response interceptor (lib/confluence-client.js:74-105),
isScopedToken()is checked beforeauthType === 'none'. In the unlikely topology where a reverse proxy fronts a path containing/ex/confluence/or uses anapi.atlassian.com-like host, users would get the scoped-token hint instead of the new reverse-proxy hint. Moving thenonebranch aboveisScopedToken()would make the hint match the explicit user intent. -
Stale credentials when
none+ token/cookie/mtls are both set — if a user setsCONFLUENCE_AUTH_TYPE=nonealongsideCONFLUENCE_API_TOKEN, the token is still copied into the resolved config (lib/config.js:793) but never sent. Not a security issue, but aconsole.warnwhennoneis combined with other credentials would help avoid "why isn't my token being used?" confusion. -
Test coverage gaps worth considering:
saveConfig→getConfiground-trip for a stored{ authType: 'none', domain: ... }profile (exercises the file-based path, not just env).validateCliOptions({ authType: 'none' })returning no errors without email/token/cookie.- Non-interactive
initConfigwith--auth-type none --domain xtaking thehasRequiredValuesbranch added at lib/config.js:644.
Nice work — the motivation in the description is clear and the implementation matches the intent precisely.
# [2.8.0](v2.7.0...v2.8.0) (2026-05-23) ### Features * **auth:** add 'none' auth type for reverse-proxy injected credentials ([#190](#190)) ([21a03bd](21a03bd))
|
🎉 This PR is included in version 2.8.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
noneas a new value for--auth-type/CONFLUENCE_AUTH_TYPE.authType === 'none', the client builds requests with noAuthorizationorCookieheader. Designed for setups where a local reverse proxy injects credentials on the wire (SPNEGO/Kerberos, mTLS-at-edge, header injection).validateAuthConfigshort-circuits fornone, so token / email / cookie / mTLS fields are not required at any layer (CLI flags, env vars, profile file, interactive prompts).hasEnvAuthingetConfigacceptsCONFLUENCE_AUTH_TYPE=nonealone —CONFLUENCE_DOMAIN+CONFLUENCE_AUTH_TYPE=noneis enough to drive the env path.mtls/cookiesections; update the--auth-typeflag listing.Why
Behind a reverse proxy that auto-injects auth headers, users had to invent a placeholder token to satisfy the existing required-credentials checks. A first-class
nonemode makes the intent explicit and removes the workaround.Behavior preservation
basic,bearer,mtls,cookie) are unchanged.noneis only selected explicitly —normalizeAuthTypestill defaults tobasic/bearerbased on email presence.none-specific hint pointing at the proxy; other hints are untouched.Test plan
npm test— 689/689 pass (+4 new: 2 intests/config.test.js, 2 intests/confluence-client.test.js)npm run lint— cleannode bin/confluence.js init --auth-type none --domain confluence.example.com --protocol httpssucceeds without promptingCONFLUENCE_AUTH_TYPE=none— confirmed noauthorization/cookieon the outgoing request