summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Tokle <mortent@oath.com>2019-02-21 11:25:50 +0100
committerMorten Tokle <mortent@oath.com>2019-02-21 11:59:59 +0100
commitbab80d36445a020981830f28bd050a9840f112f4 (patch)
tree8869923960ff77af0ee059ba3c2cc7904e312ee0
parent4380cd5a3cdf50c6dd5d39e0a0b8b245b8ae70e5 (diff)
Add aws credential provider
-rw-r--r--parent/pom.xml6
-rw-r--r--vespa-athenz/pom.xml5
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/aws/AwsCredentialsProvider.java79
3 files changed, 89 insertions, 1 deletions
diff --git a/parent/pom.xml b/parent/pom.xml
index 7d7dfc1dc08..1cececbd8e8 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -708,6 +708,11 @@
<artifactId>assertj-core</artifactId>
<version>3.11.1</version>
</dependency>
+ <dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk-core</artifactId>
+ <version>${aws.sdk.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -717,6 +722,7 @@
<apache.httpclient.version>4.4.1</apache.httpclient.version>
<apache.httpcore.version>4.4.1</apache.httpcore.version>
<asm.version>7.0</asm.version>
+ <aws.sdk.version>1.11.357</aws.sdk.version>
<jna.version>4.5.2</jna.version>
<tensorflow.version>1.12.0</tensorflow.version>
<!-- Athenz dependencies. Make sure these dependencies matches those in Vespa's internal repositories -->
diff --git a/vespa-athenz/pom.xml b/vespa-athenz/pom.xml
index 27b68fbf360..f30aed1af5f 100644
--- a/vespa-athenz/pom.xml
+++ b/vespa-athenz/pom.xml
@@ -114,7 +114,10 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk-core</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/aws/AwsCredentialsProvider.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/aws/AwsCredentialsProvider.java
new file mode 100644
index 00000000000..28f028832b4
--- /dev/null
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/aws/AwsCredentialsProvider.java
@@ -0,0 +1,79 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.athenz.client.aws;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.BasicSessionCredentials;
+import com.yahoo.vespa.athenz.api.AthenzDomain;
+import com.yahoo.vespa.athenz.api.AwsRole;
+import com.yahoo.vespa.athenz.api.AwsTemporaryCredentials;
+import com.yahoo.vespa.athenz.client.zts.DefaultZtsClient;
+import com.yahoo.vespa.athenz.client.zts.ZtsClient;
+import com.yahoo.vespa.athenz.identity.ServiceIdentityProvider;
+
+import javax.net.ssl.SSLContext;
+import java.net.URI;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Objects;
+import java.util.logging.Logger;
+
+/**
+ * Implementation of AWSCredentialsProvider using com.yahoo.vespa.athenz.client.zts.ZtsClient
+ *
+ * @author mortent
+ */
+public class AwsCredentialsProvider implements AWSCredentialsProvider {
+
+ private static final Logger logger = Logger.getLogger(AwsCredentialsProvider.class.getName());
+
+ private final static Duration MIN_EXPIRY = Duration.ofMinutes(5);
+ private final AthenzDomain athenzDomain;
+ private final AwsRole awsRole;
+ private final ZtsClient ztsClient;
+ private volatile AwsTemporaryCredentials credentials;
+
+ public AwsCredentialsProvider(ZtsClient ztsClient, AthenzDomain athenzDomain, AwsRole awsRole) {
+ this.ztsClient = ztsClient;
+ this.athenzDomain = athenzDomain;
+ this.awsRole = awsRole;
+ this.credentials = getAthenzTempCredentials();
+ }
+
+ public AwsCredentialsProvider(URI ztsUrl, ServiceIdentityProvider identityProvider, AthenzDomain athenzDomain, AwsRole awsRole) {
+ this(new DefaultZtsClient(ztsUrl, identityProvider), athenzDomain, awsRole);
+ }
+
+ public AwsCredentialsProvider(URI ztsUrl, SSLContext sslContext, AthenzDomain athenzDomain, AwsRole awsRole) {
+ this(new DefaultZtsClient(ztsUrl, null, sslContext), athenzDomain, awsRole);
+ }
+
+ /**
+ * Requests temporary credentials from ZTS or return cached credentials
+ */
+ private AwsTemporaryCredentials getAthenzTempCredentials() {
+ if(shouldRefresh(credentials)) {
+ this.credentials = ztsClient.getAwsTemporaryCredentials(athenzDomain, awsRole);
+ }
+ return credentials;
+ }
+
+ @Override
+ public AWSCredentials getCredentials() {
+ AwsTemporaryCredentials creds = getAthenzTempCredentials();
+ return new BasicSessionCredentials(creds.accessKeyId(), creds.secretAccessKey(), creds.sessionToken());
+ }
+
+ @Override
+ public void refresh() {
+ getAthenzTempCredentials();
+ }
+
+ /*
+ * Checks credential expiration, returns true if it will expipre in the next MIN_EXPIRY minutes
+ */
+ private static boolean shouldRefresh(AwsTemporaryCredentials credentials) {
+ Instant expiration = credentials.expiration();
+ return Objects.isNull(expiration) || expiration.minus(MIN_EXPIRY).isAfter(Instant.now());
+ }
+}