repositoryGrants =
+ decodeTokenRepositoryGrants(authorization.getToken());
+ return repositoryGrants == null || repositoryGrants.containsEntry(repository, "pull");
+ }
+
/** @return the registry endpoint's API root, without the protocol */
@VisibleForTesting
String getApiRouteBase() {
diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointRequestProperties.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointRequestProperties.java
index 4483344f74..2e125ec847 100644
--- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointRequestProperties.java
+++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointRequestProperties.java
@@ -16,19 +16,33 @@
package com.google.cloud.tools.jib.registry;
+import javax.annotation.Nullable;
+
/** Properties of registry endpoint requests. */
class RegistryEndpointRequestProperties {
private final String serverUrl;
private final String imageName;
+ @Nullable private final String sourceImageName;
/**
* @param serverUrl the server URL for the registry (for example, {@code gcr.io})
* @param imageName the image/repository name (also known as, namespace)
*/
RegistryEndpointRequestProperties(String serverUrl, String imageName) {
+ this(serverUrl, imageName, null);
+ }
+
+ /**
+ * @param serverUrl the server URL for the registry (for example, {@code gcr.io})
+ * @param imageName the image/repository name (also known as, namespace)
+ * @param sourceImageName additional source image to request pull permission from the registry
+ */
+ RegistryEndpointRequestProperties(
+ String serverUrl, String imageName, @Nullable String sourceImageName) {
this.serverUrl = serverUrl;
this.imageName = imageName;
+ this.sourceImageName = sourceImageName;
}
String getServerUrl() {
@@ -38,4 +52,9 @@ String getServerUrl() {
String getImageName() {
return imageName;
}
+
+ @Nullable
+ String getSourceImageName() {
+ return sourceImageName;
+ }
}
diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/RegistryCredentials.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/RegistryCredentials.java
deleted file mode 100644
index e2fc2ccb14..0000000000
--- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/credentials/RegistryCredentials.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2018 Google LLC.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.cloud.tools.jib.registry.credentials;
-
-import com.google.cloud.tools.jib.http.Authorization;
-
-/**
- * Stores retrieved registry credentials and their source.
- *
- * The credentials are referred to by the registry they are used for.
- */
-public class RegistryCredentials {
-
- private final Authorization authorization;
-
- /**
- * A string representation of where the credentials were retrieved from. This is useful for
- * letting the user know which credentials were used.
- */
- private final String credentialSource;
-
- public RegistryCredentials(String credentialSource, Authorization authorization) {
- this.authorization = authorization;
- this.credentialSource = credentialSource;
- }
-
- public Authorization getAuthorization() {
- return authorization;
- }
-
- public String getCredentialSource() {
- return credentialSource;
- }
-}
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/global/JibSystemPropertiesTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/global/JibSystemPropertiesTest.java
index f055a3c789..4fca87bef0 100644
--- a/jib-core/src/test/java/com/google/cloud/tools/jib/global/JibSystemPropertiesTest.java
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/global/JibSystemPropertiesTest.java
@@ -45,6 +45,7 @@ public void tearDown() {
if (httpsProxyPortSaved != null) {
System.setProperty("https.proxyPort", httpsProxyPortSaved);
}
+ System.clearProperty(JibSystemProperties.CROSS_REPOSITORY_BLOB_MOUNTS);
}
@Test
@@ -152,4 +153,33 @@ public void testCheckHttpProxyPortProperty_stringValue() {
Assert.assertEquals("https.proxyPort must be an integer: some string", ex.getMessage());
}
}
+
+ @Test
+ public void testUseBlobMountsPropertyName() {
+ Assert.assertEquals("jib.blobMounts", JibSystemProperties.CROSS_REPOSITORY_BLOB_MOUNTS);
+ }
+
+ @Test
+ public void testUseBlobMounts_undefined() {
+ System.clearProperty(JibSystemProperties.CROSS_REPOSITORY_BLOB_MOUNTS);
+ Assert.assertTrue(JibSystemProperties.useCrossRepositoryBlobMounts());
+ }
+
+ @Test
+ public void testUseBlobMounts_true() {
+ System.setProperty(JibSystemProperties.CROSS_REPOSITORY_BLOB_MOUNTS, "true");
+ Assert.assertTrue(JibSystemProperties.useCrossRepositoryBlobMounts());
+ }
+
+ @Test
+ public void testUseBlobMounts_false() {
+ System.setProperty(JibSystemProperties.CROSS_REPOSITORY_BLOB_MOUNTS, "false");
+ Assert.assertFalse(JibSystemProperties.useCrossRepositoryBlobMounts());
+ }
+
+ @Test
+ public void testUseBlobMounts_other() {
+ System.setProperty(JibSystemProperties.CROSS_REPOSITORY_BLOB_MOUNTS, "nonbool");
+ Assert.assertFalse(JibSystemProperties.useCrossRepositoryBlobMounts());
+ }
}
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetrieverTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetrieverTest.java
index 7eae71f001..d1e96c1787 100644
--- a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetrieverTest.java
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/AuthenticationMethodRetrieverTest.java
@@ -23,6 +23,7 @@
import com.google.cloud.tools.jib.http.Response;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collections;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
@@ -149,6 +150,7 @@ public void testHandleHttpResponseException_pass()
Assert.assertEquals(
new URL("https://somerealm?service=someservice&scope=repository:someImageName:someScope"),
- registryAuthenticator.getAuthenticationUrl(null, "someScope"));
+ registryAuthenticator.getAuthenticationUrl(
+ null, Collections.singletonMap("someImageName", "someScope")));
}
}
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/DockerRegistryBearerTokenTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/DockerRegistryBearerTokenTest.java
new file mode 100644
index 0000000000..451d8ba1da
--- /dev/null
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/DockerRegistryBearerTokenTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.tools.jib.registry;
+
+import com.google.api.client.util.Base64;
+import com.google.cloud.tools.jib.http.Authorization;
+import com.google.common.collect.Multimap;
+import java.nio.charset.StandardCharsets;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Tests for {@link RegistryClient} around handling of Docker Registry Bearer Tokens.
+ *
+ *
JWTs were generated from jwt.io's JWT Debugger. Set the
+ * algorithm to HS256, and paste the JSON shown as the Payload.
+ */
+public class DockerRegistryBearerTokenTest {
+ @Test
+ public void testDecode_dockerToken() {
+ // A genuine token from accessing docker.io's openjdk:
+ // {"access":[{"type":"repository","name":"library/openjdk","actions":["pull"]}]
+ // Generated by
+ // $ cd examples/helloworld
+ // $ mvn package jib:dockerBuild -Djib.from.image=openjdk \
+ // -Djava.util.logging.config.file=
+ Multimap decoded =
+ RegistryClient.decodeTokenRepositoryGrants(
+ "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsIng1YyI6WyJNSUlDK2pDQ0FwK2dBd0lCQWdJQkFEQUtCZ2dxaGtqT1BRUURBakJHTVVRd1FnWURWUVFERXpzeVYwNVpPbFZMUzFJNlJFMUVVanBTU1U5Rk9reEhOa0U2UTFWWVZEcE5SbFZNT2tZelNFVTZOVkF5VlRwTFNqTkdPa05CTmxrNlNrbEVVVEFlRncweE9UQXhNVEl3TURJeU5EVmFGdzB5TURBeE1USXdNREl5TkRWYU1FWXhSREJDQmdOVkJBTVRPMUpMTkZNNlMwRkxVVHBEV0RWRk9rRTJSMVE2VTBwTVR6cFFNbEpMT2tOWlZVUTZTMEpEU0RwWFNVeE1Pa3hUU2xrNldscFFVVHBaVWxsRU1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcjY2bXkveXpHN21VUzF3eFQ3dFplS2pqRzcvNnBwZFNMY3JCcko5VytwcndzMGtIUDVwUHRkMUpkcFdEWU1OZWdqQXhpUWtRUUNvd25IUnN2ODVUalBUdE5wUkdKVTRkeHJkeXBvWGc4TVhYUEUzL2lRbHhPS2VNU0prNlRKbG5wNGFtWVBHQlhuQXRoQzJtTlR5ak1zdFh2ZmNWN3VFYWpRcnlOVUcyUVdXQ1k1Ujl0a2k5ZG54Z3dCSEF6bG8wTzJCczFmcm5JbmJxaCtic3ZSZ1FxU3BrMWhxYnhSU3AyRlNrL2tBL1gyeUFxZzJQSUJxWFFMaTVQQ3krWERYZElJczV6VG9ZbWJUK0pmbnZaMzRLcG5mSkpNalpIRW4xUVJtQldOZXJZcVdtNVhkQVhUMUJrQU9aditMNFVwSTk3NFZFZ2ppY1JINVdBeWV4b1BFclRRSURBUUFCbzRHeU1JR3ZNQTRHQTFVZER3RUIvd1FFQXdJSGdEQVBCZ05WSFNVRUNEQUdCZ1JWSFNVQU1FUUdBMVVkRGdROUJEdFNTelJUT2t0QlMxRTZRMWcxUlRwQk5rZFVPbE5LVEU4NlVESlNTenBEV1ZWRU9rdENRMGc2VjBsTVREcE1VMHBaT2xwYVVGRTZXVkpaUkRCR0JnTlZIU01FUHpBOWdEc3lWMDVaT2xWTFMxSTZSRTFFVWpwU1NVOUZPa3hITmtFNlExVllWRHBOUmxWTU9rWXpTRVU2TlZBeVZUcExTak5HT2tOQk5sazZTa2xFVVRBS0JnZ3Foa2pPUFFRREFnTkpBREJHQWlFQXFOSXEwMFdZTmM5Z2tDZGdSUzRSWUhtNTRZcDBTa05Rd2lyMm5hSWtGd3dDSVFEMjlYdUl5TmpTa1cvWmpQaFlWWFB6QW9TNFVkRXNvUUhyUVZHMDd1N3ZsUT09Il19"
+ + ".eyJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6ImxpYnJhcnkvb3BlbmpkayIsImFjdGlvbnMiOlsicHVsbCJdfV0sImF1ZCI6InJlZ2lzdHJ5LmRvY2tlci5pbyIsImV4cCI6MTU2MTA0MzkwNSwiaWF0IjoxNTYxMDQzNjA1LCJpc3MiOiJhdXRoLmRvY2tlci5pbyIsImp0aSI6Ikc5bWpiOE9GeU5STFlpY3ZUMFZxIiwibmJmIjoxNTYxMDQzMzA1LCJzdWIiOiIifQ"
+ + ".jblwG_taIVf3IRiv200ivsc8q_IUj-M9QePKPAULfXdSZlY6H9n_XWtT6lw43k-J6QHfmnY4Yuh3eZq61KS7AT9yggM1VuolRCvYztSZ-MZHMIlvSE2KCc0wXa5gNQarjmDJloYduZuyLaKaRUUbO4osk1MuruODY_c2g2j16ce0Z8XVJ-7R8_J_Z8g0GdtFAfPO4bqpg9dj31MA8AKl3h-ru8NXcs3y1PkrYHpEGCgpcGcUQwLY7uiIrzjr0trCUbsLsv6iq2XTXnN_tTrfvL1R3yTB6gITvXZdsnU3r_UIDTzexTtlZWdntucJAGKX9HMA_jYEcTZ4ZhyEzETGpw");
+ Assert.assertEquals(1, decoded.size());
+ Assert.assertTrue(decoded.containsEntry("library/openjdk", "pull"));
+ Assert.assertFalse(decoded.containsEntry("library/openjdk", "push"));
+ Assert.assertFalse(decoded.containsEntry("randomrepo", "push"));
+ }
+
+ @Test
+ public void testDecode_nonToken() {
+ String base64Text =
+ Base64.encodeBase64String(
+ "something other than a JWT token".getBytes(StandardCharsets.UTF_8));
+ Multimap decoded = RegistryClient.decodeTokenRepositoryGrants(base64Text);
+ Assert.assertNull(decoded);
+ }
+
+ @Test
+ public void testDecode_invalidToken_accessString() {
+ // a JWT with an "access" field that is not an array: {"access": "string"}
+ String jwt =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOiJzdHJpbmcifQ.12ODBkkfh6J79qEejxwlD5AfOa9mjObPCzOnUL75NSQ";
+ Multimap decoded = RegistryClient.decodeTokenRepositoryGrants(jwt);
+ Assert.assertNull(decoded);
+ }
+
+ @Test
+ public void testDecode_invalidToken_accessArray() {
+ // a JWT with an "access" field that is an array of non-claim objects: {"access":["string"]}
+ String jwt =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOlsic3RyaW5nIl19.gWZ9J4sO_w0hIVVxrfuuUC2lNhqkU3P0_z46xMCXfwU";
+ Multimap decoded = RegistryClient.decodeTokenRepositoryGrants(jwt);
+ Assert.assertNull(decoded);
+ }
+
+ @Test
+ @Ignore("Annotate AccessClaim.actions to disallow coercion of integers to strings")
+ public void testDecode_invalidToken_actionsArray() {
+ // a JWT with an "access" field that is an action array of non-strings:
+ // {"access":[{"type": "repository","name": "library/openjdk","actions":[1]}]}
+ String jwt =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6ImxpYnJhcnkvb3BlbmpkayIsImFjdGlvbnMiOlsxXX1dfQ.12HZGeFvthXw0PP9ZKdttJRh2qsRfFNTeZV3_lZiI10";
+ Multimap decoded = RegistryClient.decodeTokenRepositoryGrants(jwt);
+ Assert.assertNull(decoded);
+ }
+
+ @Test
+ public void testDecode_invalidToken_randoJwt() {
+ // the JWT example token from jwt.io
+ String jwt =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
+ Multimap decoded = RegistryClient.decodeTokenRepositoryGrants(jwt);
+ Assert.assertNull(decoded);
+ }
+
+ /** Basic credential should allow access to all. */
+ @Test
+ public void testCanAttemptBlobMount_basicCredential() {
+ Authorization fixture = Authorization.fromBasicCredentials("foo", "bar");
+ Assert.assertTrue(RegistryClient.canAttemptBlobMount(fixture, "random"));
+ }
+
+ /** Basic token should allow access to all. */
+ @Test
+ public void testCanAttemptBlobMount_basicToken() {
+ // basic tokens are assumed to allow all repositories to be mounted
+ Authorization fixture = Authorization.fromBasicToken("gobbledygook");
+ Assert.assertTrue(RegistryClient.canAttemptBlobMount(fixture, "library/openjdk"));
+ Assert.assertTrue(RegistryClient.canAttemptBlobMount(fixture, "randomrepo"));
+ }
+
+ @Test
+ public void testCanAttemptBlobMount_bearer_withToken() {
+ // a synthetic token for accessing docker.io's openjdk with push and pull
+ // {"access":[{"type":"repository","name":"library/openjdk","actions":["pull","push"]}]}
+ String token =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6ImxpYnJhcnkvb3BlbmpkayIsImFjdGlvbnMiOlsicHVsbCIsInB1c2giXX1dfQ.VEn96Ug4eseKHX3WwP3PlgR9P7Y6VuYmMm-YRUjngFg";
+ Authorization authorization = Authorization.fromBearerToken(token);
+ Assert.assertNotNull(authorization);
+ Assert.assertTrue(RegistryClient.canAttemptBlobMount(authorization, "library/openjdk"));
+ Assert.assertFalse(RegistryClient.canAttemptBlobMount(authorization, "randomrepo"));
+ }
+
+ @Test
+ public void testCanAttemptBlobMount_bearer_withNonToken() {
+ // non-Docker Registry Bearer Tokens are assumed to allow access to all
+ // the JWT example token from jwt.io
+ String jwt =
+ "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
+ Authorization authorization = Authorization.fromBearerToken(jwt);
+ Assert.assertNotNull(authorization);
+ Assert.assertTrue(RegistryClient.canAttemptBlobMount(authorization, "library/openjdk"));
+ Assert.assertTrue(RegistryClient.canAttemptBlobMount(authorization, "randomrepo"));
+ }
+}
diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java
index d6481b8271..0f498051e6 100644
--- a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java
+++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryAuthenticatorTest.java
@@ -24,6 +24,7 @@
import java.net.URISyntaxException;
import java.net.URL;
import java.security.GeneralSecurityException;
+import java.util.Collections;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
@@ -55,7 +56,8 @@ public void testFromAuthenticationMethod_bearer()
"user-agent");
Assert.assertEquals(
new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"),
- registryAuthenticator.getAuthenticationUrl(null, "scope"));
+ registryAuthenticator.getAuthenticationUrl(
+ null, Collections.singletonMap("someimage", "scope")));
registryAuthenticator =
RegistryAuthenticator.fromAuthenticationMethod(
@@ -64,14 +66,16 @@ public void testFromAuthenticationMethod_bearer()
"user-agent");
Assert.assertEquals(
new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"),
- registryAuthenticator.getAuthenticationUrl(null, "scope"));
+ registryAuthenticator.getAuthenticationUrl(
+ null, Collections.singletonMap("someimage", "scope")));
}
@Test
public void testAuthRequestParameters_basicAuth() {
Assert.assertEquals(
"service=someservice&scope=repository:someimage:scope",
- registryAuthenticator.getAuthRequestParameters(null, "scope"));
+ registryAuthenticator.getAuthRequestParameters(
+ null, Collections.singletonMap("someimage", "scope")));
}
@Test
@@ -81,7 +85,8 @@ public void testAuthRequestParameters_oauth2() {
"service=someservice&scope=repository:someimage:scope"
+ "&client_id=jib.da031fe481a93ac107a95a96462358f9"
+ "&grant_type=refresh_token&refresh_token=oauth2_access_token",
- registryAuthenticator.getAuthRequestParameters(credential, "scope"));
+ registryAuthenticator.getAuthRequestParameters(
+ credential, Collections.singletonMap("someimage", "scope")));
}
@Test
@@ -105,7 +110,8 @@ public void isOAuth2Auth_oauth2() {
public void getAuthenticationUrl_basicAuth() throws MalformedURLException {
Assert.assertEquals(
new URL("https://somerealm?service=someservice&scope=repository:someimage:scope"),
- registryAuthenticator.getAuthenticationUrl(null, "scope"));
+ registryAuthenticator.getAuthenticationUrl(
+ null, Collections.singletonMap("someimage", "scope")));
}
@Test
@@ -113,7 +119,7 @@ public void istAuthenticationUrl_oauth2() throws MalformedURLException {
Credential credential = Credential.from("", "oauth2_token");
Assert.assertEquals(
new URL("https://somerealm"),
- registryAuthenticator.getAuthenticationUrl(credential, "scope"));
+ registryAuthenticator.getAuthenticationUrl(credential, Collections.emptyMap()));
}
@Test
@@ -176,7 +182,8 @@ public void testFromAuthenticationMethod_noService()
Assert.assertEquals(
new URL("https://somerealm?service=someserver&scope=repository:someimage:scope"),
- registryAuthenticator.getAuthenticationUrl(null, "scope"));
+ registryAuthenticator.getAuthenticationUrl(
+ null, Collections.singletonMap("someimage", "scope")));
}
@Test
diff --git a/jib-gradle-plugin/CHANGELOG.md b/jib-gradle-plugin/CHANGELOG.md
index 87865969d9..3e786f2334 100644
--- a/jib-gradle-plugin/CHANGELOG.md
+++ b/jib-gradle-plugin/CHANGELOG.md
@@ -15,6 +15,8 @@ All notable changes to this project will be documented in this file.
### Fixed
+- Re-enabled cross-repository blob mounts ([#1793](https://github.com/GoogleContainerTools/jib/pull/1793))
+
## 1.3.0
### Changed
diff --git a/jib-maven-plugin/CHANGELOG.md b/jib-maven-plugin/CHANGELOG.md
index ed3b0e6c58..c9a260a56b 100644
--- a/jib-maven-plugin/CHANGELOG.md
+++ b/jib-maven-plugin/CHANGELOG.md
@@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.
### Fixed
+- Re-enabled cross-repository blob mounts ([#1793](https://github.com/GoogleContainerTools/jib/pull/1793))
+
## 1.3.0
### Changed