Skip to content
79 changes: 79 additions & 0 deletions iam/iam-client/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>iam-client</artifactId>
<packaging>jar</packaging>
<name>MultiCloudJ - IAM Client</name>

<parent>
<groupId>com.salesforce.multicloudj</groupId>
<artifactId>iam</artifactId>
<version>0.2.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<dependencies>
<!-- Core dependencies -->
<dependency>
<groupId>com.salesforce.multicloudj</groupId>
<artifactId>multicloudj-common</artifactId>
</dependency>
<dependency>
<groupId>com.salesforce.multicloudj</groupId>
<artifactId>sts-client</artifactId>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.16.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.12.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.16.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.salesforce.multicloudj</groupId>
<artifactId>multicloudj-common</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>

</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package com.salesforce.multicloudj.iam.client;

import com.salesforce.multicloudj.iam.model.CreateOptions;
import com.salesforce.multicloudj.iam.model.PolicyDocument;
import com.salesforce.multicloudj.iam.model.TrustConfiguration;
import com.salesforce.multicloudj.sts.model.CredentialsOverrider;

import java.net.URI;
import java.util.List;
import java.util.Optional;

/**
* Entry point for client code to interact with Identity and Access Management (IAM) services
* in a substrate-agnostic way.
*
* <p>This client provides unified IAM operations across multiple cloud providers including
* AWS IAM, GCP IAM, and AliCloud RAM. It handles the complexity of different cloud IAM models
* and provides a consistent API for identity lifecycle management and policy operations.
*
* <p>Usage example:
* <pre>
* IamClient client = IamClient.builder("aws")
* .withRegion("us-west-2")
* .build();
*
* // Create identity
* String identityId = client.createIdentity("MyRole", "Example role", "123456789012", "us-west-2",
* Optional.empty(), Optional.empty());
*
* // Create policy
* PolicyDocument policy = PolicyDocument.builder()
* .version("2012-10-17") // Use provider-specific version (AWS example)
* .statement("StorageAccess")
* .effect("Allow")
* .addAction("storage:GetObject")
* .addResource("storage://my-bucket/*")
* .endStatement()
* .build();
*
* // Attach policy
* client.attachInlinePolicy(policy, "123456789012", "us-west-2", "my-bucket");
* </pre>
*/
public class IamClient {

/**
* Protected constructor for IamClient.
* Use the builder pattern to create instances.
*/
protected IamClient() {
// Implementation will be added later when AbstractIamService is available
}

/**
* Creates a new IamClientBuilder for the specified provider.
*
* @param providerId the ID of the provider such as "aws", "gcp", or "ali"
* @return a new IamClientBuilder instance
*/
public static IamClientBuilder builder(String providerId) {
return new IamClientBuilder(providerId);
}

/**
* Creates a new identity (role/service account) in the cloud provider.
*
* @param identityName the name of the identity to create
* @param description optional description for the identity (can be null)
* @param tenantId the tenant ID (AWS Account ID, GCP Project ID, or AliCloud Account ID)
* @param region the region for IAM operations
* @param trustConfig optional trust configuration
* @param options optional creation options
* @return the unique identifier of the created identity
*/
public String createIdentity(String identityName, String description, String tenantId, String region,
Optional<TrustConfiguration> trustConfig, Optional<CreateOptions> options) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Attaches an inline policy to a resource.
*
* @param policyDocument the policy document in substrate-neutral format
* @param tenantId the tenant ID
* @param region the region
* @param resource the resource to attach the policy to
*/
public void attachInlinePolicy(PolicyDocument policyDocument, String tenantId, String region, String resource) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Retrieves the details of a specific inline policy attached to an identity.
*
* @param identityName the name of the identity
* @param policyName the name of the policy
* @param tenantId the tenant ID
* @param region the region
* @return the policy document details as a string
*/
public String getInlinePolicyDetails(String identityName, String policyName, String tenantId, String region) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Lists all inline policies attached to an identity.
*
* @param identityName the name of the identity
* @param tenantId the tenant ID
* @param region the region
* @return a list of policy names
*/
public List<String> getAttachedPolicies(String identityName, String tenantId, String region) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Removes an inline policy from an identity.
*
* @param identityName the name of the identity
* @param policyName the name of the policy to remove
* @param tenantId the tenant ID
* @param region the region
*/
public void removePolicy(String identityName, String policyName, String tenantId, String region) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Deletes an identity from the cloud provider.
*
* @param identityName the name of the identity to delete
* @param tenantId the tenant ID
* @param region the region
*/
public void deleteIdentity(String identityName, String tenantId, String region) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Retrieves metadata about an identity.
*
* @param identityName the name of the identity
* @param tenantId the tenant ID
* @param region the region
* @return the unique identity identifier (ARN, email, or roleId)
*/
public String getIdentity(String identityName, String tenantId, String region) {
// Implementation will be added when driver layer is available
throw new UnsupportedOperationException("Implementation will be added when driver layer is available");
}

/**
* Builder class for IamClient.
*/
public static class IamClientBuilder {
protected String region;
protected URI endpoint;

/**
* Constructor for IamClientBuilder.
*
* @param providerId the ID of the provider such as "aws", "gcp", or "ali"
*/
public IamClientBuilder(String providerId) {
// Implementation will be added when ServiceLoader and AbstractIamService are available
// Will find and initialize the provider builder here
}

/**
* Sets the region for the IAM client.
*
* @param region the region to set
* @return this IamClientBuilder instance
*/
public IamClientBuilder withRegion(String region) {
this.region = region;
// Implementation will be added later to delegate to underlying provider builder
return this;
}

/**
* Sets the endpoint to override for the IAM client.
*
* @param endpoint the endpoint to set
* @return this IamClientBuilder instance
*/
public IamClientBuilder withEndpoint(URI endpoint) {
this.endpoint = endpoint;
// Implementation will be added later to delegate to underlying provider builder
return this;
}

/**
* Builds and returns an IamClient instance.
*
* @return a new IamClient instance
*/
public IamClient build() {
// Implementation will be added when ServiceLoader and AbstractIamService are available
return new IamClient();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.salesforce.multicloudj.iam.model;

import java.util.Objects;
import lombok.Builder;
import lombok.Getter;

/**
* Optional configuration for identity creation operations.
*
* <p>This class provides additional options that can be set during identity creation,
* such as path specifications, session duration limits, and permission boundaries.
*
* <p>Permission boundary identifiers are provider-specific and translated internally
* by the implementation layer. The client accepts the native format for the target
* cloud provider.
*
* <p>Usage example:
* <pre>
* CreateOptions options = CreateOptions.builder()
* .path("/service-roles/")
* .maxSessionDuration(3600) // 1 hour in seconds
* .permissionBoundary("policy-identifier") // Provider-specific format
* .build();
* </pre>
*/
@Getter
@Builder
public class CreateOptions {
private final String path;
private final Integer maxSessionDuration;
private final String permissionBoundary;

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CreateOptions that = (CreateOptions) o;
return Objects.equals(path, that.path)
&& Objects.equals(maxSessionDuration, that.maxSessionDuration)
&& Objects.equals(permissionBoundary, that.permissionBoundary);
}

@Override
public int hashCode() {
return Objects.hash(path, maxSessionDuration, permissionBoundary);
}

@Override
public String toString() {
return "CreateOptions{"
+ "path='" + path + '\''
+ ", maxSessionDuration=" + maxSessionDuration
+ ", permissionBoundary='" + permissionBoundary + '\''
+ '}';
}
}
Comment on lines +33 to +60
Copy link
Contributor

Choose a reason for hiding this comment

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

I see you have onboarded these methods for all classes? These should exist if they are required, I don't see the usage anywhere

Loading
Loading