Skip to content

Private repositories and proxies: URL credentials, proxy auth, mirror-aware lookups, docs - #253

Open
rochala wants to merge 3 commits into
mainfrom
private-repo-credentials
Open

rochala wants to merge 3 commits into
mainfrom
private-repo-credentials

Conversation

@rochala

@rochala rochala commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #191: credential and proxy handling for external commands, plus a README section that documents exactly what coursier reads.

Changes

  • Credentials in repository URLs. -r / maven.repositories URLs go through coursier's RepositoryParser: https://user:token@host/... becomes repository authentication, sent with the first request (HTTPS-only unless the URL is http). Previously the userinfo was silently ignored. This is what Azure Artifacts needs: it answers anonymous requests with 203 + a sign-in page, so challenge-based credentials never reach it.
  • Credentials never printed. Errors mask everything between the scheme and the last @ (tokens may contain /, @, #), and explain that such credentials cannot go in a URL.
  • Duplicates keep credentials. A repository given with credentials on -r wins over the same URL configured without them.
  • Proxy authentication. http(s).proxyUser/proxyPassword now work: coursier's proxy Authenticator is installed at startup, proxyProtocol defaults to http (otherwise an https.proxy*-only setup is never answered), and the native image allows Basic for HTTPS tunnels — that JDK setting is fixed at image build time.
  • Mirror-aware lookups. :latest and "did you mean" suggestions now go through the same mirrors as the fetch (coursier's Versions/Complete skip the scala-cli and Maven settings.xml mirrors Resolve applies), so they work behind a company mirror.
  • No 203 rejection. Considered and dropped: coursier documents most 203s as a proxy's transformed body. A sign-in page already fails on its checksum, and coursier caches per user, so authenticated runs never see it.
  • README Private repositories: credential sources (incl. Maven settings.xml mirrors + <server> credentials, coursier's default; COURSIER_MAVEN_SETTINGS=false opts out), formats, sbt .credentials mapping, URL credentials with ${?ENV}, per-project setup, proxies (forward, auth, TLS, mirrors), troubleshooting table, COURSIER_HTTP_DEBUG.

Verification

  • lib.test, cli.test, profilingRuntime.test pass; ./mill _.fix --check clean.
  • New PrivateRepositoryTest against in-process servers: URL credentials reach a 203-for-anonymous feed with no anonymous request made; an authenticating forward proxy is passed the proxy credentials; an https.proxy*-only setup is answered. Mutation-checked: removing the authenticator or the proxyProtocol default fails the respective test.
  • RepositoryUrlTest: masking with /, @ and token-only credentials; ExtraRepositoriesTest: credentialed duplicate wins.
  • Manual, JVM and native binary: authenticating proxy over plain HTTP and HTTPS tunnel (https.* only), wrong proxy password, settings.xml mirror with <server> credentials incl. :latest and suggestions, ${?UNSET} in project config, credentials-file/inline/realm/URL against 401/404/203 servers, --debug never prints the password.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ETVFFSQUFsAxXzjVsFwthR

rochala and others added 3 commits October 21, 2026 16:43
cellar reads only coursier's credential sources; document where they live,
the formats, and how to carry over an sbt .credentials file, instead of
reading other tools' credentials.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ETVFFSQUFsAxXzjVsFwthR
Coursier holds file/env credentials back until a server rejects an
anonymous request with a 4xx. Azure Artifacts answers with 203 and a
sign-in page instead, which coursier cached as the POM: credentials were
never sent and the cache stayed broken with a checksum error.

- Route every coursier call through one FileCache with
  rejectNonAuthoritativeResponses, so a 203 fails cleanly.
- Parse -r / maven.repositories URLs with coursier's RepositoryParser:
  user:password in the URL becomes repository authentication, sent up
  front (HTTPS-only unless the URL is http). Error messages mask it.
- README: correct the retry rule (any 4xx, not just 401), document URL
  credentials with ${ENV} substitution, and a troubleshooting table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ETVFFSQUFsAxXzjVsFwthR
- Drop the global 203 rejection: coursier documents most 203s as a
  proxy's transformed body, and a sign-in page already fails on its
  checksum (and is cached per user, so authenticated runs never see it).
- Proxy credentials: install coursier's proxy Authenticator from
  http(s).proxyUser/proxyPassword, default proxyProtocol to http so an
  https.proxy*-only setup is answered, and allow Basic for HTTPS tunnels
  in the native image, where that setting is fixed at build time.
- :latest and "did you mean" suggestions go through the same mirrors as
  the fetch (scala-cli and Maven settings mirrors included).
- Mask everything between scheme and last @ in repository URL errors;
  explain that credentials with / ? # @ cannot go in a URL.
- A duplicate repository carrying credentials wins over one without.
- README: credential sources incl. Maven settings mirrors, ${?ENV},
  per-project credentials, proxies, troubleshooting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ETVFFSQUFsAxXzjVsFwthR
@rochala
rochala force-pushed the private-repo-credentials branch from 17a47b9 to 4371410 Compare October 21, 2026 15:43
@rochala rochala changed the title Private repository credentials: reject 203 sign-in pages, URL credentials, docs Private repositories and proxies: URL credentials, proxy auth, mirror-aware lookups, docs Oct 21, 2026

This branch has not been deployed

No deployments
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.

1 participant