From 337fbe0cef34d6a5c6e12a593b7eea6ec9ad459e Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Thu, 23 Feb 2023 11:46:38 +0100 Subject: Set ztsUrl/sisUrl in identity document --- .../IdentityDocumentGenerator.java | 29 +++++++++++++++++++--- .../hosted/ca/restapi/InstanceSerializer.java | 5 +++- .../src/vespa/athenz-provider-service.def | 1 + .../identityprovider/api/EntityBindingsMapper.java | 2 ++ .../api/SignedIdentityDocument.java | 7 +++--- .../api/bindings/SignedIdentityDocumentEntity.java | 8 +++--- .../api/EntityBindingsMapperTest.java | 1 + .../client/IdentityDocumentSignerTest.java | 7 +++--- 8 files changed, 47 insertions(+), 13 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 5143a38b2c1..5138bee1ff6 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 @@ -3,7 +3,10 @@ package com.yahoo.vespa.hosted.athenz.instanceproviderservice; import com.yahoo.component.annotation.Inject; import com.yahoo.config.provision.Zone; +import com.yahoo.container.jdisc.secretstore.SecretStore; import com.yahoo.net.HostName; +import com.yahoo.security.KeyUtils; + import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.identityprovider.api.ClusterType; import com.yahoo.vespa.athenz.identityprovider.api.IdentityType; @@ -32,17 +35,20 @@ public class IdentityDocumentGenerator { private final NodeRepository nodeRepository; private final Zone zone; private final KeyProvider keyProvider; + private final SecretStore secretStore; private final AthenzProviderServiceConfig athenzProviderServiceConfig; @Inject public IdentityDocumentGenerator(AthenzProviderServiceConfig config, NodeRepository nodeRepository, Zone zone, - KeyProvider keyProvider) { + KeyProvider keyProvider, + SecretStore secretStore) { this.athenzProviderServiceConfig = config; this.nodeRepository = nodeRepository; this.zone = zone; this.keyProvider = keyProvider; + this.secretStore = secretStore; } public SignedIdentityDocument generateSignedIdentityDocument(String hostname, IdentityType identityType) { @@ -61,7 +67,7 @@ public class IdentityDocumentGenerator { Set ips = new HashSet<>(node.ipConfig().primary()); - PrivateKey privateKey = keyProvider.getPrivateKey(athenzProviderServiceConfig.secretVersion()); + PrivateKey privateKey = privateKey(node); AthenzService providerService = new AthenzService(athenzProviderServiceConfig.domain(), athenzProviderServiceConfig.serviceName()); String configServerHostname = HostName.getLocalhost(); @@ -73,11 +79,28 @@ public class IdentityDocumentGenerator { return new SignedIdentityDocument( signature, athenzProviderServiceConfig.secretVersion(), providerUniqueId, providerService, SignedIdentityDocument.DEFAULT_DOCUMENT_VERSION, configServerHostname, node.hostname(), - createdAt, ips, identityType, clusterType); + createdAt, ips, identityType, clusterType, ztsUrl(node)); } catch (Exception e) { throw new RuntimeException("Exception generating identity document: " + e.getMessage(), e); } } + private PrivateKey privateKey(Node node) { + // return sisSecret for public non-enclave hosts. secret otherwise + if (zone.system().isPublic() && !node.cloudAccount().isEnclave(zone)) { + String keyPem = secretStore.getSecret(athenzProviderServiceConfig.sisSecretName(), athenzProviderServiceConfig.sisSecretVersion()); + return KeyUtils.fromPemEncodedPrivateKey(keyPem); + } else { + return keyProvider.getPrivateKey(athenzProviderServiceConfig.secretVersion()); + } + } + private String ztsUrl(Node node) { + // return sisUrl for public non-enclave hosts, ztsUrl otherwise + if (zone.system().isPublic() && !node.cloudAccount().isEnclave(zone)) { + return athenzProviderServiceConfig.sisUrl(); + } else { + return athenzProviderServiceConfig.ztsUrl(); + } + } } 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 fec03afab69..8c575a6403b 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 @@ -49,6 +49,7 @@ public class InstanceSerializer { 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 String IDD_ZTS_URL_FIELD = "zts-url"; private static final ObjectMapper objectMapper = new ObjectMapper(); static { @@ -100,10 +101,12 @@ public class InstanceSerializer { IdentityType identityType = IdentityType.fromId(requireField(IDD_IDENTITY_TYPE_FIELD, root).asString()); var clusterTypeField = root.field(IDD_CLUSTER_TYPE_FIELD); var clusterType = clusterTypeField.valid() ? ClusterType.from(clusterTypeField.asString()) : null; + var ztsUrlField = root.field(IDD_ZTS_URL_FIELD); + var ztsUrl = ztsUrlField.valid() ? ztsUrlField.asString() : ""; return new SignedIdentityDocument(signature, (int)signingKeyVersion, providerUniqueId, athenzService, (int)documentVersion, - configserverHostname, instanceHostname, createdAt, ips, identityType, clusterType); + configserverHostname, instanceHostname, createdAt, ips, identityType, clusterType, ztsUrl); } private static Instant getJsr310Instant(double v) { diff --git a/configdefinitions/src/vespa/athenz-provider-service.def b/configdefinitions/src/vespa/athenz-provider-service.def index cb6787c4bec..4c9c74f9b8f 100644 --- a/configdefinitions/src/vespa/athenz-provider-service.def +++ b/configdefinitions/src/vespa/athenz-provider-service.def @@ -16,6 +16,7 @@ secretVersion int # Tempory resources sisSecretName string default="" sisSecretVersion int default=0 +sisUrl string default = "" # Secret name of CA certificate caCertSecretName string 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 9b7b666e353..067e8a6b00f 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 @@ -58,6 +58,7 @@ public class EntityBindingsMapper { entity.ipAddresses(), IdentityType.fromId(entity.identityType()), Optional.ofNullable(entity.clusterType()).map(ClusterType::from).orElse(null), + entity.ztsUrl(), entity.unknownAttributes()); } @@ -74,6 +75,7 @@ public class EntityBindingsMapper { model.ipAddresses(), model.identityType().id(), Optional.ofNullable(model.clusterType()).map(ClusterType::toConfigValue).orElse(null), + model.ztsUrl(), model.unknownAttributes()); } 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 49a39d25e87..eba89b72d87 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 @@ -3,6 +3,7 @@ package com.yahoo.vespa.athenz.identityprovider.api; import com.yahoo.vespa.athenz.api.AthenzService; +import java.net.URL; import java.time.Instant; import java.util.HashMap; import java.util.Map; @@ -17,7 +18,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 ipAddresses, - IdentityType identityType, ClusterType clusterType, Map unknownAttributes) { + IdentityType identityType, ClusterType clusterType, String ztsUrl, Map unknownAttributes) { public SignedIdentityDocument { ipAddresses = Set.copyOf(ipAddresses); @@ -33,9 +34,9 @@ public record SignedIdentityDocument(String signature, int signingKeyVersion, Ve public SignedIdentityDocument(String signature, int signingKeyVersion, VespaUniqueInstanceId providerUniqueId, AthenzService providerService, int documentVersion, String configServerHostname, String instanceHostname, Instant createdAt, Set ipAddresses, - IdentityType identityType, ClusterType clusterType) { + IdentityType identityType, ClusterType clusterType, String ztsUrl) { this(signature, signingKeyVersion, providerUniqueId, providerService, documentVersion, configServerHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, Map.of()); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, Map.of()); } public static final int DEFAULT_DOCUMENT_VERSION = 2; 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 c37dd2f9147..edbe032ec26 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 @@ -17,7 +17,7 @@ import java.util.Set; public record SignedIdentityDocumentEntity( String signature, int signingKeyVersion, String providerUniqueId, String providerService, int documentVersion, String configServerHostname, String instanceHostname, Instant createdAt, Set ipAddresses, - String identityType, String clusterType, Map unknownAttributes) { + String identityType, String clusterType, String ztsUrl, Map unknownAttributes) { @JsonCreator public SignedIdentityDocumentEntity(@JsonProperty("signature") String signature, @@ -30,9 +30,10 @@ public record SignedIdentityDocumentEntity( @JsonProperty("created-at") Instant createdAt, @JsonProperty("ip-addresses") Set ipAddresses, @JsonProperty("identity-type") String identityType, - @JsonProperty("cluster-type") String clusterType) { + @JsonProperty("cluster-type") String clusterType, + @JsonProperty("zts-url") String ztsUrl) { this(signature, signingKeyVersion, providerUniqueId, providerService, documentVersion, configServerHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType, new HashMap<>()); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl, new HashMap<>()); } @JsonProperty("signature") @Override public String signature() { return signature; } @@ -46,6 +47,7 @@ public record SignedIdentityDocumentEntity( @JsonProperty("ip-addresses") @Override public Set 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; } @JsonAnyGetter @Override public Map unknownAttributes() { return unknownAttributes; } @JsonAnySetter public void set(String name, Object value) { unknownAttributes.put(name, value); } } 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 f8c119190a6..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 @@ -30,6 +30,7 @@ class EntityBindingsMapperTest { "ip-addresses": [], "identity-type": "node", "cluster-type": "admin", + "zts-url": "https://zts.url/", "unknown-string": "string-value", "unknown-object": { "member-in-unknown-object": 123 } } 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 0b8ff4277f1..36c640f3839 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 @@ -36,6 +36,7 @@ public class IdentityDocumentSignerTest { private static final Instant createdAt = Instant.EPOCH; private static final HashSet ipAddresses = new HashSet<>(Arrays.asList("1.2.3.4", "::1")); private static final ClusterType clusterType = ClusterType.CONTAINER; + private static final String ztsUrl = "https://foo"; @Test void generates_and_validates_signature() { @@ -46,7 +47,7 @@ public class IdentityDocumentSignerTest { SignedIdentityDocument signedIdentityDocument = new SignedIdentityDocument( signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl); assertTrue(signer.hasValidSignature(signedIdentityDocument, keyPair.getPublic())); } @@ -60,10 +61,10 @@ public class IdentityDocumentSignerTest { var docWithoutClusterType = new SignedIdentityDocument( signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, null); + instanceHostname, createdAt, ipAddresses, identityType, null, ztsUrl); var docWithClusterType = new SignedIdentityDocument( signature, KEY_VERSION, id, providerService, DEFAULT_DOCUMENT_VERSION, configserverHostname, - instanceHostname, createdAt, ipAddresses, identityType, clusterType); + instanceHostname, createdAt, ipAddresses, identityType, clusterType, ztsUrl); assertTrue(signer.hasValidSignature(docWithoutClusterType, keyPair.getPublic())); assertEquals(docWithClusterType.signature(), docWithoutClusterType.signature()); -- cgit v1.2.3