skip to content

Authenticated Repositories

Supplying credentials to private repositories from gradle.properties or the environment instead of hardcoding them, plus header-based authentication schemes. A standard question about keeping secrets out of build scripts.

on this pageshow

questions

5

How do you configure a private Maven repository in Gradle that requires a username and password, and where should those secrets actually live?

level: juniorimportance: must knowfreq 70%

answer

  1. credentials(PasswordCredentials::class)
  2. <repoName>Username / <repoName>Password
  3. ~/.gradle/gradle.properties not project file
  4. ORG_GRADLE_PROJECT_ env var
  5. never hardcode in build script

basics

~10 s

Declare 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 s

You 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 lines
kotlin
repositories {
    maven {
        name = "mavenPrivate"
        url = uri("https://repo.example.com/private")
        credentials(PasswordCredentials::class)
    }
}

// ~/.gradle/gradle.properties (per-user, not committed):
// mavenPrivateUsername=alice
// mavenPrivatePassword=s3cr3t

go deeper

for a junior

Know that a private Maven repo needs a credentials block and that secrets belong in gradle.properties / env vars, not the build script.

for a middle

Explain the <repoName>Username/<repoName>Password naming convention and the precedence chain (CLI -P, ORG_GRADLE_PROJECT_ env, user-home file, project file).

for a senior

Discuss CI injection via ORG_GRADLE_PROJECT_ env vars and keeping the build script identical across all environments.

for a principal

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.

context

open as a page

Some private repositories authenticate with a token in an HTTP header rather than basic auth. How do you configure that in Gradle?

level: middleimportance: should knowfreq 45%

basics

~10 s

Use credentials(HttpHeaderCredentials::class) to set a header name and value (e.g. a bearer token), then declare authentication { create<HttpHeaderAuthentication>("header") } so Gradle sends that header.

open as a page

How do you supply private-repository credentials in CI without committing secrets, and how do you keep them from leaking into build logs or the cache?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Inject credentials as ORG_GRADLE_PROJECT_<name>Username/Password environment variables from the CI secret store. Keep them out of the repo, never echo them, and let Gradle treat them as credentials so they aren't printed.

open as a page

Why does Gradle recommend wiring repository credentials lazily via the Provider API, and what changes when you do?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Lazy credentials (e.g. credentials(PasswordCredentials::class) resolved through providers) are only required when the repo is actually used. Gradle then fails fast at configuration time with a clear error if a credential is missing — but only for tasks that need it.

open as a page

What does the `authentication {}` block control on a repository, and when would you explicitly choose BasicAuthentication versus the default behavior?

level: middleimportance: nice to knowfreq 25%

basics

~10 s

The authentication {} block picks which auth scheme Gradle uses for a repo. Adding create<BasicAuthentication>("basic") forces Gradle to send Basic credentials preemptively instead of waiting for a 401 challenge.

open as a page