Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
<version>1.5.13</version>
</dependency>

<!-- HTTP request dependencies-->
Expand Down Expand Up @@ -130,6 +130,15 @@
<version>2.34.8</version>
<optional>true</optional>
</dependency>

<!-- GCP dependencies-->
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>1.20.0</version>
<optional>true</optional>
</dependency>

<!-- Testing dependencies-->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/com/infisical/sdk/auth/GCPAuthProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.infisical.sdk.auth;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.IdTokenCredentials;
import com.google.auth.oauth2.IdTokenProvider;
import com.google.auth.oauth2.IdTokenProvider.Option;
import com.infisical.sdk.util.InfisicalException;

public class GCPAuthProvider {

public static HashMap<String,String> getGCPAuthInput(String identityId) throws InfisicalException{

if ( identityId == null || identityId.isEmpty() )

throw new InfisicalException( "Identity ID is required");

try{

// This will fetch credentials from environment variable named GOOGLE_APPLICATION_CREDENTIALS or
// or if it's running in a GCP instance it will get them from the instance itself (GCP service account attached)
GoogleCredentials googleCredentials = GoogleCredentials.getApplicationDefault();

IdTokenCredentials idTokenCredentials =
IdTokenCredentials.newBuilder()
.setIdTokenProvider((IdTokenProvider) googleCredentials)
.setTargetAudience(identityId)
.setOptions(Arrays.asList(Option.FORMAT_FULL, Option.LICENSES_TRUE))
.build();

// Get the ID token.
String idToken = idTokenCredentials.refreshAccessToken().getTokenValue();

// Body cannot be a string so used a HashMap, you can use builder, POJO etc
HashMap<String, String> body = new HashMap<>();
body.put("identityId", identityId);
body.put("jwt", idToken);

return body;

} catch (IOException e){
throw new RuntimeException("Failed to fetch Google credentials", e);
} catch (Exception e){
throw new RuntimeException("Error during GCP Authentication", e);
}

}
}
14 changes: 14 additions & 0 deletions src/main/java/com/infisical/sdk/resources/AuthClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.infisical.sdk.api.ApiClient;
import com.infisical.sdk.auth.AwsAuthProvider;
import com.infisical.sdk.auth.GCPAuthProvider;
import com.infisical.sdk.models.AwsAuthLoginInput;
import com.infisical.sdk.models.LdapAuthLoginInput;
import com.infisical.sdk.models.MachineIdentityCredential;
Expand Down Expand Up @@ -56,6 +57,19 @@ public void AwsAuthLogin(AwsAuthLoginInput input) throws InfisicalException {
this.onAuthenticate.accept(credential.getAccessToken());
}

public void GCPAuthLogin(String identityId) throws InfisicalException {

if (identityId == null || identityId.isEmpty())

throw new InfisicalException("Identity ID is required");

var url = String.format("%s%s", this.apiClient.GetBaseUrl(), "/api/v1/auth/gcp-auth/login");

var input = GCPAuthProvider.getGCPAuthInput(identityId);
var credential = this.apiClient.post(url, input, MachineIdentityCredential.class);
this.onAuthenticate.accept(credential.getAccessToken());
}

public void SetAccessToken(String accessToken) {
this.onAuthenticate.accept(accessToken);
}
Expand Down
63 changes: 63 additions & 0 deletions src/test/java/com/infisical/sdk/auth/GCPAuthIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.infisical.sdk.auth;

import com.infisical.sdk.InfisicalSdk;
import com.infisical.sdk.config.SdkConfig;
import com.infisical.sdk.util.EnvironmentVariables;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.junit.jupiter.api.Assertions.*;

public class GCPAuthIntegrationTest {

private static final Logger logger = LoggerFactory.getLogger(GCPAuthIntegrationTest.class);
@Test
public void testGCPAuthAndFetchSecrets() throws Exception {

// Load env variables
var envVars = new EnvironmentVariables();

// Get Machine Identity Id
String machineIdentityId = System.getenv("INFISICAL_MACHINE_IDENTITY_ID");


// Check if env variable machine identity is set others are already tested via env tests
assertNotNull(machineIdentityId, "INFISICAL_MACHINE_IDENTITY_ID env variable must be set");


// Create SDK instance
var sdk = new InfisicalSdk(new SdkConfig.Builder()
.withSiteUrl(envVars.getSiteUrl())
.build()
);

// Authenticate using GCP Auth
assertDoesNotThrow(() -> {
sdk.Auth().GCPAuthLogin(machineIdentityId);
});



try {

// Test if we have correctly logged in and we can list the secrets
var secrets = sdk.Secrets().ListSecrets(
envVars.getProjectId(),
"dev",
"/",
null,
null,
null);

assertNotNull(secrets, "Secrets list should not be null");
assertFalse(secrets.isEmpty(), "Secrets list should not be empty");
Comment on lines +53 to +54
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Test assumes secrets exist in the 'dev' environment. Consider adding a comment explaining this prerequisite or making the test more robust by checking if no secrets exist.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/test/java/com/infisical/sdk/auth/GCPAuthIntegrationTest.java
Line: 53:54

Comment:
**style:** Test assumes secrets exist in the 'dev' environment. Consider adding a comment explaining this prerequisite or making the test more robust by checking if no secrets exist.

How can I resolve this? If you propose a fix, please make it concise.


logger.info("TestGCPAuth Successful");
logger.info("Secrets length : {}", secrets.size());

} catch (Exception e) {
throw new AssertionError(e);
}
}
}