summaryrefslogtreecommitdiffstats
path: root/athenz-identity-provider-service
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2023-02-02 16:11:08 +0100
committerBjørn Christian Seime <bjorncs@yahooinc.com>2023-02-03 12:23:24 +0100
commite09b191faf77bb95b923bb709b2181a0a3ee2c81 (patch)
tree42d28de543d81ca48bd0b2c4da53fe89f34d405f /athenz-identity-provider-service
parent3981141b25ee115f18529e74dacf21e1bf653fed (diff)
Add cluster type as SAN URI in Athenz instance certificates for Vespa
Diffstat (limited to 'athenz-identity-provider-service')
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/IdentityDocumentGenerator.java17
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidator.java22
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializer.java6
-rw-r--r--athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/InstanceValidatorTest.java13
-rw-r--r--athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/ca/restapi/InstanceSerializerTest.java3
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" +