Gradle plugin which authenticates against AWS CodeArtifact using your local credentials to obtain the token.
The plugin automatically detects any Maven repository whose URL matches a CodeArtifact endpoint and injects the appropriate credentials — no extra configuration needed.
Both public endpoint shapes that aws codeartifact get-repository-endpoint returns are recognised:
| Endpoint type | Repository URL |
|---|---|
ipv4 |
https://{domain}-{owner}.d.codeartifact.{region}.amazonaws.com/{format}/{repository}/ |
dualstack |
https://{domain}-{owner}.codeartifact.{region}.on.aws/{format}/{repository}/ |
Note the dualstack host has no .d. segment. VPC endpoints are not supported: they carry the domain and owner in the
path rather than the host.
The plugin can be applied to either your project's build.gradle(.kts) file or to your settings.gradle(.kts) file.
Apply the plugin to your build.gradle.kts (Kotlin DSL) or build.gradle (Groovy DSL) to automatically configure repositories in thatproject.
In your build.gradle.kts file:
plugins {
id("ai.clarity.codeartifact") version "0.2.1"
}
repositories {
maven {
url = uri("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/")
}
}In your build.gradle.kts file:
plugins {
id("ai.clarity.codeartifact") version "0.2.1"
}
publishing {
repositories {
maven {
url = uri("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/")
}
}
}In your build.gradle file:
plugins {
id 'ai.clarity.codeartifact' version '0.2.1'
}
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
}
}In your build.gradle file:
plugins {
id 'ai.clarity.codeartifact' version '0.2.1'
}
publishing {
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
}
}
}Instead of relying on automatic detection via maven { url ... }, you can use the codeartifact() helper method
directly on the repositories block. This method accepts the repository URL, an optional profile name or the
credentials of a service account, and an optional configuration closure/action.
Note: The
codeartifact()helper can be used inbuild.gradle(.kts), and insettings.gradle(.kts)insidedependencyResolutionManagement. It cannot be used insidepluginManagement, which Gradle evaluates before theplugins { }block applies this plugin. Usemaven { url ... }there and rely on automatic detection.
repositories {
codeartifact("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/")
// With a specific profile:
codeartifact("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/", "prod")
// With a specific profile and additional repository configuration:
codeartifact("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/", "prod") {
name = "myCodeArtifactRepo"
}
// With the credentials of a service account instead of a profile:
codeartifact(
"https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/",
CodeArtifactCredentials.of(
providers.gradleProperty("codeArtifactAccessKeyId").get(),
providers.gradleProperty("codeArtifactSecretAccessKey").get()
)
)
}Note: in
build.gradle.ktsthe helper and the credentials class have to be imported:import ai.clarity.codeartifact.codeartifactandimport ai.clarity.codeartifact.CodeArtifactCredentials.
repositories {
codeartifact('https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/')
// With a specific profile:
codeartifact('https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/', 'prod')
// With a specific profile and additional repository configuration:
codeartifact('https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/', 'prod') {
name = 'myCodeArtifactRepo'
}
// With the credentials of a service account instead of a profile:
codeartifact('https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/', [
accessKeyId : providers.gradleProperty('codeArtifactAccessKeyId').get(),
secretAccessKey: providers.gradleProperty('codeArtifactSecretAccessKey').get()
])
}Applying the plugin in settings.gradle.kts or settings.gradle allows you to centralize repository configuration for all projects in the
build, including pluginManagement and dependencyResolutionManagement.
Note: Inside
pluginManagementthecodeartifact()helper is not available, because Gradle evaluates that block before theplugins { }block applies this plugin. Use the standardmaven { url ... }approach there and rely on automatic detection. InsidedependencyResolutionManagementthe helper does work.
In your settings.gradle.kts file:
plugins {
id("ai.clarity.codeartifact") version "0.2.1"
}
dependencyResolutionManagement {
repositories {
maven {
url = uri("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/")
}
}
}In your settings.gradle.kts file:
plugins {
id("ai.clarity.codeartifact") version "0.2.1"
}
pluginManagement {
repositories {
maven {
url = uri("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/")
}
}
}In your settings.gradle file:
plugins {
id 'ai.clarity.codeartifact' version '0.2.1'
}
dependencyResolutionManagement {
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
}
}
}In your settings.gradle file:
plugins {
id 'ai.clarity.codeartifact' version '0.2.1'
}
pluginManagement {
repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/'
}
}
}If you need a concrete profile for AWS authentication, you have 4 different options:
repositories {
maven {
url = uri("https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/?profile=prod")
}
}repositories {
maven {
url 'https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/?profile=prod'
}
}Note: The query param is used to configure the profile and is automatically removed from the URL in any request to AWS.
This plugin uses the AWS SDK for authorization, all the standard environment variables are applicable.
If you need a different profile for CodeArtifact than for the rest of your AWS calls you can use this environment variable.
If you need a different profile for CodeArtifact and you cannot define an environment variable, you can define it as a Gradle property.
Using the gradle.properties file:
codeartifact.profile=<your profile>Or using the command line:
gradle -Pcodeartifact.profile=<your profile> ...The system property form is equally supported, for builds that already use it:
systemProp.codeartifact.profile=<your profile> in gradle.properties, or
-Dcodeartifact.profile=<your profile> on the command line.
To give every developer a default profile without any local setup, while still letting CI/CD
override it, commit the default to the project's gradle.properties instead of using the
?profile= query param:
# gradle.properties (committed with the project)
codeartifact.profile=devLocal builds then use the dev profile out of the box, and CI/CD overrides it from the
command line:
gradle -Pcodeartifact.profile=ci ...Keep in mind:
- Match the override to the form you committed. A Gradle property is overridden with
-P, asystemProp.one with-D. Since the Gradle property is the one that wins, a-Dagainst a committed plaincodeartifact.profileis ignored — the build warns when that happens rather than authenticating with the wrong profile silently. - Neither
CODEARTIFACT_PROFILEnor any other environment variable takes precedence over a profile defined ingradle.properties. When a plain entry shadows a differently-valuedCODEARTIFACT_PROFILE, the build warns, since that usually means an exported override has stopped working. - A developer can override the project default for their machine in
~/.gradle/gradle.properties, which takes precedence over the project file. - Do not combine this pattern with
?profile=in the repository URL: the query param has the highest precedence and would defeat the override.
On CI/CD, or on any machine without an ~/.aws/credentials file, the plugin can authenticate with the static access
keys of a service account — an IAM user or a set of temporary credentials — instead of an AWS profile.
Configure the access key id and the secret access key. Each value is read from its Gradle property first, from the system property of the same name second, and from its environment variable last:
| Value | Gradle / system property | Environment variable | Required |
|---|---|---|---|
| Access key id | codeartifact.accessKeyId |
CODEARTIFACT_ACCESS_KEY_ID |
Yes |
| Secret access key | codeartifact.secretAccessKey |
CODEARTIFACT_SECRET_ACCESS_KEY |
Yes |
| Session token | codeartifact.sessionToken |
CODEARTIFACT_SESSION_TOKEN |
Only for temporary credentials |
In a CI/CD pipeline, export them from the secret store of your platform:
export CODEARTIFACT_ACCESS_KEY_ID=<your access key id>
export CODEARTIFACT_SECRET_ACCESS_KEY=<your secret access key>On a developer machine, declare them in ~/.gradle/gradle.properties, which lives outside the project:
codeartifact.accessKeyId=<your access key id>
codeartifact.secretAccessKey=<your secret access key>The systemProp.codeartifact.accessKeyId form works too, for builds that already use it.
They then apply to every CodeArtifact repository of the build, including the ones declared in settings.gradle(.kts),
and they take precedence over the codeartifact.profile / CODEARTIFACT_PROFILE configuration.
Warning: never commit these values to the project
gradle.properties. There is deliberately no?accessKeyId=query param either, because the repository URL ends up in build scans, caches and logs. The plugin only writes a masked access key id (AKIA************MPLE) to the build log, never the secret.
Setting only one of the two required values fails the build with an explicit message, instead of silently falling back to another set of credentials.
When repositories belong to different AWS accounts, pass the credentials to the codeartifact() helper. Read the
values from Gradle properties or from the environment rather than hardcoding them in the build script.
import ai.clarity.codeartifact.CodeArtifactCredentials
import ai.clarity.codeartifact.codeartifact
repositories {
codeartifact(
"https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/",
CodeArtifactCredentials.of(
providers.gradleProperty("codeArtifactAccessKeyId").get(),
providers.gradleProperty("codeArtifactSecretAccessKey").get()
)
) {
name = "myCodeArtifactRepo"
}
}repositories {
codeartifact('https://domain-id.d.codeartifact.eu-central-1.amazonaws.com/maven/repository/', [
accessKeyId : providers.gradleProperty('codeArtifactAccessKeyId').get(),
secretAccessKey: providers.gradleProperty('codeArtifactSecretAccessKey').get()
// add a sessionToken entry only for temporary credentials
]) {
name = 'myCodeArtifactRepo'
}
}Note: the
codeartifact()helper also works insettings.gradle(.kts)insidedependencyResolutionManagement, but not insidepluginManagement. Use the build-wide configuration above for the repositories declared there.
The plugin uses the configuration closest to the repository, and prefers service account credentials over profiles at the same level:
- Credentials passed to the
codeartifact()helper - Profile passed to the
codeartifact()helper, or?profile=query parameter in the repository URL codeartifact.accessKeyIdandcodeartifact.secretAccessKeycodeartifact.profile- The AWS SDK default credentials provider chain (
AWS_PROFILE,AWS_ACCESS_KEY_ID, instance roles, …)
Every codeartifact.* setting in steps 3 and 4 is looked up in three places, in this order:
- the Gradle property — written plainly in
gradle.properties, or passed as-P - the Java system property — written as
systemProp.ingradle.properties, or passed as-D - the environment variable —
CODEARTIFACT_PROFILE,CODEARTIFACT_ACCESS_KEY_ID, …
The first place that holds the setting wins, even when the value is blank; a blank value then resolves to "not
configured" rather than falling through to the next place. When a Gradle property shadows a system property — or, with
no system property set, an environment variable — holding a different value, the build warns, because that is usually a
-D or exported override that has stopped working.
Note: step 4 only applies to the repositories detected automatically. A repository declared with the
codeartifact()helper and no explicit profile falls back to thedefaultprofile instead, socodeartifact.profilehas no effect on it. Pass the profile to the helper if you need another one.
The incomplete-configuration check on step 3 runs only when steps 1 and 2 did not already settle the authentication:
with a ?profile= in the URL, or a profile passed to the helper, a half-configured pair of service credentials is
ignored rather than reported.
This project is licensed under the Apache License 2.0.