diff options
author | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2023-02-02 16:11:08 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2023-02-03 12:23:24 +0100 |
commit | e09b191faf77bb95b923bb709b2181a0a3ee2c81 (patch) | |
tree | 42d28de543d81ca48bd0b2c4da53fe89f34d405f /athenz-identity-provider-service | |
parent | 3981141b25ee115f18529e74dacf21e1bf653fed (diff) |
Add cluster type as SAN URI in Athenz instance certificates for Vespa
Diffstat (limited to 'athenz-identity-provider-service')
5 files changed, 36 insertions, 25 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 5b1a909e109..5042c8cf617 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,21 +65,14 @@ public class IdentityDocumentGenerator { String configServerHostname = HostName.getLocalhost(); Instant createdAt = Instant.now(); + var clusterType = allocation.membership().cluster().type().name(); String signature = signer.generateSignature( providerUniqueId, providerService, configServerHostname, - node.hostname(), createdAt, ips, identityType, privateKey); - + node.hostname(), createdAt, ips, identityType, clusterType, privateKey); return new SignedIdentityDocument( - signature, - athenzProviderServiceConfig.secretVersion(), - providerUniqueId, - providerService, - SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION, - configServerHostname, - node.hostname(), - createdAt, - ips, - identityType); + signature, athenzProviderServiceConfig.secretVersion(), providerUniqueId, providerService, + SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION, configServerHostname, node.hostname(), + createdAt, ips, identityType, clusterType); } catch (Exception e) { throw new RuntimeException("Exception generating identity document: " + e.getMessage(), e); } 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 6b7a4835aee..82f486f1bc0 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 @@ -17,14 +17,16 @@ import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; import java.net.InetAddress; +import java.net.URI; import java.security.PublicKey; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Stream; +import java.util.stream.Collectors; /** * Verifies that the instance's identity document is valid @@ -41,6 +43,7 @@ public class InstanceValidator { public static final String SAN_IPS_ATTRNAME = "sanIP"; public static final String SAN_DNS_ATTRNAME = "sanDNS"; + public static final String SAN_URI_ATTRNAME = "sanURI"; private final AthenzService tenantDockerContainerIdentity; private final IdentityDocumentSigner signer; @@ -163,6 +166,23 @@ public class InstanceValidator { log.log(Level.WARNING, "Invalid InstanceConfirmation, wrong ip in : " + vespaUniqueInstanceId); return false; } + + var urisCommaSeparated = confirmation.attributes.get(SAN_URI_ATTRNAME); + Set<URI> requestedUris; + try { + requestedUris = Optional.ofNullable(urisCommaSeparated).stream() + .flatMap(s -> Arrays.stream(s.split(","))).map(URI::create).collect(Collectors.toSet()); + } catch (IllegalArgumentException e) { + log.log(Level.WARNING, "Invalid SAN URIs: " + urisCommaSeparated); + return false; + } + var clusterType = node.allocation().map(a -> a.membership().cluster().type().name()).orElse(null); + Set<URI> allowedUris = clusterType != null + ? Set.of(URI.create("vespa://cluster-type/%s".formatted(clusterType))) : Set.of(); + if (!allowedUris.containsAll(requestedUris)) { + log.log(Level.WARNING, "Illegal SAN URIs: expected '%s' found '%s'".formatted(allowedUris, requestedUris)); + return false; + } return true; } 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 83a7b850365..2e143bc53cc 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 @@ -47,6 +47,7 @@ public class InstanceSerializer { private static final String IDD_CREATED_AT_FIELD = "created-at"; private static final String IDD_IPADDRESSES_FIELD = "ip-addresses"; private static final String IDD_IDENTITY_TYPE_FIELD = "identity-type"; + private static final String IDD_CLUSTER_TYPE_FIELD = "cluster-type"; private static final ObjectMapper objectMapper = new ObjectMapper(); static { @@ -96,9 +97,12 @@ public class InstanceSerializer { Set<String> ips = new HashSet<>(); 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; + return new SignedIdentityDocument(signature, (int)signingKeyVersion, providerUniqueId, athenzService, (int)documentVersion, - configserverHostname, instanceHostname, createdAt, ips, identityType); + configserverHostname, instanceHostname, createdAt, ips, identityType, clusterType); } private static Instant getJsr310Instant(double v) { 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 2b5165a815a..2014b74a3e6 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 @@ -199,16 +199,9 @@ public class InstanceValidatorTest { 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); - SignedIdentityDocument signedIdentityDocument = new SignedIdentityDocument(null, - 0, - vespaUniqueInstanceId, - new AthenzService(domain, service), - 0, - "localhost", - "localhost", - Instant.now(), - Collections.emptySet(), - IdentityType.NODE); + SignedIdentityDocument signedIdentityDocument = new SignedIdentityDocument( + null, 0, vespaUniqueInstanceId, new AthenzService(domain, service), 0, "localhost", "localhost", + Instant.now(), Collections.emptySet(), IdentityType.NODE, "container"); return createInstanceConfirmation(vespaUniqueInstanceId, domain, service, signedIdentityDocument); } 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 df75e09b957..4e977324298 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 @@ -46,7 +46,8 @@ public class InstanceSerializerTest { "instancehostname", Instant.now().truncatedTo(ChronoUnit.MICROS), // Truncate to the precision given from EntityBindingsMapper.toAttestationData() Collections.emptySet(), - IdentityType.NODE); + IdentityType.NODE, + "container"); var json = String.format("{\n" + " \"provider\": \"provider_prod_us-north-1\",\n" + |