Some artifact registries authenticate with a bearer/header token rather than basic username+password. How do you configure that in a Gradle repository?
answer
- HttpHeaderCredentials: name=header, value=token
- must add HttpHeaderAuthentication
- GitLab Private-Token / Bearer
- no repo-name convention here
- token from gradleProperty, not hardcoded
basics
~10 sUse 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 sWhen 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 linesmaven {
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
Awareness that a header/token option exists (HttpHeaderCredentials) is enough at this level.
Configure it correctly: name/value semantics plus the mandatory HttpHeaderAuthentication registration; know it's for registries like GitLab.
Explain the wire-format difference vs Basic, the bearer-token form, and keeping the token lazy via providers.gradleProperty.
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.