/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package software.amazon.awssdk.policybuilder.iam; import java.util.Collection; import java.util.List; import java.util.function.Consumer; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.annotations.ThreadSafe; import software.amazon.awssdk.policybuilder.iam.internal.DefaultIamPolicy; import software.amazon.awssdk.utils.builder.CopyableBuilder; import software.amazon.awssdk.utils.builder.ToCopyableBuilder; /** * An AWS access control policy is a object that acts as a container for one or * more statements, which specify fine grained rules for allowing or denying * various types of actions from being performed on your AWS resources. *

* By default, all requests to use your resource coming from anyone but you are * denied. Access control polices can override that by allowing different types * of access to your resources, or by explicitly denying different types of * access. *

* Each statement in an AWS access control policy takes the form: * "A has permission to do B to C where D applies". *

*

* For more information, see The IAM User Guide * *

Usage Examples

* Create a new IAM identity policy that allows a role to write items to an Amazon DynamoDB table. * {@snippet : * // IamClient requires a dependency on software.amazon.awssdk:iam * try (IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build()) { * IamPolicy policy = * IamPolicy.builder() * .addStatement(IamStatement.builder() * .effect(IamEffect.ALLOW) * .addAction("dynamodb:PutItem") * .addResource("arn:aws:dynamodb:us-east-2:123456789012:table/books") * .build()) * .build(); * iam.createPolicy(r -> r.policyName("AllowWriteBookMetadata") * .policyDocument(policy.toJson())); * } * } * *

* Download the policy uploaded in the previous example and create a new policy with "read" access added to it. * {@snippet : * // IamClient requires a dependency on software.amazon.awssdk:iam * try (IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build()) { * String policyArn = "arn:aws:iam::123456789012:policy/AllowWriteBookMetadata"; * GetPolicyResponse getPolicyResponse = iam.getPolicy(r -> r.policyArn(policyArn)); * * String policyVersion = getPolicyResponse.defaultVersionId(); * GetPolicyVersionResponse getPolicyVersionResponse = * iam.getPolicyVersion(r -> r.policyArn(policyArn).versionId(policyVersion)); * * IamPolicy policy = IamPolicy.fromJson(getPolicyVersionResponse.policyVersion().document()); * * IamStatement newStatement = policy.statements().get(0).copy(s -> s.addAction("dynamodb:GetItem")); * IamPolicy newPolicy = policy.copy(p -> p.statements(Arrays.asList(newStatement))); * * iam.createPolicy(r -> r.policyName("AllowReadWriteBookMetadata") * .policyDocument(newPolicy.toJson())); * } * } * * @see IamPolicyReader * @see IamPolicyWriter * @see IamStatement * @see IAM User Guide */ @SdkPublicApi @ThreadSafe public interface IamPolicy extends ToCopyableBuilder { /** * Create an {@code IamPolicy} from an IAM policy in JSON form. *

* This will raise an exception if the provided JSON is invalid or does not appear to represent a valid policy document. *

* This is equivalent to {@code IamPolicyReader.create().read(json)}. */ static IamPolicy fromJson(String json) { return IamPolicyReader.create().read(json); } /** * Create an {@code IamPolicy} containing the provided statements. *

* At least one statement is required. *

* This is equivalent to {@code IamPolicy.builder().statements(statements).build()} */ static IamPolicy create(Collection statements) { return builder().statements(statements).build(); } /** * Create a {@link Builder} for an {@code IamPolicy}. */ static Builder builder() { return DefaultIamPolicy.builder(); } /** * Retrieve the value set by {@link Builder#id(String)}. */ String id(); /** * Retrieve the value set by {@link Builder#version(String)}. */ String version(); /** * Retrieve the value set by {@link Builder#statements(Collection)}. */ List statements(); /** * Convert this policy to the JSON format that is accepted by AWS services. *

* This is equivalent to {@code IamPolicyWriter.create().writeToString(policy)} *

* {@snippet : * IamPolicy policy = * IamPolicy.builder() * .addStatement(IamStatement.builder() * .effect(IamEffect.ALLOW) * .addAction("dynamodb:PutItem") * .addResource("arn:aws:dynamodb:us-east-2:123456789012:table/books") * .build()) * .build(); * System.out.println("Policy:\n" + policy.toJson()); * } */ String toJson(); /** * Convert this policy to the JSON format that is accepted by AWS services, using the provided writer. *

* This is equivalent to {@code writer.writeToString(policy)} *

* {@snippet : * IamPolicyWriter prettyWriter = * IamPolicyWriter.builder() * .prettyPrint(true) * .build(); * IamPolicy policy = * IamPolicy.builder() * .addStatement(IamStatement.builder() * .effect(IamEffect.ALLOW) * .addAction("dynamodb:PutItem") * .addResource("arn:aws:dynamodb:us-east-2:123456789012:table/books") * .build()) * .build(); * System.out.println("Policy:\n" + policy.toJson(prettyWriter)); * } */ String toJson(IamPolicyWriter writer); /** * @see #builder() */ interface Builder extends CopyableBuilder { /** * Configure the {@code * Id} element of the policy, specifying an optional identifier for the policy. *

* The ID is used differently in different services. ID is allowed in resource-based policies, but not in * identity-based policies. *

* For services that let you set an ID element, we recommend you use a UUID (GUID) for the value, or incorporate a UUID * as part of the ID to ensure uniqueness. *

* This value is optional. *

* {@snippet : * IamPolicy policy = * IamPolicy.builder() * .id("cd3ad3d9-2776-4ef1-a904-4c229d1642ee") // An identifier for the policy * .addStatement(IamStatement.builder() * .effect(IamEffect.DENY) * .addAction(IamAction.ALL) * .build()) * .build(); *} * * @see ID user guide */ Builder id(String id); /** * Configure the * {@code Version} * element of the policy, specifying the language syntax rules that are to be used to * process the policy. *

* By default, this value is {@code 2012-10-17}. *

* {@snippet : * IamPolicy policy = * IamPolicy.builder() * .version("2012-10-17") // The IAM policy language syntax version to use * .addStatement(IamStatement.builder() * .effect(IamEffect.DENY) * .addAction(IamAction.ALL) * .build()) * .build(); * } * * @see Version * user guide */ Builder version(String version); /** * Configure the * {@code * Statement} element of the policy, specifying the access rules for this policy. *

* This will replace any other statements already added to the policy. At least one statement is required to * create a policy. *

* {@snippet : * IamPolicy policy = * IamPolicy.builder() * // Add a statement to this policy that denies all actions: * .statements(Arrays.asList(IamStatement.builder() * .effect(IamEffect.DENY) * .addAction(IamAction.ALL) * .build())) * .build(); * } * @see * Statement user guide */ Builder statements(Collection statements); /** * Append a * {@code * Statement} element to this policy to specify additional access rules. *

* At least one statement is required to create a policy. *

* {@snippet : * IamPolicy policy = * IamPolicy.builder() * // Add a statement to this policy that denies all actions: * .addStatement(IamStatement.builder() * .effect(IamEffect.DENY) * .addAction(IamAction.ALL) * .build()) * .build(); * } * @see * Statement user guide */ Builder addStatement(IamStatement statement); /** * Append a * {@code * Statement} element to this policy to specify additional access rules. *

* This works the same as {@link #addStatement(IamStatement)}, except you do not need to specify {@code IamStatement * .builder()} or {@code build()}. At least one statement is required to create a policy. *

* {@snippet : * IamPolicy policy = * IamPolicy.builder() * // Add a statement to this policy that denies all actions: * .addStatement(s -> s.effect(IamEffect.DENY) * .addAction(IamAction.ALL)) * .build(); * } * @see * Statement user guide */ Builder addStatement(Consumer statement); } }