skip to content

Some artifact registries authenticate with a bearer/header token rather than basic username+password. How do you configure that in a Gradle repository?

level: middleimportance: should knowfreq 40%

answer

  1. HttpHeaderCredentials: name=header, value=token
  2. must add HttpHeaderAuthentication
  3. GitLab Private-Token / Bearer
  4. no repo-name convention here
  5. token from gradleProperty, not hardcoded

basics

~10 s

Use credentials(HttpHeaderCredentials::class) and set a name (the header, e.g. Authorization or Private-Token) and value (the token). You must also add authentication { create<HttpHeaderAuthentication>("header") } so Gradle sends it as an HTTP header.

solid answer

~40 s

When a registry expects a token in an HTTP header (e.g. GitLab's `Private-Token`, or `Authorization: Bearer ...`), `PasswordCredentials` (HTTP Basic) doesn't fit. Gradle provides `HttpHeaderCredentials`, which has two fields: `name` (the header name) and `value` (the token). You configure it inside the repository and **must** also register the header authentication scheme via `authentication { create<HttpHeaderAuthentication>("header") }`, otherwise Gradle won't know to use header auth. The token itself should still come from a Gradle property / env var rather than being hardcoded — e.g. `value = providers.gradleProperty("gitlabToken").get()`. This is the standard pattern for registries that don't support Basic auth or that prefer scoped tokens.

code

kotlin · 11 lines
kotlin
maven {
    name = "gitlab"
    url = uri("https://gitlab.example.com/api/v4/projects/42/packages/maven")
    credentials(HttpHeaderCredentials::class) {
        name = "Private-Token"
        value = providers.gradleProperty("gitlabToken").get()
    }
    authentication {
        create<HttpHeaderAuthentication>("header")
    }
}

go deeper

for a junior

Awareness that a header/token option exists (HttpHeaderCredentials) is enough at this level.

for a middle

Configure it correctly: name/value semantics plus the mandatory HttpHeaderAuthentication registration; know it's for registries like GitLab.

for a senior

Explain the wire-format difference vs Basic, the bearer-token form, and keeping the token lazy via providers.gradleProperty.

for a principal

Decide token-auth strategy across registries, scoped/short-lived tokens, and standardize the pattern so teams don't fall into the missing-auth-block trap.

## When Basic auth isn't enough `PasswordCredentials` produces an HTTP **Basic** `Authorization` header from a username/password. Many modern registries instead want: - a custom header such as GitLab's `Private-Token: <token>`, or - a bearer token: `Authorization: Bearer <token>`. For these, Gradle offers `HttpHeaderCredentials`. ## Two required pieces Configuring header auth needs **both** the credentials and an explicit authentication scheme: ```kotlin maven { url = uri("https://gitlab.example.com/api/v4/projects/42/packages/maven") name = "gitlab" credentials(HttpHeaderCredentials::class) { name = "Private-Token" // the HTTP header name value = providers.gradleProperty("gitlabToken").get() // the token } authentication { create<HttpHeaderAuthentication>("header") } } ``` - `credentials(HttpHeaderCredentials::class) { ... }`: `name` is the **header name**, `value` is the **token**. - `authentication { create<HttpHeaderAuthentication>("header") }`: registers the `HttpHeaderAuthentication` scheme. **Without this block Gradle does not apply the header**, and you'll get 401s — a classic gotcha. ## Bearer tokens If the registry wants `Authorization: Bearer <token>`, set the header name to `Authorization` and the value to `"Bearer $token"`. ## Keep the token out of source Just like passwords, the token should come from a property/env var. Because `HttpHeaderCredentials` here is configured with a lambda, prefer `providers.gradleProperty("...")` so it stays lazy and configuration-cache friendly, rather than reading directly at script-evaluation time. ## Contrast with PasswordCredentials | Aspect | PasswordCredentials | HttpHeaderCredentials | |---|---|---| | Wire format | Basic `Authorization` | Arbitrary header | | Fields | `username`, `password` | `name` (header), `value` (token) | | Convention lookup by repo name | Yes (`<repo>Username/Password`) | No — you set values yourself | | Extra auth block needed | No | Yes (`HttpHeaderAuthentication`) | The key interview point: header auth requires the explicit `authentication`/`HttpHeaderAuthentication` registration, and `name`/`value` mean header-name/token (not username/password).

  • You configured HttpHeaderCredentials but keep getting 401s. What's the most likely cause?
    You forgot the `authentication { create<HttpHeaderAuthentication>("header") }` block, so Gradle never sends the header. Both the credentials and the auth scheme are required.
  • In HttpHeaderCredentials, what do `name` and `value` mean?
    `name` is the HTTP header name (e.g. `Private-Token` or `Authorization`) and `value` is the token to put in that header.
  • How would you send `Authorization: Bearer <token>`?
    Set `name = "Authorization"` and `value = "Bearer $token"`.

saying these in an interview costs you the question

  • Saying `HttpHeaderCredentials` uses `username`/`password` — it uses `name`/`value`.
  • Omitting the `HttpHeaderAuthentication` registration and assuming the header is sent automatically.
  • Assuming the `<repoName>Username` convention applies — it doesn't; you set values explicitly.
  • Hardcoding the token literal in the build script.

context