How do you configure a private Maven repository in Gradle that requires a username and password, and where should those secrets actually live?
answer
- credentials(PasswordCredentials::class)
- <repoName>Username / <repoName>Password
- ~/.gradle/gradle.properties not project file
- ORG_GRADLE_PROJECT_ env var
- never hardcode in build script
basics
~10 sDeclare the repo with a url and a credentials { username; password } block. Don't hardcode the secrets — read them from gradle.properties or environment variables instead.
solid answer
~30 sYou add a `maven { ... }` repository and supply `credentials(PasswordCredentials::class)` (or an inline `credentials { username = ...; password = ... }`). The key point is *not* to put the literal username/password in the build script, which is committed to version control. Instead store them in `~/.gradle/gradle.properties` as properties whose names match the repository name — e.g. for a repo named `mavenPrivate`, Gradle auto-binds `mavenPrivateUsername` and `mavenPrivatePassword` when you call `credentials(PasswordCredentials::class)`. They can also come from environment variables (`ORG_GRADLE_PROJECT_mavenPrivateUsername`) or be wired manually via `providers.gradleProperty(...)`. This keeps secrets out of the repo and lets CI inject them.
code
kotlin · 11 linesrepositories {
maven {
name = "mavenPrivate"
url = uri("https://repo.example.com/private")
credentials(PasswordCredentials::class)
}
}
// ~/.gradle/gradle.properties (per-user, not committed):
// mavenPrivateUsername=alice
// mavenPrivatePassword=s3cr3tgo deeper
Know that a private Maven repo needs a credentials block and that secrets belong in gradle.properties / env vars, not the build script.
Explain the <repoName>Username/<repoName>Password naming convention and the precedence chain (CLI -P, ORG_GRADLE_PROJECT_ env, user-home file, project file).
Discuss CI injection via ORG_GRADLE_PROJECT_ env vars and keeping the build script identical across all environments.
Frame the org policy: secrets never in VCS, central secret store feeding CI, per-developer user-home configuration, and auditing for leaked credentials.
## The problem A *private* artifact repository (a company Artifactory, Nexus, GitHub Packages, etc.) refuses anonymous reads. Gradle must present credentials when it resolves dependencies from that repo. The naive approach — typing the password into `build.gradle.kts` — leaks the secret into source control. Gradle gives you a structured way to supply credentials *and* a convention for sourcing them from outside the build. ## Two ways to attach credentials **1. Inline credentials block** — you set the values yourself: ```kotlin repositories { maven { url = uri("https://repo.example.com/private") credentials { username = providers.gradleProperty("repoUser").get() password = providers.gradleProperty("repoPassword").get() } } } ``` **2. Typed credentials with the naming convention** — `credentials(PasswordCredentials::class)` tells Gradle to look up `<repoName>Username` and `<repoName>Password` automatically: ```kotlin repositories { maven { name = "mavenPrivate" url = uri("https://repo.example.com/private") credentials(PasswordCredentials::class) } } ``` With the repo named `mavenPrivate`, Gradle resolves `mavenPrivateUsername` / `mavenPrivatePassword`. ## Where the values come from Gradle properties resolve from (highest precedence first): `-PmavenPrivateUsername=...` on the command line, the `ORG_GRADLE_PROJECT_mavenPrivateUsername` environment variable, `~/.gradle/gradle.properties` (per-user, NOT in the repo), then the project's `gradle.properties`. For secrets you want the *user-home* gradle.properties or the env var, never the project file. ## Why the convention matters With `credentials(PasswordCredentials::class)` and a per-user gradle.properties, the same build script works for every developer and for CI without any secret appearing in the repo. CI typically injects them as `ORG_GRADLE_PROJECT_*` env vars from its secret store.
- Why store the password in ~/.gradle/gradle.properties rather than the project's gradle.properties?The project file is committed to version control, so the secret would leak. The user-home file is per-machine and outside the repo, so it stays private and can differ per developer.
- If the repo is named 'mavenPrivate', what gradle.properties keys does credentials(PasswordCredentials::class) look up?mavenPrivateUsername and mavenPrivatePassword — Gradle derives the property names from the repository name plus the Username/Password suffixes.
saying these in an interview costs you the question
- Hardcoding username/password literals directly in build.gradle.kts.
- Putting secrets in the project gradle.properties (committed) instead of the user-home one.