IAM

The IamClient class in the multicloudj library provides a comprehensive, cloud-agnostic interface to interact with Identity and Access Management services like AWS IAM and GCP IAM.

This client enables creating and managing identities (roles, service accounts), attaching and managing inline policies, and configuring trust relationships across multiple cloud providers with a consistent API.


Feature Support Across Providers

Core API Features

Feature Name GCP AWS ALI Comments
Create Identity ✅ Supported ✅ Supported 📅 In Roadmap Create roles/service accounts with optional trust and options
Get Identity ✅ Supported ✅ Supported 📅 In Roadmap Retrieve identity metadata (ARN, email, or roleId)
Delete Identity ✅ Supported ✅ Supported 📅 In Roadmap Remove an identity from the cloud provider
Attach Inline Policy ✅ Supported ✅ Supported 📅 In Roadmap Attach a policy document to an identity
Get Attached Policies ✅ Supported ✅ Supported 📅 In Roadmap List inline policies attached to an identity
Get Inline Policy Details ✅ Supported ✅ Supported 📅 In Roadmap Retrieve policy document details
Remove Policy ✅ Supported ✅ Supported 📅 In Roadmap Remove an inline policy from an identity

Configuration Options

Configuration GCP AWS ALI Comments
Trust Configuration ✅ Supported ✅ Supported 📅 In Roadmap Principals and conditions for assume/impersonate
Endpoint Override ✅ Supported ✅ Supported 📅 In Roadmap Custom endpoint configuration
Credentials Override ✅ Supported ✅ Supported 📅 In Roadmap Custom credential providers via STS

Provider IDs

Provider Provider ID
AWS aws
GCP (Google Cloud Platform) gcp

Alibaba Cloud RAM is not yet implemented for IAM. There is currently no iam-ali module, so only the aws and gcp provider IDs are available.


Provider-Specific Notes

AWS (IAM)

  • Tenant ID is the AWS account ID (12-digit). IAM is global per partition; region is used by the IAM client to resolve the partition and its endpoint.
  • Get inline policy details: policyName is required.

GCP (IAM)

  • Tenant ID: for identity operations use project ID (or projects/...); for policy operations use the resource that owns the IAM policy (e.g. projects/my-project, folders/123).
  • Create Identity creates a Service Account on GCP. You provide the service account ID; it returns email {id}@{project}.iam.gserviceaccount.com. Create options are unused.
  • Attach policy: the policy principal is the IAM member (e.g. serviceAccount:...); policy actions are GCP role names (e.g. roles/storage.objectViewer). Get inline policy details: roleName is required; policyName is not used.
  • Remove policy: policyName is the role name to remove.

Creating the Client

Basic Client

IamClient iamClient = IamClient.builder("aws")
    .withRegion("us-west-2")
    .build();

Use the appropriate provider ID: "aws" or "gcp". The client implements AutoCloseable; use try-with-resources or call close() when done.

You can also override the endpoint or supply custom credentials:

IamClient iamClient = IamClient.builder("aws")
    .withRegion("us-west-2")
    .withEndpoint(URI.create("https://iam.custom-endpoint.com"))
    .withCredentialsOverrider(credentialsOverrider)
    .build();

Identity Operations

Creating an Identity

try (IamClient iamClient = IamClient.builder("aws").withRegion("us-west-2").build()) {

    String identityId = iamClient.createIdentity(
        "MyRole",
        "Example role for storage access",
        "123456789012",
        "us-west-2",
        Optional.empty(),
        Optional.empty()
    );
}

With trust configuration:

TrustConfiguration trustConfig = TrustConfiguration.builder()
    .addTrustedPrincipal("arn:aws:iam::123456789012:root")
    .build();

String identityId = iamClient.createIdentity(
    "CrossAccountRole",
    "Role assumable by account 123456789012",
    "123456789012",
    "us-west-2",
    Optional.of(trustConfig),
    Optional.empty()
);

With creation options (path, max session duration, permission boundary):

CreateOptions options = CreateOptions.builder()
    .path("/service-roles/")
    .maxSessionDuration(3600)
    .build();

String identityId = iamClient.createIdentity(
    "ServiceRole",
    "Role for backend service",
    "123456789012",
    "us-west-2",
    Optional.empty(),
    Optional.of(options)
);

Getting Identity Metadata

String identityInfo = iamClient.getIdentity("MyRole", "123456789012", "us-west-2");

Deleting an Identity

iamClient.deleteIdentity("MyRole", "123456789012", "us-west-2");

Policy Operations

Building a Policy Document

A policy document is composed of one or more Statement objects. Each statement is built with Statement.builder() and added to the document with .statement(...). Actions are substrate-neutral Action values (use the pre-defined constants in StorageActions, ComputeActions, and IamActions, or Action.of("service:operation") for custom actions), and effects use the Effect enum.

PolicyDocument policy = PolicyDocument.builder()
    .version("2012-10-17")
    .statement(Statement.builder()
        .sid("StorageAccess")
        .effect(Effect.ALLOW)
        .action(StorageActions.GET_OBJECT)
        .action(StorageActions.PUT_OBJECT)
        .resource("storage://my-bucket/*")
        .condition(ConditionOperator.STRING_EQUALS, "aws:RequestedRegion", "us-west-2")
        .build())
    .build();

You can also create custom actions:

Statement statement = Statement.builder()
    .sid("CustomAccess")
    .effect(Effect.ALLOW)
    .action(Action.of("storage:GetObject"))
    .resource("storage://my-bucket/*")
    .build();

Attaching an Inline Policy

iamClient.attachInlinePolicy(AttachInlinePolicyRequest.builder()
    .policyDocument(policy)
    .tenantId("123456789012")
    .region("us-west-2")
    .identityName("MyRole")
    .build());

Listing Attached Policies

List<String> policyNames = iamClient.getAttachedPolicies(GetAttachedPoliciesRequest.builder()
    .identityName("MyRole")
    .tenantId("123456789012")
    .region("us-west-2")
    .build());
policyNames.forEach(name -> System.out.println("Policy: " + name));

Getting Inline Policy Details

String policyJson = iamClient.getInlinePolicyDetails(GetInlinePolicyDetailsRequest.builder()
    .identityName("MyRole")
    .policyName("StorageAccess")
    .tenantId("123456789012")
    .region("us-west-2")
    .build());

On GCP, set roleName instead of policyName (the role to inspect). See Provider-Specific Notes above.

Removing a Policy

iamClient.removePolicy("MyRole", "StorageAccess", "123456789012", "us-west-2");

Important: Parameter semantics (identityName, policyName, roleName, tenantId) differ by provider. See Provider-Specific Notes above.


Error Handling

Exception Handling

All IAM operations may throw SubstrateSdkException:

try {
    String identityId = iamClient.createIdentity("MyRole", "Description", "123456789012", "us-west-2",
        Optional.empty(), Optional.empty());
} catch (SubstrateSdkException e) {
    // Handle access denied, validation errors, etc.
    e.printStackTrace();
}