diff options
author | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2023-02-03 12:22:44 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2023-02-03 12:23:24 +0100 |
commit | 90892ba4d2a302b1a262fdd1198fac8c6724e44f (patch) | |
tree | 0eaa5c41368af736cd3bdb0a36f4b74f4370b886 | |
parent | e09b191faf77bb95b923bb709b2181a0a3ee2c81 (diff) |
Add SAN URI with cluster type in instance certificates
12 files changed, 69 insertions, 24 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityDocumentGenerator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityDocumentGenerator.java index 5042c8cf617..258cd3fc091 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityDocumentGenerator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityDocumentGenerator.java @@ -65,7 +65,7 @@ public class IdentityDocumentGenerator { String configServerHostname = HostName.getLocalhost(); Instant createdAt = Instant.now(); - var clusterType = allocation.membership().cluster().type().name(); + var clusterType = allocation.membership().cluster().type(); String signature = signer.generateSignature( providerUniqueId, providerService, configServerHostname, node.hostname(), createdAt, ips, identityType, clusterType, privateKey); diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidator.java index 82f486f1bc0..b316d9fb0b4 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidator.java @@ -176,9 +176,9 @@ public class InstanceValidator { log.log(Level.WARNING, "Invalid SAN URIs: " + urisCommaSeparated); return false; } - var clusterType = node.allocation().map(a -> a.membership().cluster().type().name()).orElse(null); + var clusterType = node.allocation().map(a -> a.membership().cluster().type()).orElse(null); Set<URI> allowedUris = clusterType != null - ? Set.of(URI.create("vespa://cluster-type/%s".formatted(clusterType))) : Set.of(); + ? Set.of(URI.create("vespa://cluster-type/%s".formatted(clusterType.name()))) : Set.of(); if (!allowedUris.containsAll(requestedUris)) { log.log(Level.WARNING, "Illegal SAN URIs: expected '%s' found '%s'".formatted(allowedUris, requestedUris)); return false; diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java index 2e143bc53cc..800636943d9 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.ca.restapi; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.security.Pkcs10CsrUtils; import com.yahoo.security.X509CertificateUtils; import com.yahoo.slime.ArrayTraverser; @@ -98,7 +99,7 @@ public class InstanceSerializer { requireField(IDD_IPADDRESSES_FIELD, root).traverse((ArrayTraverser) (__, entry) -> ips.add(entry.asString())); IdentityType identityType = IdentityType.fromId(requireField(IDD_IDENTITY_TYPE_FIELD, root).asString()); var clusterTypeField = root.field(IDD_CLUSTER_TYPE_FIELD); - var clusterType = root.valid() ? clusterTypeField.asString() : null; + var clusterType = clusterTypeField.valid() ? ClusterSpec.Type.from(clusterTypeField.asString()) : null; return new SignedIdentityDocument(signature, (int)signingKeyVersion, providerUniqueId, athenzService, (int)documentVersion, diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidatorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidatorTest.java index 2014b74a3e6..fbaa57d9694 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidatorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidatorTest.java @@ -10,6 +10,7 @@ import com.yahoo.config.model.api.SuperModel; import com.yahoo.config.model.api.SuperModelProvider; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterMembership; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.NodeType; import com.yahoo.vespa.athenz.api.AthenzService; @@ -59,6 +60,7 @@ public class InstanceValidatorTest { private final String service = "service"; private final AthenzService vespaTenantDomain = new AthenzService("vespa.vespa.tenant"); + private final AutoGeneratedKeyProvider keyProvider = new AutoGeneratedKeyProvider(); @Test void application_does_not_exist() { @@ -133,6 +135,17 @@ public class InstanceValidatorTest { } @Test + void rejects_invalid_cluster_type_in_csr() { + var props = Map.of(SERVICE_PROPERTIES_DOMAIN_KEY, domain, SERVICE_PROPERTIES_SERVICE_KEY, service); + var info = new ServiceInfo("serviceName", "type", List.of(), props, "confId", "hostName"); + var provider = mockSuperModelProvider(mockApplicationInfo(applicationId, 5, List.of(info))); + var instanceValidator = new InstanceValidator(keyProvider, provider, mockNodeRepo(), new IdentityDocumentSigner(), vespaTenantDomain); + var instanceConfirmation = createRegisterInstanceConfirmation(applicationId, domain, service); + instanceConfirmation.set("sanURI", "vespa://cluster-type/content"); + assertFalse(instanceValidator.isValidInstance(instanceConfirmation)); + } + + @Test void accepts_valid_refresh_requests() { NodeRepository nodeRepository = mock(NodeRepository.class); Nodes nodes = mock(Nodes.class); @@ -188,8 +201,6 @@ public class InstanceValidatorTest { NodeRepository nodeRepository = mock(NodeRepository.class); Nodes nodes = mock(Nodes.class); when(nodeRepository.nodes()).thenReturn(nodes); - InstanceValidator instanceValidator = new InstanceValidator(null, null, nodeRepository, new IdentityDocumentSigner(), vespaTenantDomain); - List<Node> nodeList = createNodes(10); Node node = nodeList.get(0); nodeList = allocateNode(nodeList, node, applicationId); @@ -197,11 +208,19 @@ public class InstanceValidatorTest { return nodeRepository; } - private InstanceConfirmation createRegisterInstanceConfirmation(ApplicationId applicationId, String domain, String service) { + private InstanceConfirmation createRegisterInstanceConfirmation( + ApplicationId applicationId, String domain, String service) { VespaUniqueInstanceId vespaUniqueInstanceId = new VespaUniqueInstanceId(0, "default", applicationId.instance().value(), applicationId.application().value(), applicationId.tenant().value(), "us-north-1", "dev", IdentityType.NODE); + var domainService = new AthenzService(domain, service); + var clock = Instant.now(); + var clusterType = ClusterSpec.Type.container; + var signature = new IdentityDocumentSigner() + .generateSignature( + vespaUniqueInstanceId, domainService, "localhost", "localhost", clock, Set.of(), + IdentityType.NODE, clusterType, keyProvider.getPrivateKey(0)); SignedIdentityDocument signedIdentityDocument = new SignedIdentityDocument( - null, 0, vespaUniqueInstanceId, new AthenzService(domain, service), 0, "localhost", "localhost", - Instant.now(), Collections.emptySet(), IdentityType.NODE, "container"); + signature, 0, vespaUniqueInstanceId, domainService, 0, "localhost", "localhost", + clock, Collections.emptySet(), IdentityType.NODE, clusterType); return createInstanceConfirmation(vespaUniqueInstanceId, domain, service, signedIdentityDocument); } @@ -221,6 +240,7 @@ public class InstanceValidatorTest { .map(EntityBindingsMapper::toSignedIdentityDocumentEntity) .orElse(null)); instanceConfirmation.set("sanDNS", vespaUniqueInstanceId.asDottedString() + ".instanceid.athenz.dev-us-north-1.vespa.yahoo.cloud"); + instanceConfirmation.set("sanURI", "vespa://cluster-type/container"); return instanceConfirmation; } diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java index 4e977324298..fbd98a70b74 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.ca.restapi; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.security.Pkcs10CsrUtils; import com.yahoo.security.X509CertificateUtils; import com.yahoo.slime.Slime; @@ -47,7 +48,7 @@ public class InstanceSerializerTest { Instant.now().truncatedTo(ChronoUnit.MICROS), // Truncate to the precision given from EntityBindingsMapper.toAttestationData() Collections.emptySet(), IdentityType.NODE, - "container"); + ClusterSpec.Type.container); var json = String.format("{\n" + " \"provider\": \"provider_prod_us-north-1\",\n" + diff --git a/vespa-athenz/pom.xml b/vespa-athenz/pom.xml index 29a4058e180..d7a9b55d05f 100644 --- a/vespa-athenz/pom.xml +++ b/vespa-athenz/pom.xml @@ -92,6 +92,12 @@ <artifactId>guava</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>config-provisioning</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> <!-- test --> <dependency> 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 0949192b884..ddec80cda9d 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 @@ -4,6 +4,7 @@ package com.yahoo.vespa.athenz.identityprovider.api; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.identityprovider.api.bindings.SignedIdentityDocumentEntity; @@ -14,6 +15,7 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.util.Optional; import static com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId.fromDottedString; @@ -48,7 +50,7 @@ public class EntityBindingsMapper { entity.createdAt(), entity.ipAddresses(), IdentityType.fromId(entity.identityType()), - entity.clusterType()); + ClusterSpec.Type.from(entity.clusterType())); } public static SignedIdentityDocumentEntity toSignedIdentityDocumentEntity(SignedIdentityDocument model) { @@ -63,7 +65,7 @@ public class EntityBindingsMapper { model.createdAt(), model.ipAddresses(), model.identityType().id(), - model.clusterType()); + Optional.ofNullable(model.clusterType()).map(ClusterSpec.Type::name).orElse(null)); } public static SignedIdentityDocument readSignedIdentityDocumentFromFile(Path file) { 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 c2d8ece84a5..0fe09f47d80 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,6 +1,7 @@ // 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.config.provision.ClusterSpec; import com.yahoo.vespa.athenz.api.AthenzService; import java.time.Instant; @@ -14,7 +15,7 @@ import java.util.Set; public record SignedIdentityDocument(String signature, int signingKeyVersion, VespaUniqueInstanceId providerUniqueId, AthenzService providerService, int documentVersion, String configServerHostname, String instanceHostname, Instant createdAt, Set<String> ipAddresses, - IdentityType identityType, String clusterType) { + IdentityType identityType, ClusterSpec.Type clusterType) { public static final int DEFAULT_DOCUMENT_VERSION = 2; } diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java index bafeab805bd..8deecb9d549 100644 --- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java +++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/CsrGenerator.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.athenz.identityprovider.client; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.security.Pkcs10Csr; import com.yahoo.security.Pkcs10CsrBuilder; import com.yahoo.security.SubjectAlternativeName; @@ -36,7 +37,7 @@ public class CsrGenerator { public Pkcs10Csr generateInstanceCsr(AthenzIdentity instanceIdentity, VespaUniqueInstanceId instanceId, Set<String> ipAddresses, - String clusterType, + ClusterSpec.Type clusterType, KeyPair keyPair) { X500Principal subject = new X500Principal(String.format("OU=%s, CN=%s", providerService, instanceIdentity.getFullName())); // Add SAN dnsname <service>.<domain-with-dashes>.<provider-dnsname-suffix> @@ -50,7 +51,7 @@ public class CsrGenerator { instanceIdentity.getDomainName().replace(".", "-"), dnsSuffix)) .addSubjectAlternativeName(DNS, getIdentitySAN(instanceId)); - if (clusterType != null) pkcs10CsrBuilder.addSubjectAlternativeName(URI, "vespa://cluster-type/%s".formatted(clusterType)); + if (clusterType != null) pkcs10CsrBuilder.addSubjectAlternativeName(URI, "vespa://cluster-type/%s".formatted(clusterType.name())); ipAddresses.forEach(ip -> pkcs10CsrBuilder.addSubjectAlternativeName(new SubjectAlternativeName(IP, ip))); return pkcs10CsrBuilder.build(); } @@ -58,13 +59,13 @@ public class CsrGenerator { public Pkcs10Csr generateRoleCsr(AthenzIdentity identity, AthenzRole role, VespaUniqueInstanceId instanceId, - String clusterType, + ClusterSpec.Type clusterType, KeyPair keyPair) { X500Principal principal = new X500Principal(String.format("OU=%s, cn=%s:role.%s", providerService, role.domain().getName(), role.roleName())); var b = Pkcs10CsrBuilder.fromKeypair(principal, keyPair, SHA256_WITH_RSA) .addSubjectAlternativeName(DNS, getIdentitySAN(instanceId)) .addSubjectAlternativeName(EMAIL, String.format("%s.%s@%s", identity.getDomainName(), identity.getName(), dnsSuffix)); - if (clusterType != null) b.addSubjectAlternativeName(URI, "vespa://cluster-type/%s".formatted(clusterType)); + if (clusterType != null) b.addSubjectAlternativeName(URI, "vespa://cluster-type/%s".formatted(clusterType.name())); return b.build(); } 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 13bea80dfed..6aa22263a7e 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 @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.athenz.identityprovider.client; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.security.SignatureUtils; import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.identityprovider.api.IdentityType; @@ -34,7 +35,7 @@ public class IdentityDocumentSigner { Instant createdAt, Set<String> ipAddresses, IdentityType identityType, - String clusterType, + ClusterSpec.Type clusterType, PrivateKey privateKey) { try { Signature signer = SignatureUtils.createSigner(privateKey); @@ -70,7 +71,7 @@ public class IdentityDocumentSigner { Instant createdAt, Set<String> ipAddresses, IdentityType identityType, - String clusterType) throws SignatureException { + ClusterSpec.Type clusterType) throws SignatureException { signer.update(providerUniqueId.asDottedString().getBytes(UTF_8)); signer.update(providerService.getFullName().getBytes(UTF_8)); signer.update(configServerHostname.getBytes(UTF_8)); @@ -82,6 +83,6 @@ public class IdentityDocumentSigner { signer.update(ipAddress.getBytes(UTF_8)); } signer.update(identityType.id().getBytes(UTF_8)); - if (clusterType != null) signer.update(clusterType.getBytes(UTF_8)); + if (clusterType != null) signer.update(clusterType.name().getBytes(UTF_8)); } } 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 ede006539a1..55d134fd7cb 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 @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.athenz.identityprovider.client; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.security.KeyAlgorithm; import com.yahoo.security.KeyUtils; import com.yahoo.vespa.athenz.api.AthenzService; @@ -36,7 +37,7 @@ public class IdentityDocumentSignerTest { String instanceHostname = "instancehostname"; Instant createdAt = Instant.EPOCH; HashSet<String> ipAddresses = new HashSet<>(Arrays.asList("1.2.3.4", "::1")); - String clusterType = "container"; + var clusterType = ClusterSpec.Type.container; String signature = signer.generateSignature(id, providerService, configserverHostname, instanceHostname, createdAt, ipAddresses, identityType, clusterType, keyPair.getPrivate()); diff --git a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java index aa4c3e68094..09fefdff0bd 100644 --- a/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java +++ b/vespa-athenz/src/test/java/com/yahoo/vespa/athenz/identityprovider/client/InstanceCsrGeneratorTest.java @@ -1,17 +1,22 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.athenz.identityprovider.client; +import com.yahoo.config.provision.ClusterSpec; import com.yahoo.security.KeyAlgorithm; import com.yahoo.security.KeyUtils; +import com.yahoo.security.Pkcs10Csr; +import com.yahoo.security.SubjectAlternativeName; import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; -import com.yahoo.security.Pkcs10Csr; import org.junit.jupiter.api.Test; import javax.security.auth.x500.X500Principal; import java.security.KeyPair; import java.util.Collections; +import java.util.Set; +import static com.yahoo.security.SubjectAlternativeName.Type.DNS; +import static com.yahoo.security.SubjectAlternativeName.Type.URI; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -24,14 +29,20 @@ public class InstanceCsrGeneratorTest { private static final String ATHENZ_SERVICE = "foo.bar"; @Test - void it_generates_csr_with_correct_subject() { + void generates_correct_subject_and_alternative_names() { CsrGenerator csrGenerator = new CsrGenerator(DNS_SUFFIX, PROVIDER_SERVICE); AthenzService service = new AthenzService(ATHENZ_SERVICE); VespaUniqueInstanceId vespaUniqueInstanceId = VespaUniqueInstanceId.fromDottedString("0.default.default.foo-app.vespa.us-north-1.prod.node"); KeyPair keyPair = KeyUtils.generateKeypair(KeyAlgorithm.RSA); - Pkcs10Csr csr = csrGenerator.generateInstanceCsr(service, vespaUniqueInstanceId, Collections.emptySet(), "container", keyPair); + Pkcs10Csr csr = csrGenerator.generateInstanceCsr(service, vespaUniqueInstanceId, Collections.emptySet(), ClusterSpec.Type.container, keyPair); assertEquals(new X500Principal(String.format("OU=%s, CN=%s", PROVIDER_SERVICE, ATHENZ_SERVICE)), csr.getSubject()); + var actualSans = Set.copyOf(csr.getSubjectAlternativeNames()); + var expectedSans = Set.of( + new SubjectAlternativeName(DNS, "bar.foo.prod-us-north-1.vespa.yahoo.cloud"), + new SubjectAlternativeName(DNS, "0.default.default.foo-app.vespa.us-north-1.prod.node.instanceid.athenz.prod-us-north-1.vespa.yahoo.cloud"), + new SubjectAlternativeName(URI, "vespa://cluster-type/container")); + assertEquals(expectedSans, actualSans); } } |