rules_jvm_external
rules_jvm_external copied to clipboard
Failed to get artifact from private repo when using URL basic auth
Hi all, I have artifacts hosted on a private repository using jfrog. In my workspace file, I have a maven_install rule with
artifacts = [
'com.functorz:ztype:0.3.19',
],
repositories = [
"https://repo1.maven.org/maven2",
"https://geoff%40functorz.com:<password>@functorz.jfrog.io/artifactory/maven",
]
and in a build rule, I have a dependency on @maven//:com_functorz_ztype. Running bazel build yields the following error:
Resolution error: Error downloading com.functorz:ztype:0.3.19
not found: https://repo1.maven.org/maven2/com/functorz/ztype/0.3.19/ztype-0.3.19.pom
forbidden: https://functorz.jfrog.io/artifactory/maven/com/functorz/ztype/0.3.19/ztype-0.3.19.pom
Some observations:
- Trying it with
curlforhttps://geoff%40functorz.com:<password>@functorz.jfrog.io/artifactory/maven/com/functorz/ztype/0.3.19/ztype-0.3.19.pomreturns the pom file successfully - Using a credentials file via
COURSIER_CREDENTIALSworks as well
My best guess at the moment is that both my username (email) and password have special characters in them. I used url encoded versions of them in the URL, which works fine for curl. Is it possible that in the interactions between Bazel and Coursier, this case isn't handled properly?
Anyway, just a guess. Happy to help debug and provide more info if needed.
OK, I did a bit more digging, here are some more notes in no particular order:
- When passing repositories as an object (i.e.
{ repo_url: ..., user: ..., password: ... }), the--credentialsflag passed to java args file is broken. Thehost user:passstring is not properly quoted to handle the space, and Coursier will choke up. (This could probably be a separate issue on its own) - Passing a URL encoded username or password as part of the URL to Coursier is not decoded and results in a "forbidden"
- Passing unencoded username or password with an
@in it causes Coursier to mistake the@as the start of the host. Interestingly, the Bazel scripts handles this case by doing anrsplit(@, 1)
At the moment, the only workaround is to pass a credentials file using an environment variable.
When downloading (and assuming pinning), Bazel should be using your .netrc file for authentication. When pinning (or not using pinned downloads), you're likely correct.
For now, (as you say) I would strongly recommend using the COURSIER_CREDENTIALS environment variable.
Just in case someone stumbles on this issue while looking for how to solve this problem, I'll detail the required steps here.
First, create a ~/.config/coursier/credentials.properties file which should contain your authentication credentials.
maven.username=
Secondly, export this the absolute path to this file as COUSIER_CREDENTIALS via your shell's rc file (eg. .bashrc or .zshrc). Start a new shell or export the env var manually if you don't want to start a new shell session.
I know that a workaround is far from ideal, but while we're finding the time to address this issue, I hope this solution is okay.
If finding a better solution is urgent for you, and you'd like to send a PR to address any (all? :) ) of these problems, I'd be very happy to review it.
@shs96c think you have a typo in the env var missing an R, coursier vs cousier.
Side question does this invalidate how the DAG is calculated and invalidate remote caches if the auth is different?