diff options
Diffstat (limited to 'vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider')
7 files changed, 37 insertions, 19 deletions
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 5e887cc4df4..0949192b884 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 @@ -47,7 +47,8 @@ public class EntityBindingsMapper { entity.instanceHostname(), entity.createdAt(), entity.ipAddresses(), - IdentityType.fromId(entity.identityType())); + IdentityType.fromId(entity.identityType()), + entity.clusterType()); } public static SignedIdentityDocumentEntity toSignedIdentityDocumentEntity(SignedIdentityDocument model) { @@ -61,7 +62,8 @@ public class EntityBindingsMapper { model.instanceHostname(), model.createdAt(), model.ipAddresses(), - model.identityType().id()); + model.identityType().id(), + model.clusterType()); } 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 0f941ea5bf0..c2d8ece84a5 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 @@ -14,7 +14,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) { - public static final int DEFAULT_DOCUMENT_VERSION = 1; + IdentityType identityType, String clusterType) { + 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 868b41b6689..2fb709615da 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 @@ -20,5 +20,6 @@ public record SignedIdentityDocumentEntity(@JsonProperty("signature") String sig @JsonProperty("instance-hostname") String instanceHostname, @JsonProperty("created-at") Instant createdAt, @JsonProperty("ip-addresses") Set<String> ipAddresses, - @JsonProperty("identity-type") String identityType) { + @JsonProperty("identity-type") String identityType, + @JsonProperty("cluster-type") String clusterType) { } 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 91b95cb6084..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 @@ -79,6 +79,7 @@ class AthenzCredentialsService { tenantIdentity, document.providerUniqueId(), document.ipAddresses(), + document.clusterType(), keyPair); try (ZtsClient ztsClient = new DefaultZtsClient.Builder(ztsEndpoint).withIdentityProvider(nodeIdentityProvider).build()) { @@ -100,6 +101,7 @@ class AthenzCredentialsService { tenantIdentity, document.providerUniqueId(), document.ipAddresses(), + document.clusterType(), newKeyPair); try (ZtsClient ztsClient = new DefaultZtsClient.Builder(ztsEndpoint).withSslContext(sslContext).build()) { 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 0caf3bdfd0b..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 @@ -4,18 +4,18 @@ package com.yahoo.vespa.athenz.identityprovider.client; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.yahoo.component.annotation.Inject; import com.yahoo.component.AbstractComponent; +import com.yahoo.component.annotation.Inject; import com.yahoo.container.core.identity.IdentityConfig; import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider; import com.yahoo.container.jdisc.athenz.AthenzIdentityProviderException; import com.yahoo.jdisc.Metric; import com.yahoo.metrics.ContainerMetrics; import com.yahoo.security.KeyStoreBuilder; +import com.yahoo.security.MutableX509KeyManager; import com.yahoo.security.Pkcs10Csr; import com.yahoo.security.SslContextBuilder; import com.yahoo.security.X509CertificateWithKey; -import com.yahoo.security.MutableX509KeyManager; import com.yahoo.vespa.athenz.api.AthenzAccessToken; import com.yahoo.vespa.athenz.api.AthenzDomain; import com.yahoo.vespa.athenz.api.AthenzRole; @@ -48,7 +48,6 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Collectors; import static com.yahoo.security.KeyStoreType.PKCS12; @@ -299,7 +298,9 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen } private X509Certificate requestRoleCertificate(AthenzRole role) { - Pkcs10Csr csr = csrGenerator.generateRoleCsr(identity, role, credentials.getIdentityDocument().providerUniqueId(), credentials.getKeyPair()); + var doc = credentials.getIdentityDocument(); + Pkcs10Csr csr = csrGenerator.generateRoleCsr( + identity, role, doc.providerUniqueId(), doc.clusterType(), credentials.getKeyPair()); try (ZtsClient client = createZtsClient()) { X509Certificate roleCertificate = client.getRoleCertificate(role, csr); updateRoleKeyManager(role, roleCertificate); 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 21ce30fd244..bafeab805bd 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,12 +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.client; -import com.yahoo.vespa.athenz.api.AthenzIdentity; -import com.yahoo.vespa.athenz.api.AthenzRole; -import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; import com.yahoo.security.Pkcs10Csr; import com.yahoo.security.Pkcs10CsrBuilder; import com.yahoo.security.SubjectAlternativeName; +import com.yahoo.vespa.athenz.api.AthenzIdentity; +import com.yahoo.vespa.athenz.api.AthenzRole; +import com.yahoo.vespa.athenz.identityprovider.api.VespaUniqueInstanceId; import javax.security.auth.x500.X500Principal; import java.security.KeyPair; @@ -14,8 +14,9 @@ import java.util.Set; import static com.yahoo.security.SignatureAlgorithm.SHA256_WITH_RSA; import static com.yahoo.security.SubjectAlternativeName.Type.DNS; -import static com.yahoo.security.SubjectAlternativeName.Type.IP; import static com.yahoo.security.SubjectAlternativeName.Type.EMAIL; +import static com.yahoo.security.SubjectAlternativeName.Type.IP; +import static com.yahoo.security.SubjectAlternativeName.Type.URI; /** * Generates a {@link Pkcs10Csr} for an instance. @@ -35,6 +36,7 @@ public class CsrGenerator { public Pkcs10Csr generateInstanceCsr(AthenzIdentity instanceIdentity, VespaUniqueInstanceId instanceId, Set<String> ipAddresses, + String 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> @@ -48,6 +50,7 @@ public class CsrGenerator { instanceIdentity.getDomainName().replace(".", "-"), dnsSuffix)) .addSubjectAlternativeName(DNS, getIdentitySAN(instanceId)); + if (clusterType != null) pkcs10CsrBuilder.addSubjectAlternativeName(URI, "vespa://cluster-type/%s".formatted(clusterType)); ipAddresses.forEach(ip -> pkcs10CsrBuilder.addSubjectAlternativeName(new SubjectAlternativeName(IP, ip))); return pkcs10CsrBuilder.build(); } @@ -55,12 +58,14 @@ public class CsrGenerator { public Pkcs10Csr generateRoleCsr(AthenzIdentity identity, AthenzRole role, VespaUniqueInstanceId instanceId, + String clusterType, KeyPair keyPair) { X500Principal principal = new X500Principal(String.format("OU=%s, cn=%s:role.%s", providerService, role.domain().getName(), role.roleName())); - return Pkcs10CsrBuilder.fromKeypair(principal, keyPair, SHA256_WITH_RSA) + 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)) - .build(); + .addSubjectAlternativeName(EMAIL, String.format("%s.%s@%s", identity.getDomainName(), identity.getName(), dnsSuffix)); + if (clusterType != null) b.addSubjectAlternativeName(URI, "vespa://cluster-type/%s".formatted(clusterType)); + return b.build(); } private String getIdentitySAN(VespaUniqueInstanceId instanceId) { 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 1c1dcb655c0..13bea80dfed 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 @@ -34,11 +34,14 @@ public class IdentityDocumentSigner { Instant createdAt, Set<String> ipAddresses, IdentityType identityType, + String clusterType, PrivateKey privateKey) { try { Signature signer = SignatureUtils.createSigner(privateKey); signer.initSign(privateKey); - writeToSigner(signer, providerUniqueId, providerService, configServerHostname, instanceHostname, createdAt, ipAddresses, identityType); + writeToSigner( + signer, providerUniqueId, providerService, configServerHostname, instanceHostname, createdAt, + ipAddresses, identityType, clusterType); byte[] signature = signer.sign(); return Base64.getEncoder().encodeToString(signature); } catch (GeneralSecurityException e) { @@ -50,7 +53,9 @@ public class IdentityDocumentSigner { try { Signature signer = SignatureUtils.createVerifier(publicKey); signer.initVerify(publicKey); - writeToSigner(signer, doc.providerUniqueId(), doc.providerService(), doc.configServerHostname(), doc.instanceHostname(), doc.createdAt(), doc.ipAddresses(), doc.identityType()); + writeToSigner( + signer, doc.providerUniqueId(), doc.providerService(), doc.configServerHostname(), + doc.instanceHostname(), doc.createdAt(), doc.ipAddresses(), doc.identityType(), doc.clusterType()); return signer.verify(Base64.getDecoder().decode(doc.signature())); } catch (GeneralSecurityException e) { throw new RuntimeException(e); @@ -64,7 +69,8 @@ public class IdentityDocumentSigner { String instanceHostname, Instant createdAt, Set<String> ipAddresses, - IdentityType identityType) throws SignatureException { + IdentityType identityType, + String clusterType) throws SignatureException { signer.update(providerUniqueId.asDottedString().getBytes(UTF_8)); signer.update(providerService.getFullName().getBytes(UTF_8)); signer.update(configServerHostname.getBytes(UTF_8)); @@ -76,5 +82,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)); } } |