aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cloud-tenant-base-dependencies-enforcer/pom.xml2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java6
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java42
-rw-r--r--parent/pom.xml2
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/DefaultSignedIdentityDocument.java14
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java124
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java54
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocumentClient.java6
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/LegacySignedIdentityDocument.java6
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/SignedIdentityDocument.java52
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/DefaultSignedIdentityDocumentEntity.java12
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java51
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/LegacySignedIdentityDocumentEntity.java57
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java124
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java18
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java2
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/DefaultIdentityDocumentClient.java11
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSigner.java50
-rw-r--r--vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java43
-rw-r--r--vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java68
-rw-r--r--vespa-dependencies-enforcer/allowed-maven-dependencies.txt28
21 files changed, 197 insertions, 575 deletions
diff --git a/cloud-tenant-base-dependencies-enforcer/pom.xml b/cloud-tenant-base-dependencies-enforcer/pom.xml
index 69e1a94a813..7971f4eebcf 100644
--- a/cloud-tenant-base-dependencies-enforcer/pom.xml
+++ b/cloud-tenant-base-dependencies-enforcer/pom.xml
@@ -45,7 +45,7 @@
<javax.servlet-api.version>3.1.0</javax.servlet-api.version>
<javax.ws.rs-api.version>2.0.1</javax.ws.rs-api.version>
<jaxb.version>2.3.0</jaxb.version>
- <jetty.version>11.0.14</jetty.version>
+ <jetty.version>11.0.15</jetty.version>
<org.lz4.version>1.8.0</org.lz4.version>
<org.json.version>20230227</org.json.version> <!-- TODO: Remove on Vespa 9 -->
<slf4j.version>1.7.32</slf4j.version> <!-- WARNING: when updated, also update c.y.v.tenant:base pom -->
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index e89724dfb16..0a5cd1aacac 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -410,12 +410,6 @@ public class Flags {
"Takes effect at redeployment",
ZONE_ID);
- public static final UnboundBooleanFlag NEW_IDDOC_LAYOUT = defineFeatureFlag(
- "new_iddoc_layout", false, List.of("tokle", "bjorncs", "olaa"), "2023-04-24", "2023-05-31",
- "Whether to use new identity document lauoyt",
- "Takes effect on node reboot",
- HOSTNAME);
-
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java
index c9c76e1edd3..3fb9c73367d 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java
@@ -13,7 +13,6 @@ import com.yahoo.vespa.athenz.client.zts.ZtsClient;
import com.yahoo.vespa.athenz.client.zts.ZtsClientException;
import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider;
import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper;
-import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocumentClient;
import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.client.CsrGenerator;
@@ -77,7 +76,6 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
private final ServiceIdentityProvider hostIdentityProvider;
private final IdentityDocumentClient identityDocumentClient;
private final BooleanFlag tenantServiceIdentityFlag;
- private final BooleanFlag useNewIdentityDocumentLayout;
// Used as an optimization to ensure ZTS is not DDoS'ed on continuously failing refresh attempts
private final Map<ContainerName, Instant> lastRefreshAttempt = new ConcurrentHashMap<>();
@@ -99,7 +97,6 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
new AthenzIdentityVerifier(Set.of(configServerInfo.getConfigServerIdentity())));
this.clock = clock;
this.tenantServiceIdentityFlag = Flags.NODE_ADMIN_TENANT_SERVICE_REGISTRY.bindTo(flagSource);
- this.useNewIdentityDocumentLayout = Flags.NEW_IDDOC_LAYOUT.bindTo(flagSource);
}
public boolean converge(NodeAgentContext context) {
@@ -133,7 +130,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
Instant now = clock.instant();
Instant expiry = certificate.getNotAfter().toInstant();
var doc = EntityBindingsMapper.readSignedIdentityDocumentFromFile(identityDocumentFile);
- if (refreshIdentityDocument(doc, context)) {
+ if (doc.outdated()) {
context.log(logger, "Identity document is outdated (version=%d)", doc.documentVersion());
registerIdentity(context, privateKeyFile, certificateFile, identityDocumentFile, identityType, athenzIdentity);
return true;
@@ -153,7 +150,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
return false;
} else {
lastRefreshAttempt.put(context.containerName(), now);
- refreshIdentity(context, privateKeyFile, certificateFile, identityDocumentFile, doc.identityDocument(), identityType, athenzIdentity);
+ refreshIdentity(context, privateKeyFile, certificateFile, identityDocumentFile, doc, identityType, athenzIdentity);
return true;
}
}
@@ -164,11 +161,6 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
}
}
- private boolean refreshIdentityDocument(SignedIdentityDocument signedIdentityDocument, NodeAgentContext context) {
- int expectedVersion = documentVersion(context);
- return signedIdentityDocument.outdated() || signedIdentityDocument.documentVersion() != expectedVersion;
- }
-
public void clearCredentials(NodeAgentContext context) {
FileFinder.files(context.paths().of(CONTAINER_SIA_DIRECTORY))
.deleteRecursively(context);
@@ -208,8 +200,7 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
private void registerIdentity(NodeAgentContext context, ContainerPath privateKeyFile, ContainerPath certificateFile, ContainerPath identityDocumentFile, IdentityType identityType, AthenzIdentity identity) {
KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
- SignedIdentityDocument signedDoc = signedIdentityDocument(context, identityType);
- IdentityDocument doc = signedDoc.identityDocument();
+ SignedIdentityDocument doc = signedIdentityDocument(context, identityType);
CsrGenerator csrGenerator = new CsrGenerator(certificateDnsSuffix, doc.providerService().getFullName());
Pkcs10Csr csr = csrGenerator.generateInstanceCsr(
identity, doc.providerUniqueId(), doc.ipAddresses(), doc.clusterType(), keyPair);
@@ -221,9 +212,9 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
ztsClient.registerInstance(
doc.providerService(),
identity,
- EntityBindingsMapper.toAttestationData(signedDoc),
+ EntityBindingsMapper.toAttestationData(doc),
csr);
- EntityBindingsMapper.writeSignedIdentityDocumentToFile(identityDocumentFile, signedDoc);
+ EntityBindingsMapper.writeSignedIdentityDocumentToFile(identityDocumentFile, doc);
writePrivateKeyAndCertificate(privateKeyFile, keyPair.getPrivate(), certificateFile, instanceIdentity.certificate());
context.log(logger, "Instance successfully registered and credentials written to file");
}
@@ -232,14 +223,14 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
/**
* Return zts url from identity document, fallback to ztsEndpoint
*/
- private URI ztsEndpoint(IdentityDocument doc) {
+ private URI ztsEndpoint(SignedIdentityDocument doc) {
return Optional.ofNullable(doc.ztsUrl())
.filter(s -> !s.isBlank())
.map(URI::create)
.orElse(ztsEndpoint);
}
private void refreshIdentity(NodeAgentContext context, ContainerPath privateKeyFile, ContainerPath certificateFile,
- ContainerPath identityDocumentFile, IdentityDocument doc, IdentityType identityType, AthenzIdentity identity) {
+ ContainerPath identityDocumentFile, SignedIdentityDocument doc, IdentityType identityType, AthenzIdentity identity) {
KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
CsrGenerator csrGenerator = new CsrGenerator(certificateDnsSuffix, doc.providerService().getFullName());
Pkcs10Csr csr = csrGenerator.generateInstanceCsr(
@@ -300,8 +291,8 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
private SignedIdentityDocument signedIdentityDocument(NodeAgentContext context, IdentityType identityType) {
return switch (identityType) {
- case NODE -> identityDocumentClient.getNodeIdentityDocument(context.hostname().value(), documentVersion(context));
- case TENANT -> identityDocumentClient.getTenantIdentityDocument(context.hostname().value(), documentVersion(context));
+ case NODE -> identityDocumentClient.getNodeIdentityDocument(context.hostname().value());
+ case TENANT -> identityDocumentClient.getTenantIdentityDocument(context.hostname().value());
};
}
@@ -314,9 +305,9 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
private AthenzIdentity getTenantIdentity(NodeAgentContext context, ContainerPath identityDocumentFile) {
if (Files.exists(identityDocumentFile)) {
- return EntityBindingsMapper.readSignedIdentityDocumentFromFile(identityDocumentFile).identityDocument().serviceIdentity();
+ return EntityBindingsMapper.readSignedIdentityDocumentFromFile(identityDocumentFile).serviceIdentity();
} else {
- return identityDocumentClient.getTenantIdentityDocument(context.hostname().value(), documentVersion(context)).identityDocument().serviceIdentity();
+ return identityDocumentClient.getTenantIdentityDocument(context.hostname().value()).serviceIdentity();
}
}
@@ -326,17 +317,6 @@ public class AthenzCredentialsMaintainer implements CredentialsMaintainer {
.value();
}
- /*
- Get the document version to ask for
- */
- private int documentVersion(NodeAgentContext context) {
- return useNewIdentityDocumentLayout
- .with(FetchVector.Dimension.HOSTNAME, context.hostname().value())
- .value()
- ? SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION
- : SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION;
- }
-
enum IdentityType {
NODE("vespa-node-identity-document.json"),
TENANT("vespa-tenant-identity-document.json");
diff --git a/parent/pom.xml b/parent/pom.xml
index e6ef7e873fd..f3b9fc9baeb 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1155,7 +1155,7 @@
<felix.log.version>1.0.1</felix.log.version>
<findbugs.version>3.0.2</findbugs.version> <!-- Should be kept in sync with guava -->
<hdrhistogram.version>2.1.12</hdrhistogram.version>
- <jetty.version>11.0.14</jetty.version>
+ <jetty.version>11.0.15</jetty.version>
<jetty-servlet-api.version>5.0.2</jetty-servlet-api.version>
<jjwt.version>0.11.2</jjwt.version>
<jna.version>5.11.0</jna.version>
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/DefaultSignedIdentityDocument.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/DefaultSignedIdentityDocument.java
deleted file mode 100644
index c2ab22f4921..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/DefaultSignedIdentityDocument.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.identityprovider.api;
-
-public record DefaultSignedIdentityDocument(String signature, int signingKeyVersion, int documentVersion,
- String data, IdentityDocument identityDocument) implements SignedIdentityDocument {
-
- public DefaultSignedIdentityDocument {
- identityDocument = EntityBindingsMapper.fromIdentityDocumentData(data);
- }
-
- public DefaultSignedIdentityDocument(String signature, int signingKeyVersion, int documentVersion, String data) {
- this(signature,signingKeyVersion,documentVersion, data, null);
- }
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java
index a695e10a29c..2d77d2ceda1 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapper.java
@@ -6,12 +6,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzService;
-import com.yahoo.vespa.athenz.identityprovider.api.bindings.DefaultSignedIdentityDocumentEntity;
-import com.yahoo.vespa.athenz.identityprovider.api.bindings.IdentityDocumentEntity;
-import com.yahoo.vespa.athenz.identityprovider.api.bindings.LegacySignedIdentityDocumentEntity;
import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity;
import com.yahoo.vespa.athenz.utils.AthenzIdentities;
-import com.yahoo.yolean.Exceptions;
import java.io.IOException;
import java.io.InputStream;
@@ -20,8 +16,6 @@ import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
-import java.time.Instant;
-import java.util.Base64;
import java.util.Optional;
import static com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId.fromDottedString;
@@ -30,7 +24,6 @@ import static com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId.
* Utility class for mapping objects model types and their Jackson binding versions.
*
* @author bjorncs
- * @author mortent
*/
public class EntityBindingsMapper {
@@ -55,60 +48,39 @@ public class EntityBindingsMapper {
}
public static SignedIdentityDocument toSignedIdentityDocument(SignedIdentityDocumentEntity entity) {
- if (entity instanceof LegacySignedIdentityDocumentEntity docEntity) {
- IdentityDocument doc = new IdentityDocument(
- fromDottedString(docEntity.providerUniqueId()),
- new AthenzService(docEntity.providerService()),
- docEntity.configServerHostname(),
- docEntity.instanceHostname(),
- docEntity.createdAt(),
- docEntity.ipAddresses(),
- IdentityType.fromId(docEntity.identityType()),
- Optional.ofNullable(docEntity.clusterType()).map(ClusterType::from).orElse(null),
- docEntity.ztsUrl(),
- Optional.ofNullable(docEntity.serviceIdentity()).map(AthenzIdentities::from).orElse(null),
- docEntity.unknownAttributes());
- return new LegacySignedIdentityDocument(
- docEntity.signature(),
- docEntity.signingKeyVersion(),
- entity.documentVersion(),
- doc);
- } else if (entity instanceof DefaultSignedIdentityDocumentEntity docEntity) {
- return new DefaultSignedIdentityDocument(docEntity.signature(),
- docEntity.signingKeyVersion(),
- docEntity.documentVersion(),
- docEntity.data());
- } else {
- throw new IllegalArgumentException("Unknown signed identity document type: " + entity.getClass().getName());
- }
+ return new SignedIdentityDocument(
+ entity.signature(),
+ entity.signingKeyVersion(),
+ fromDottedString(entity.providerUniqueId()),
+ new AthenzService(entity.providerService()),
+ entity.documentVersion(),
+ entity.configServerHostname(),
+ entity.instanceHostname(),
+ entity.createdAt(),
+ entity.ipAddresses(),
+ IdentityType.fromId(entity.identityType()),
+ Optional.ofNullable(entity.clusterType()).map(ClusterType::from).orElse(null),
+ entity.ztsUrl(),
+ Optional.ofNullable(entity.serviceIdentity()).map(AthenzIdentities::from).orElse(null),
+ entity.unknownAttributes());
}
public static SignedIdentityDocumentEntity toSignedIdentityDocumentEntity(SignedIdentityDocument model) {
- if (model instanceof LegacySignedIdentityDocument legacyModel) {
- IdentityDocument idDoc = legacyModel.identityDocument();
- return new LegacySignedIdentityDocumentEntity(
- legacyModel.signature(),
- legacyModel.signingKeyVersion(),
- idDoc.providerUniqueId().asDottedString(),
- idDoc.providerService().getFullName(),
- legacyModel.documentVersion(),
- idDoc.configServerHostname(),
- idDoc.instanceHostname(),
- idDoc.createdAt(),
- idDoc.ipAddresses(),
- idDoc.identityType().id(),
- Optional.ofNullable(idDoc.clusterType()).map(ClusterType::toConfigValue).orElse(null),
- idDoc.ztsUrl(),
- Optional.ofNullable(idDoc.serviceIdentity()).map(AthenzIdentity::getFullName).orElse(null),
- idDoc.unknownAttributes());
- } else if (model instanceof DefaultSignedIdentityDocument defaultModel){
- return new DefaultSignedIdentityDocumentEntity(defaultModel.signature(),
- defaultModel.signingKeyVersion(),
- defaultModel.documentVersion(),
- defaultModel.data());
- } else {
- throw new IllegalArgumentException("Unsupported model type: " + model.getClass().getName());
- }
+ return new SignedIdentityDocumentEntity(
+ model.signature(),
+ model.signingKeyVersion(),
+ model.providerUniqueId().asDottedString(),
+ model.providerService().getFullName(),
+ model.documentVersion(),
+ model.configServerHostname(),
+ model.instanceHostname(),
+ model.createdAt(),
+ model.ipAddresses(),
+ model.identityType().id(),
+ Optional.ofNullable(model.clusterType()).map(ClusterType::toConfigValue).orElse(null),
+ model.ztsUrl(),
+ Optional.ofNullable(model.serviceIdentity()).map(AthenzIdentity::getFullName).orElse(null),
+ model.unknownAttributes());
}
public static SignedIdentityDocument readSignedIdentityDocumentFromFile(Path file) {
@@ -132,40 +104,4 @@ public class EntityBindingsMapper {
}
}
- public static IdentityDocument fromIdentityDocumentData(String data) {
- byte[] decoded = Base64.getDecoder().decode(data);
- IdentityDocumentEntity docEntity = Exceptions.uncheck(() -> mapper.readValue(decoded, IdentityDocumentEntity.class));
- return new IdentityDocument(
- fromDottedString(docEntity.providerUniqueId()),
- new AthenzService(docEntity.providerService()),
- docEntity.configServerHostname(),
- docEntity.instanceHostname(),
- docEntity.createdAt(),
- docEntity.ipAddresses(),
- IdentityType.fromId(docEntity.identityType()),
- Optional.ofNullable(docEntity.clusterType()).map(ClusterType::from).orElse(null),
- docEntity.ztsUrl(),
- Optional.ofNullable(docEntity.serviceIdentity()).map(AthenzIdentities::from).orElse(null),
- docEntity.unknownAttributes());
- }
-
- public static String toIdentityDocmentData(IdentityDocument identityDocument) {
- IdentityDocumentEntity documentEntity = new IdentityDocumentEntity(
- identityDocument.providerUniqueId().asDottedString(),
- identityDocument.providerService().getFullName(),
- identityDocument.configServerHostname(),
- identityDocument.instanceHostname(),
- identityDocument.createdAt(),
- identityDocument.ipAddresses(),
- identityDocument.identityType().id(),
- Optional.ofNullable(identityDocument.clusterType()).map(ClusterType::toConfigValue).orElse(null),
- identityDocument.ztsUrl(),
- identityDocument.serviceIdentity().getFullName());
- try {
- byte[] bytes = mapper.writeValueAsBytes(documentEntity);
- return Base64.getEncoder().encodeToString(bytes);
- } catch (JsonProcessingException e) {
- throw new RuntimeException("Error during serialization of identity document.", e);
- }
- }
}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java
deleted file mode 100644
index 577584db185..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocument.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.identityprovider.api;
-
-import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzService;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Represents an unsigned identity document
- * @author mortent
- */
-public record IdentityDocument(VespaUniqueInstanceId providerUniqueId, AthenzService providerService, String configServerHostname,
- String instanceHostname, Instant createdAt, Set<String> ipAddresses,
- IdentityType identityType, ClusterType clusterType, String ztsUrl,
- AthenzIdentity serviceIdentity, Map<String, Object> unknownAttributes) {
-
- public IdentityDocument {
- ipAddresses = Set.copyOf(ipAddresses);
-
- Map<String, Object> nonNull = new HashMap<>();
- unknownAttributes.forEach((key, value) -> {
- if (value != null) nonNull.put(key, value);
- });
- // Map.copyOf() does not allow null values
- unknownAttributes = Map.copyOf(nonNull);
- }
-
- public IdentityDocument(VespaUniqueInstanceId providerUniqueId, AthenzService providerService, String configServerHostname,
- String instanceHostname, Instant createdAt, Set<String> ipAddresses,
- IdentityType identityType, ClusterType clusterType, String ztsUrl,
- AthenzIdentity serviceIdentity) {
- this(providerUniqueId, providerService, configServerHostname, instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, Map.of());
- }
-
-
- public IdentityDocument withServiceIdentity(AthenzService athenzService) {
- return new IdentityDocument(
- this.providerUniqueId,
- this.providerService,
- this.configServerHostname,
- this.instanceHostname,
- this.createdAt,
- this.ipAddresses,
- this.identityType,
- this.clusterType,
- this.ztsUrl,
- athenzService,
- this.unknownAttributes);
- }
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocumentClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocumentClient.java
index 0e13cba8de9..5a0f77ec765 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocumentClient.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/IdentityDocumentClient.java
@@ -1,14 +1,12 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.athenz.identityprovider.api;
-import java.util.OptionalInt;
-
/**
* A client that communicates that fetches an identity document.
*
* @author bjorncs
*/
public interface IdentityDocumentClient {
- SignedIdentityDocument getNodeIdentityDocument(String host, int documentVersion);
- SignedIdentityDocument getTenantIdentityDocument(String host, int documentVersion);
+ SignedIdentityDocument getNodeIdentityDocument(String host);
+ SignedIdentityDocument getTenantIdentityDocument(String host);
}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/LegacySignedIdentityDocument.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/LegacySignedIdentityDocument.java
deleted file mode 100644
index 220bc72a017..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/LegacySignedIdentityDocument.java
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.identityprovider.api;
-
-public record LegacySignedIdentityDocument(String signature, int signingKeyVersion, int documentVersion,
- IdentityDocument identityDocument) implements SignedIdentityDocument {
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/SignedIdentityDocument.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/SignedIdentityDocument.java
index 4e3bd8dee91..de78d81cd1b 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/SignedIdentityDocument.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/SignedIdentityDocument.java
@@ -1,20 +1,54 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.athenz.identityprovider.api;
+import com.yahoo.vespa.athenz.api.AthenzIdentity;
+import com.yahoo.vespa.athenz.api.AthenzService;
+
+import java.net.URL;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
/**
* A signed identity document.
+ * The {@link #unknownAttributes()} member provides forward compatibility and ensures any new/unknown fields are kept intact when serialized to JSON.
+ *
* @author bjorncs
- * @author mortent
*/
-public interface SignedIdentityDocument {
+public record SignedIdentityDocument(String signature, int signingKeyVersion, VespaUniqueInstanceId providerUniqueId,
+ AthenzService providerService, int documentVersion, String configServerHostname,
+ String instanceHostname, Instant createdAt, Set<String> ipAddresses,
+ IdentityType identityType, ClusterType clusterType, String ztsUrl,
+ AthenzIdentity serviceIdentity, Map<String, Object> unknownAttributes) {
+
+ public SignedIdentityDocument {
+ ipAddresses = Set.copyOf(ipAddresses);
+
+ Map<String, Object> nonNull = new HashMap<>();
+ unknownAttributes.forEach((key, value) -> {
+ if (value != null) nonNull.put(key, value);
+ });
+ // Map.copyOf() does not allow null values
+ unknownAttributes = Map.copyOf(nonNull);
+ }
+
+ public SignedIdentityDocument(String signature, int signingKeyVersion, VespaUniqueInstanceId providerUniqueId,
+ AthenzService providerService, int documentVersion, String configServerHostname,
+ String instanceHostname, Instant createdAt, Set<String> ipAddresses,
+ IdentityType identityType, ClusterType clusterType, String ztsUrl, AthenzIdentity serviceIdentity) {
+ this(signature, signingKeyVersion, providerUniqueId, providerService, documentVersion, configServerHostname,
+ instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, Map.of());
+ }
+
+ public static final int DEFAULT_DOCUMENT_VERSION = 3;
+
+ public boolean outdated() { return documentVersion < DEFAULT_DOCUMENT_VERSION; }
- int LEGACY_DEFAULT_DOCUMENT_VERSION = 3;
- int DEFAULT_DOCUMENT_VERSION = 4;
+ public SignedIdentityDocument withServiceIdentity(AthenzIdentity identity) {
+ return new SignedIdentityDocument(signature, signingKeyVersion, providerUniqueId, providerService, documentVersion, configServerHostname, instanceHostname, createdAt,
+ ipAddresses, identityType, clusterType, ztsUrl, identity);
+ }
- default boolean outdated() { return documentVersion() < LEGACY_DEFAULT_DOCUMENT_VERSION; }
- IdentityDocument identityDocument();
- String signature();
- int signingKeyVersion();
- int documentVersion();
}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/DefaultSignedIdentityDocumentEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/DefaultSignedIdentityDocumentEntity.java
deleted file mode 100644
index 3aaff011415..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/DefaultSignedIdentityDocumentEntity.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.identityprovider.api.bindings;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public record DefaultSignedIdentityDocumentEntity(
- @JsonProperty("signature") String signature,
- @JsonProperty("signing-key-version") int signingKeyVersion,
- @JsonProperty("document-version") int documentVersion,
- @JsonProperty("data") String data)
- implements SignedIdentityDocumentEntity {
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java
deleted file mode 100644
index 946eacc67eb..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/IdentityDocumentEntity.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.identityprovider.api.bindings;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author bjorncs
- * @author mortent
- */
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record IdentityDocumentEntity(String providerUniqueId, String providerService,
- String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses,
- String identityType, String clusterType, String ztsUrl, String serviceIdentity, Map<String, Object> unknownAttributes) {
-
- @JsonCreator
- public IdentityDocumentEntity(@JsonProperty("provider-unique-id") String providerUniqueId,
- @JsonProperty("provider-service") String providerService,
- @JsonProperty("configserver-hostname") String configServerHostname,
- @JsonProperty("instance-hostname") String instanceHostname,
- @JsonProperty("created-at") Instant createdAt,
- @JsonProperty("ip-addresses") Set<String> ipAddresses,
- @JsonProperty("identity-type") String identityType,
- @JsonProperty("cluster-type") String clusterType,
- @JsonProperty("zts-url") String ztsUrl,
- @JsonProperty("service-identity") String serviceIdentity) {
- this(providerUniqueId, providerService, configServerHostname,
- instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, new HashMap<>());
- }
-
- @JsonProperty("provider-unique-id") @Override public String providerUniqueId() { return providerUniqueId; }
- @JsonProperty("provider-service") @Override public String providerService() { return providerService; }
- @JsonProperty("configserver-hostname") @Override public String configServerHostname() { return configServerHostname; }
- @JsonProperty("instance-hostname") @Override public String instanceHostname() { return instanceHostname; }
- @JsonProperty("created-at") @Override public Instant createdAt() { return createdAt; }
- @JsonProperty("ip-addresses") @Override public Set<String> ipAddresses() { return ipAddresses; }
- @JsonProperty("identity-type") @Override public String identityType() { return identityType; }
- @JsonProperty("cluster-type") @Override public String clusterType() { return clusterType; }
- @JsonProperty("zts-url") @Override public String ztsUrl() { return ztsUrl; }
- @JsonProperty("service-identity") @Override public String serviceIdentity() { return serviceIdentity; }
- @JsonAnyGetter @Override public Map<String, Object> unknownAttributes() { return unknownAttributes; }
- @JsonAnySetter public void set(String name, Object value) { unknownAttributes.put(name, value); }
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/LegacySignedIdentityDocumentEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/LegacySignedIdentityDocumentEntity.java
deleted file mode 100644
index e00ab9978f6..00000000000
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/LegacySignedIdentityDocumentEntity.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.athenz.identityprovider.api.bindings;
-
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author bjorncs
- */
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record LegacySignedIdentityDocumentEntity (
- String signature, int signingKeyVersion, String providerUniqueId, String providerService, int documentVersion,
- String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses,
- String identityType, String clusterType, String ztsUrl, String serviceIdentity, Map<String, Object> unknownAttributes) implements SignedIdentityDocumentEntity {
-
- @JsonCreator
- public LegacySignedIdentityDocumentEntity(@JsonProperty("signature") String signature,
- @JsonProperty("signing-key-version") int signingKeyVersion,
- @JsonProperty("provider-unique-id") String providerUniqueId,
- @JsonProperty("provider-service") String providerService,
- @JsonProperty("document-version") int documentVersion,
- @JsonProperty("configserver-hostname") String configServerHostname,
- @JsonProperty("instance-hostname") String instanceHostname,
- @JsonProperty("created-at") Instant createdAt,
- @JsonProperty("ip-addresses") Set<String> ipAddresses,
- @JsonProperty("identity-type") String identityType,
- @JsonProperty("cluster-type") String clusterType,
- @JsonProperty("zts-url") String ztsUrl,
- @JsonProperty("service-identity") String serviceIdentity) {
- this(signature, signingKeyVersion, providerUniqueId, providerService, documentVersion, configServerHostname,
- instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, new HashMap<>());
- }
-
- @JsonProperty("signature") @Override public String signature() { return signature; }
- @JsonProperty("signing-key-version") @Override public int signingKeyVersion() { return signingKeyVersion; }
- @JsonProperty("provider-unique-id") @Override public String providerUniqueId() { return providerUniqueId; }
- @JsonProperty("provider-service") @Override public String providerService() { return providerService; }
- @JsonProperty("document-version") @Override public int documentVersion() { return documentVersion; }
- @JsonProperty("configserver-hostname") @Override public String configServerHostname() { return configServerHostname; }
- @JsonProperty("instance-hostname") @Override public String instanceHostname() { return instanceHostname; }
- @JsonProperty("created-at") @Override public Instant createdAt() { return createdAt; }
- @JsonProperty("ip-addresses") @Override public Set<String> ipAddresses() { return ipAddresses; }
- @JsonProperty("identity-type") @Override public String identityType() { return identityType; }
- @JsonProperty("cluster-type") @Override public String clusterType() { return clusterType; }
- @JsonProperty("zts-url") @Override public String ztsUrl() { return ztsUrl; }
- @JsonProperty("service-identity") @Override public String serviceIdentity() { return serviceIdentity; }
- @JsonAnyGetter @Override public Map<String, Object> unknownAttributes() { return unknownAttributes; }
- @JsonAnySetter public void set(String name, Object value) { unknownAttributes.put(name, value); }
-}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java
index 174c76f7fa9..fc0dff3b97b 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/api/bindings/SignedIdentityDocumentEntity.java
@@ -1,77 +1,57 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.athenz.identityprovider.api.bindings;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.fasterxml.jackson.databind.DatabindContext;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
-import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument;
-
-import java.io.IOException;
-import java.util.Objects;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "document-version", visible = true)
-@JsonTypeIdResolver(SignedIdentityDocumentEntityTypeResolver.class)
-public interface SignedIdentityDocumentEntity {
- int documentVersion();
-}
-
-class SignedIdentityDocumentEntityTypeResolver implements TypeIdResolver {
- JavaType javaType;
-
- @Override
- public void init(JavaType javaType) {
- this.javaType = javaType;
- }
-
- @Override
- public String idFromValue(Object o) {
- return idFromValueAndType(o, o.getClass());
- }
-
- @Override
- public String idFromValueAndType(Object o, Class<?> aClass) {
- if (Objects.isNull(o)) {
- throw new IllegalArgumentException("Cannot serialize null oject");
- } else {
- if (o instanceof SignedIdentityDocumentEntity s) {
- return Integer.toString(s.documentVersion());
- } else {
- throw new IllegalArgumentException("Cannot serialize class: " + o.getClass());
- }
- }
- }
-
- @Override
- public String idFromBaseType() {
- return idFromValueAndType(null, javaType.getRawClass());
- }
-
- @Override
- public JavaType typeFromId(DatabindContext databindContext, String s) throws IOException {
- try {
- int version = Integer.parseInt(s);
- Class<? extends SignedIdentityDocumentEntity> cls = version <= SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION
- ? LegacySignedIdentityDocumentEntity.class
- : DefaultSignedIdentityDocumentEntity.class;
- return TypeFactory.defaultInstance().constructSpecializedType(javaType,cls);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Unable to deserialize document with version: \"%s\"".formatted(s));
- }
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author bjorncs
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public record SignedIdentityDocumentEntity(
+ String signature, int signingKeyVersion, String providerUniqueId, String providerService, int documentVersion,
+ String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses,
+ String identityType, String clusterType, String ztsUrl, String serviceIdentity, Map<String, Object> unknownAttributes) {
+
+ @JsonCreator
+ public SignedIdentityDocumentEntity(@JsonProperty("signature") String signature,
+ @JsonProperty("signing-key-version") int signingKeyVersion,
+ @JsonProperty("provider-unique-id") String providerUniqueId,
+ @JsonProperty("provider-service") String providerService,
+ @JsonProperty("document-version") int documentVersion,
+ @JsonProperty("configserver-hostname") String configServerHostname,
+ @JsonProperty("instance-hostname") String instanceHostname,
+ @JsonProperty("created-at") Instant createdAt,
+ @JsonProperty("ip-addresses") Set<String> ipAddresses,
+ @JsonProperty("identity-type") String identityType,
+ @JsonProperty("cluster-type") String clusterType,
+ @JsonProperty("zts-url") String ztsUrl,
+ @JsonProperty("service-identity") String serviceIdentity) {
+ this(signature, signingKeyVersion, providerUniqueId, providerService, documentVersion, configServerHostname,
+ instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity, new HashMap<>());
}
- @Override
- public String getDescForKnownTypeIds() {
- return "Type resolver for SignedIdentityDocumentEntity";
- }
-
- @Override
- public JsonTypeInfo.Id getMechanism() {
- return JsonTypeInfo.Id.CUSTOM;
- }
-} \ No newline at end of file
+ @JsonProperty("signature") @Override public String signature() { return signature; }
+ @JsonProperty("signing-key-version") @Override public int signingKeyVersion() { return signingKeyVersion; }
+ @JsonProperty("provider-unique-id") @Override public String providerUniqueId() { return providerUniqueId; }
+ @JsonProperty("provider-service") @Override public String providerService() { return providerService; }
+ @JsonProperty("document-version") @Override public int documentVersion() { return documentVersion; }
+ @JsonProperty("configserver-hostname") @Override public String configServerHostname() { return configServerHostname; }
+ @JsonProperty("instance-hostname") @Override public String instanceHostname() { return instanceHostname; }
+ @JsonProperty("created-at") @Override public Instant createdAt() { return createdAt; }
+ @JsonProperty("ip-addresses") @Override public Set<String> ipAddresses() { return ipAddresses; }
+ @JsonProperty("identity-type") @Override public String identityType() { return identityType; }
+ @JsonProperty("cluster-type") @Override public String clusterType() { return clusterType; }
+ @JsonProperty("zts-url") @Override public String ztsUrl() { return ztsUrl; }
+ @JsonProperty("service-identity") @Override public String serviceIdentity() { return serviceIdentity; }
+ @JsonAnyGetter @Override public Map<String, Object> unknownAttributes() { return unknownAttributes; }
+ @JsonAnySetter public void set(String name, Object value) { unknownAttributes.put(name, value); }
+}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java
index 1858653c9b4..cc9d3b2be65 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzCredentialsService.java
@@ -11,7 +11,6 @@ import com.yahoo.vespa.athenz.client.zts.InstanceIdentity;
import com.yahoo.vespa.athenz.client.zts.ZtsClient;
import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider;
import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper;
-import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocumentClient;
import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument;
import com.yahoo.vespa.athenz.tls.AthenzIdentityVerifier;
@@ -75,9 +74,7 @@ class AthenzCredentialsService {
}
KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
IdentityDocumentClient identityDocumentClient = createIdentityDocumentClient();
- // Use legacy version for now.
- SignedIdentityDocument signedDocument = identityDocumentClient.getTenantIdentityDocument(hostname, SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION);
- IdentityDocument document = signedDocument.identityDocument();
+ SignedIdentityDocument document = identityDocumentClient.getTenantIdentityDocument(hostname);
Pkcs10Csr csr = csrGenerator.generateInstanceCsr(
tenantIdentity,
document.providerUniqueId(),
@@ -90,17 +87,16 @@ class AthenzCredentialsService {
ztsClient.registerInstance(
configserverIdentity,
tenantIdentity,
- EntityBindingsMapper.toAttestationData(signedDocument),
+ EntityBindingsMapper.toAttestationData(document),
csr);
X509Certificate certificate = instanceIdentity.certificate();
- writeCredentialsToDisk(keyPair.getPrivate(), certificate, signedDocument);
- return new AthenzCredentials(certificate, keyPair, signedDocument);
+ writeCredentialsToDisk(keyPair.getPrivate(), certificate, document);
+ return new AthenzCredentials(certificate, keyPair, document);
}
}
- AthenzCredentials updateCredentials(SignedIdentityDocument signedDocument, SSLContext sslContext) {
+ AthenzCredentials updateCredentials(SignedIdentityDocument document, SSLContext sslContext) {
KeyPair newKeyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA);
- IdentityDocument document = signedDocument.identityDocument();
Pkcs10Csr csr = csrGenerator.generateInstanceCsr(
tenantIdentity,
document.providerUniqueId(),
@@ -116,8 +112,8 @@ class AthenzCredentialsService {
document.providerUniqueId().asDottedString(),
csr);
X509Certificate certificate = instanceIdentity.certificate();
- writeCredentialsToDisk(newKeyPair.getPrivate(), certificate, signedDocument);
- return new AthenzCredentials(certificate, newKeyPair, signedDocument);
+ writeCredentialsToDisk(newKeyPair.getPrivate(), certificate, document);
+ return new AthenzCredentials(certificate, newKeyPair, document);
}
}
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
index b5579cbfcd8..b9f9f3862c2 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
@@ -298,7 +298,7 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen
}
private X509Certificate requestRoleCertificate(AthenzRole role) {
- var doc = credentials.getIdentityDocument().identityDocument();
+ var doc = credentials.getIdentityDocument();
Pkcs10Csr csr = csrGenerator.generateRoleCsr(
identity, role, doc.providerUniqueId(), doc.clusterType(), credentials.getKeyPair());
try (ZtsClient client = createZtsClient()) {
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/DefaultIdentityDocumentClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/DefaultIdentityDocumentClient.java
index 48fc021dced..5b884e3dfb3 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/DefaultIdentityDocumentClient.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/DefaultIdentityDocumentClient.java
@@ -56,16 +56,16 @@ public class DefaultIdentityDocumentClient implements IdentityDocumentClient {
}
@Override
- public SignedIdentityDocument getNodeIdentityDocument(String host, int documentVersion) {
- return getIdentityDocument(host, "node", documentVersion);
+ public SignedIdentityDocument getNodeIdentityDocument(String host) {
+ return getIdentityDocument(host, "node");
}
@Override
- public SignedIdentityDocument getTenantIdentityDocument(String host, int documentVersion) {
- return getIdentityDocument(host, "tenant", documentVersion);
+ public SignedIdentityDocument getTenantIdentityDocument(String host) {
+ return getIdentityDocument(host, "tenant");
}
- private SignedIdentityDocument getIdentityDocument(String host, String type, int documentVersion) {
+ private SignedIdentityDocument getIdentityDocument(String host, String type) {
try (CloseableHttpClient client = createHttpClient(sslContextSupplier.get(), hostnameVerifier)) {
URI uri = configserverUri
@@ -76,7 +76,6 @@ public class DefaultIdentityDocumentClient implements IdentityDocumentClient {
.setUri(uri)
.addHeader("Connection", "close")
.addHeader("Accept", "application/json")
- .addParameter("documentVersion", Integer.toString(documentVersion))
.build();
try (CloseableHttpResponse response = client.execute(request)) {
String responseContent = EntityUtils.toString(response.getEntity());
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSigner.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSigner.java
index 11b30585933..019f73fc6bf 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSigner.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSigner.java
@@ -4,10 +4,7 @@ package com.yahoo.vespa.athenz.identityprovider.client;
import com.yahoo.security.SignatureUtils;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzService;
-import com.yahoo.vespa.athenz.identityprovider.api.DefaultSignedIdentityDocument;
-import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.IdentityType;
-import com.yahoo.vespa.athenz.identityprovider.api.LegacySignedIdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId;
@@ -22,7 +19,7 @@ import java.util.Base64;
import java.util.Set;
import java.util.TreeSet;
-import static com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION;
+import static com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
@@ -32,25 +29,8 @@ import static java.nio.charset.StandardCharsets.UTF_8;
*/
public class IdentityDocumentSigner {
- public String generateSignature(String identityDocumentData, PrivateKey privateKey) {
- try {
- Signature signer = SignatureUtils.createSigner(privateKey);
- signer.initSign(privateKey);
- signer.update(identityDocumentData.getBytes(UTF_8));
- byte[] signature = signer.sign();
- return Base64.getEncoder().encodeToString(signature);
- } catch (GeneralSecurityException e) {
- throw new RuntimeException(e);
- }
- }
-
- public String generateLegacySignature(IdentityDocument doc, PrivateKey privateKey) {
- return generateSignature(doc.providerUniqueId(), doc.providerService(), doc.configServerHostname(),
- doc.instanceHostname(), doc.createdAt(), doc.ipAddresses(), doc.identityType(), privateKey, doc.serviceIdentity());
- }
-
// Cluster type is ignored due to old Vespa versions not forwarding unknown fields in signed identity document
- private String generateSignature(VespaUniqueInstanceId providerUniqueId,
+ public String generateSignature(VespaUniqueInstanceId providerUniqueId,
AthenzService providerService,
String configServerHostname,
String instanceHostname,
@@ -74,32 +54,14 @@ public class IdentityDocumentSigner {
}
public boolean hasValidSignature(SignedIdentityDocument doc, PublicKey publicKey) {
- if (doc instanceof LegacySignedIdentityDocument signedDoc) {
- return validateLegacySignature(signedDoc, publicKey);
- } else if (doc instanceof DefaultSignedIdentityDocument signedDoc) {
- try {
- Signature signer = SignatureUtils.createVerifier(publicKey);
- signer.initVerify(publicKey);
- signer.update(signedDoc.data().getBytes(UTF_8));
- return signer.verify(Base64.getDecoder().decode(doc.signature()));
- } catch (GeneralSecurityException e) {
- throw new RuntimeException(e);
- }
- } else {
- throw new IllegalArgumentException("Unknown identity document type: " + doc.getClass().getName());
- }
- }
-
- private boolean validateLegacySignature(SignedIdentityDocument doc, PublicKey publicKey) {
try {
- IdentityDocument iddoc = doc.identityDocument();
Signature signer = SignatureUtils.createVerifier(publicKey);
signer.initVerify(publicKey);
writeToSigner(
- signer, iddoc.providerUniqueId(), iddoc.providerService(), iddoc.configServerHostname(),
- iddoc.instanceHostname(), iddoc.createdAt(), iddoc.ipAddresses(), iddoc.identityType());
- if (doc.documentVersion() >= LEGACY_DEFAULT_DOCUMENT_VERSION) {
- writeToSigner(signer, iddoc.serviceIdentity());
+ signer, doc.providerUniqueId(), doc.providerService(), doc.configServerHostname(),
+ doc.instanceHostname(), doc.createdAt(), doc.ipAddresses(), doc.identityType());
+ if (doc.documentVersion() >= DEFAULT_DOCUMENT_VERSION) {
+ writeToSigner(signer, doc.serviceIdentity());
}
return signer.verify(Base64.getDecoder().decode(doc.signature()));
} catch (GeneralSecurityException e) {
diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java
index 513fb4cdbd3..2a68f6fd231 100644
--- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java
+++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/api/EntityBindingsMapperTest.java
@@ -5,11 +5,8 @@ package com.yahoo.vespa.athenz.identityprovider.api;
import org.junit.jupiter.api.Test;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
@@ -18,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
class EntityBindingsMapperTest {
@Test
- public void legacy_persists_unknown_json_members() throws IOException {
+ public void persists_unknown_json_members() throws IOException {
var originalJson =
"""
{
@@ -39,8 +36,7 @@ class EntityBindingsMapperTest {
}
""";
var entity = EntityBindingsMapper.fromString(originalJson);
- assertInstanceOf(LegacySignedIdentityDocument.class, entity);
- assertEquals(2, entity.identityDocument().unknownAttributes().size(), entity.identityDocument().unknownAttributes().toString());
+ assertEquals(2, entity.unknownAttributes().size(), entity.unknownAttributes().toString());
var json = EntityBindingsMapper.toAttestationData(entity);
var expectedMemberInJson = "member-in-unknown-object";
@@ -49,39 +45,4 @@ class EntityBindingsMapperTest {
assertEquals(EntityBindingsMapper.mapper.readTree(originalJson), EntityBindingsMapper.mapper.readTree(json));
}
- @Test
- public void reads_unknown_json_members() throws IOException {
- var iddoc = """
- {
- "provider-unique-id": "0.cluster.instance.app.tenant.us-west-1.test.node",
- "provider-service": "domain.service",
- "configserver-hostname": "cfg",
- "instance-hostname": "host",
- "created-at": 12345.0,
- "ip-addresses": [],
- "identity-type": "node",
- "cluster-type": "admin",
- "zts-url": "https://zts.url/",
- "unknown-string": "string-value",
- "unknown-object": { "member-in-unknown-object": 123 }
- }
- """;
- var originalJson =
- """
- {
- "signature": "sig",
- "signing-key-version": 0,
- "document-version": 4,
- "data": "%s"
- }
- """.formatted(Base64.getEncoder().encodeToString(iddoc.getBytes(StandardCharsets.UTF_8)));
- var entity = EntityBindingsMapper.fromString(originalJson);
- assertEquals(2, entity.identityDocument().unknownAttributes().size(), entity.identityDocument().unknownAttributes().toString());
- var json = EntityBindingsMapper.toAttestationData(entity);
-
- // For the new iddoc format the identity document should be unchanged during serialization/deserialization,
- // i.e the signed identity document should be unchanged
- assertEquals(EntityBindingsMapper.mapper.readTree(originalJson), EntityBindingsMapper.mapper.readTree(json));
- }
-
} \ No newline at end of file
diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java
index acb0905700f..ff85cb79f02 100644
--- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java
+++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/IdentityDocumentSignerTest.java
@@ -6,13 +6,10 @@ import com.yahoo.security.KeyUtils;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.identityprovider.api.ClusterType;
-import com.yahoo.vespa.athenz.identityprovider.api.DefaultSignedIdentityDocument;
-import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper;
-import com.yahoo.vespa.athenz.identityprovider.api.IdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.IdentityType;
-import com.yahoo.vespa.athenz.identityprovider.api.LegacySignedIdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument;
import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId;
+import com.yahoo.vespa.athenz.utils.AthenzIdentities;
import org.junit.jupiter.api.Test;
import java.security.KeyPair;
@@ -21,7 +18,6 @@ import java.util.Arrays;
import java.util.HashSet;
import static com.yahoo.vespa.athenz.identityprovider.api.IdentityType.TENANT;
-import static com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument.LEGACY_DEFAULT_DOCUMENT_VERSION;
import static com.yahoo.vespa.athenz.identityprovider.api.SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -46,53 +42,32 @@ public class IdentityDocumentSignerTest {
private static final AthenzIdentity serviceIdentity = new AthenzService("vespa", "node");
@Test
- void legacy_generates_and_validates_signature() {
- IdentityDocumentSigner signer = new IdentityDocumentSigner();
- IdentityDocument identityDocument = new IdentityDocument(
- id, providerService, configserverHostname,
- instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
- String signature =
- signer.generateLegacySignature(identityDocument, keyPair.getPrivate());
-
- SignedIdentityDocument signedIdentityDocument = new LegacySignedIdentityDocument(
- signature, KEY_VERSION, LEGACY_DEFAULT_DOCUMENT_VERSION, identityDocument);
-
- assertTrue(signer.hasValidSignature(signedIdentityDocument, keyPair.getPublic()));
- }
-
- @Test
void generates_and_validates_signature() {
IdentityDocumentSigner signer = new IdentityDocumentSigner();
- IdentityDocument identityDocument = new IdentityDocument(
- id, providerService, configserverHostname,
- instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
- String data = EntityBindingsMapper.toIdentityDocmentData(identityDocument);
String signature =
- signer.generateSignature(data, keyPair.getPrivate());
+ signer.generateSignature(id, providerService, configserverHostname, instanceHostname, createdAt,
+ ipAddresses, identityType, keyPair.getPrivate(), serviceIdentity);
- SignedIdentityDocument signedIdentityDocument = new DefaultSignedIdentityDocument(
- signature, KEY_VERSION, DEFAULT_DOCUMENT_VERSION, data);
+ SignedIdentityDocument signedIdentityDocument = new SignedIdentityDocument(
+ signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname,
+ instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
assertTrue(signer.hasValidSignature(signedIdentityDocument, keyPair.getPublic()));
}
@Test
- void legacy_ignores_cluster_type_and_zts_url() {
+ void ignores_cluster_type_and_zts_url() {
IdentityDocumentSigner signer = new IdentityDocumentSigner();
- IdentityDocument identityDocument = new IdentityDocument(
- id, providerService, configserverHostname,
- instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
- IdentityDocument withoutIgnoredFields = new IdentityDocument(
- id, providerService, configserverHostname,
- instanceHostname, createdAt, ipAddresses, identityType, null, null, serviceIdentity);
-
String signature =
- signer.generateLegacySignature(identityDocument, keyPair.getPrivate());
+ signer.generateSignature(id, providerService, configserverHostname, instanceHostname, createdAt,
+ ipAddresses, identityType, keyPair.getPrivate(), serviceIdentity);
- var docWithoutIgnoredFields = new LegacySignedIdentityDocument(
- signature, KEY_VERSION, LEGACY_DEFAULT_DOCUMENT_VERSION, withoutIgnoredFields);
- var docWithIgnoredFields = new LegacySignedIdentityDocument(
- signature, KEY_VERSION, LEGACY_DEFAULT_DOCUMENT_VERSION, identityDocument);
+ var docWithoutIgnoredFields = new SignedIdentityDocument(
+ signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname,
+ instanceHostname, createdAt, ipAddresses, identityType, null, null, serviceIdentity);
+ var docWithIgnoredFields = new SignedIdentityDocument(
+ signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname,
+ instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
assertTrue(signer.hasValidSignature(docWithoutIgnoredFields, keyPair.getPublic()));
assertEquals(docWithIgnoredFields.signature(), docWithoutIgnoredFields.signature());
@@ -101,15 +76,16 @@ public class IdentityDocumentSignerTest {
@Test
void validates_signature_for_new_and_old_versions() {
IdentityDocumentSigner signer = new IdentityDocumentSigner();
- IdentityDocument identityDocument = new IdentityDocument(
- id, providerService, configserverHostname,
- instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
String signature =
- signer.generateLegacySignature(identityDocument, keyPair.getPrivate());
+ signer.generateSignature(id, providerService, configserverHostname, instanceHostname, createdAt,
+ ipAddresses, identityType, keyPair.getPrivate(), serviceIdentity);
- SignedIdentityDocument signedIdentityDocument = new LegacySignedIdentityDocument(
- signature, KEY_VERSION, LEGACY_DEFAULT_DOCUMENT_VERSION, identityDocument);
+ SignedIdentityDocument signedIdentityDocument = new SignedIdentityDocument(
+ signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname,
+ instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, serviceIdentity);
assertTrue(signer.hasValidSignature(signedIdentityDocument, keyPair.getPublic()));
+
}
+
} \ No newline at end of file
diff --git a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
index 0d007097fa2..1c2db273653 100644
--- a/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
+++ b/vespa-dependencies-enforcer/allowed-maven-dependencies.txt
@@ -154,20 +154,20 @@ org.codehaus.plexus:plexus-sec-dispatcher:2.0
org.codehaus.plexus:plexus-utils:3.3.1
org.eclipse.collections:eclipse-collections:11.0.0
org.eclipse.collections:eclipse-collections-api:11.0.0
-org.eclipse.jetty:jetty-alpn-client:11.0.14
-org.eclipse.jetty:jetty-alpn-java-server:11.0.14
-org.eclipse.jetty:jetty-alpn-server:11.0.14
-org.eclipse.jetty:jetty-client:11.0.14
-org.eclipse.jetty:jetty-http:11.0.14
-org.eclipse.jetty:jetty-io:11.0.14
-org.eclipse.jetty:jetty-jmx:11.0.14
-org.eclipse.jetty:jetty-security:11.0.14
-org.eclipse.jetty:jetty-server:11.0.14
-org.eclipse.jetty:jetty-servlet:11.0.14
-org.eclipse.jetty:jetty-util:11.0.14
-org.eclipse.jetty.http2:http2-common:11.0.14
-org.eclipse.jetty.http2:http2-hpack:11.0.14
-org.eclipse.jetty.http2:http2-server:11.0.14
+org.eclipse.jetty:jetty-alpn-client:11.0.15
+org.eclipse.jetty:jetty-alpn-java-server:11.0.15
+org.eclipse.jetty:jetty-alpn-server:11.0.15
+org.eclipse.jetty:jetty-client:11.0.15
+org.eclipse.jetty:jetty-http:11.0.15
+org.eclipse.jetty:jetty-io:11.0.15
+org.eclipse.jetty:jetty-jmx:11.0.15
+org.eclipse.jetty:jetty-security:11.0.15
+org.eclipse.jetty:jetty-server:11.0.15
+org.eclipse.jetty:jetty-servlet:11.0.15
+org.eclipse.jetty:jetty-util:11.0.15
+org.eclipse.jetty.http2:http2-common:11.0.15
+org.eclipse.jetty.http2:http2-hpack:11.0.15
+org.eclipse.jetty.http2:http2-server:11.0.15
org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2
org.eclipse.sisu:org.eclipse.sisu.inject:0.3.5
org.eclipse.sisu:org.eclipse.sisu.plexus:0.3.5