diff options
author | Morten Tokle <mortent@oath.com> | 2018-04-13 14:40:50 +0200 |
---|---|---|
committer | Morten Tokle <mortent@oath.com> | 2018-04-13 14:42:46 +0200 |
commit | c77f80734440af08b29e6191b8b740f6136f2014 (patch) | |
tree | 7801199f49f300e75d8b85bbeeb58a82902098b5 /athenz-identity-provider-service | |
parent | 41969051757a99e5c8ed09fac31fa0658f039c7c (diff) |
add access control to identity document resource
Diffstat (limited to 'athenz-identity-provider-service')
2 files changed, 35 insertions, 2 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java index e3a937919fe..8ce13111536 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java @@ -10,10 +10,12 @@ import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.node.Allocation; +import java.net.InetAddress; import java.security.PrivateKey; import java.security.Signature; import java.time.Instant; import java.util.Base64; +import java.util.Objects; /** * @author mortent @@ -86,5 +88,28 @@ public class IdentityDocumentGenerator { private static String toZoneDnsSuffix(Zone zone, String dnsSuffix) { return zone.environment().value() + "-" + zone.region().value() + "." + dnsSuffix; } + + /* + * Basic access control until we have mutual auth where athenz x509certs are distributed on all docker nodes by node admin + * Checks: + * If remote hostname == requested hostname --> OK + * If remote hostname is parent of requested hostname in node repo --> OK + * Otherwise NOT OK + */ + boolean validateAccess(String hostname, String remoteAddr) { + try { + InetAddress addr = InetAddress.getByName(remoteAddr); + String remoteHostname = addr.getHostName(); + if (Objects.equals(hostname, remoteHostname)) { + return true; + } + Node node = nodeRepository.getNode(hostname).orElseThrow(() -> new RuntimeException("Unable to find node " + hostname)); + return node.parentHostname() + .map(parent -> Objects.equals(parent, remoteHostname)) + .orElse(false); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java index b3e5aee97b3..a39a7cf1a05 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentResource.java @@ -5,12 +5,15 @@ import com.google.inject.Inject; import com.yahoo.container.jaxrs.annotation.Component; import com.yahoo.log.LogLevel; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.BadRequestException; +import javax.ws.rs.ForbiddenException; import javax.ws.rs.GET; import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import java.util.logging.Logger; @@ -31,8 +34,14 @@ public class IdentityDocumentResource { @GET @Produces(MediaType.APPLICATION_JSON) - public SignedIdentityDocument getIdentityDocument(@QueryParam("hostname") String hostname) { + public SignedIdentityDocument getIdentityDocument(@QueryParam("hostname") String hostname, + @Context HttpServletRequest request) { // TODO Use TLS client authentication instead of blindly trusting hostname + // Until we have distributed Athenz x509 certificates we will validate that remote address + // is authorized to access the provided hostname. This means any container + if (!identityDocumentGenerator.validateAccess(hostname, request.getRemoteAddr())) { + throw new ForbiddenException(); + } if (hostname == null) { throw new BadRequestException("The 'hostname' query parameter is missing"); } @@ -44,5 +53,4 @@ public class IdentityDocumentResource { throw new InternalServerErrorException(message, e); } } - } |