get Principal Policy Simulation
Runs a simulation of the IAM policies of a particular principal against a given hypothetical request. You can use this data source in conjunction with Preconditions and Postconditions so that your configuration can test either whether it should have sufficient access to do its own work, or whether policies your configuration declares itself are sufficient for their intended use elsewhere.
Note: Correctly using this data source requires familiarity with various details of AWS Identity and Access Management, and how various AWS services integrate with it. For general information on the AWS IAM policy simulator, see Testing IAM policies with the IAM policy simulator. This data source wraps the
iam:SimulatePrincipalPolicy
API action described on that page.
Example Usage
Self Access-checking Example
The following example raises an error if the credentials passed to the AWS provider do not have access to perform the three actions s3:GetObject
, s3:PutObject
, and s3:DeleteObject
on the S3 bucket with the given ARN.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getCallerIdentity({});
const s3ObjectAccess = current.then(current => aws.iam.getPrincipalPolicySimulation({
actionNames: [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
],
policySourceArn: current.arn,
resourceArns: ["arn:aws:s3:::my-test-bucket"],
}));
import pulumi
import pulumi_aws as aws
current = aws.get_caller_identity()
s3_object_access = aws.iam.get_principal_policy_simulation(action_names=[
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
],
policy_source_arn=current.arn,
resource_arns=["arn:aws:s3:::my-test-bucket"])
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetCallerIdentity.Invoke();
var s3ObjectAccess = Aws.Iam.GetPrincipalPolicySimulation.Invoke(new()
{
ActionNames = new[]
{
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
},
PolicySourceArn = current.Apply(getCallerIdentityResult => getCallerIdentityResult.Arn),
ResourceArns = new[]
{
"arn:aws:s3:::my-test-bucket",
},
});
});
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
if err != nil {
return err
}
_, err = iam.LookupPrincipalPolicySimulation(ctx, &iam.LookupPrincipalPolicySimulationArgs{
ActionNames: []string{
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
},
PolicySourceArn: current.Arn,
ResourceArns: []string{
"arn:aws:s3:::my-test-bucket",
},
}, nil)
if err != nil {
return err
}
return nil
})
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPrincipalPolicySimulationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var current = AwsFunctions.getCallerIdentity();
final var s3ObjectAccess = IamFunctions.getPrincipalPolicySimulation(GetPrincipalPolicySimulationArgs.builder()
.actionNames(
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject")
.policySourceArn(current.applyValue(getCallerIdentityResult -> getCallerIdentityResult.arn()))
.resourceArns("arn:aws:s3:::my-test-bucket")
.build());
}
}
variables:
current:
fn::invoke:
function: aws:getCallerIdentity
arguments: {}
s3ObjectAccess:
fn::invoke:
function: aws:iam:getPrincipalPolicySimulation
arguments:
actionNames:
- s3:GetObject
- s3:PutObject
- s3:DeleteObject
policySourceArn: ${current.arn}
resourceArns:
- arn:aws:s3:::my-test-bucket
If you intend to use this data source to quickly raise an error when the given credentials are insufficient then you must use depends_on
inside any resource which would require those credentials, to ensure that the policy check will run first:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.BucketObject("example", {bucket: "my-test-bucket"}, {
dependsOn: [s3ObjectAccess],
});
import pulumi
import pulumi_aws as aws
example = aws.s3.BucketObject("example", bucket="my-test-bucket",
opts = pulumi.ResourceOptions(depends_on=[s3_object_access]))
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.S3.BucketObject("example", new()
{
Bucket = "my-test-bucket",
}, new CustomResourceOptions
{
DependsOn =
{
s3ObjectAccess,
},
});
});
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := s3.NewBucketObject(ctx, "example", &s3.BucketObjectArgs{
Bucket: pulumi.Any("my-test-bucket"),
}, pulumi.DependsOn([]pulumi.Resource{
s3ObjectAccess,
}))
if err != nil {
return err
}
return nil
})
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.BucketObject;
import com.pulumi.aws.s3.BucketObjectArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new BucketObject("example", BucketObjectArgs.builder()
.bucket("my-test-bucket")
.build(), CustomResourceOptions.builder()
.dependsOn(s3ObjectAccess)
.build());
}
}
resources:
example:
type: aws:s3:BucketObject
properties:
bucket: my-test-bucket
options:
dependsOn:
- ${s3ObjectAccess}
Testing the Effect of a Declared Policy
The following example declares an S3 bucket and a user that should have access to the bucket, and then uses aws.iam.getPrincipalPolicySimulation
to verify that the user does indeed have access to perform needed operations against the bucket.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getCallerIdentity({});
const example = new aws.iam.User("example", {name: "example"});
const exampleBucketV2 = new aws.s3.BucketV2("example", {bucket: "my-test-bucket"});
const s3Access = new aws.iam.UserPolicy("s3_access", {
name: "example_s3_access",
user: example.name,
policy: pulumi.jsonStringify({
Version: "2012-10-17",
Statement: [{
Action: "s3:GetObject",
Effect: "Allow",
Resource: exampleBucketV2.arn,
}],
}),
});
const accountAccess = new aws.s3.BucketPolicy("account_access", {
bucket: exampleBucketV2.bucket,
policy: pulumi.jsonStringify({
Version: "2012-10-17",
Statement: [{
Action: "s3:*",
Effect: "Allow",
Principal: {
AWS: current.then(current => current.accountId),
},
Resource: [
exampleBucketV2.arn,
pulumi.interpolate`${exampleBucketV2.arn}/*`,
],
}],
}),
});
const s3ObjectAccess = aws.iam.getPrincipalPolicySimulationOutput({
actionNames: ["s3:GetObject"],
policySourceArn: example.arn,
resourceArns: [exampleBucketV2.arn],
resourcePolicyJson: accountAccess.policy,
});
import pulumi
import json
import pulumi_aws as aws
current = aws.get_caller_identity()
example = aws.iam.User("example", name="example")
example_bucket_v2 = aws.s3.BucketV2("example", bucket="my-test-bucket")
s3_access = aws.iam.UserPolicy("s3_access",
name="example_s3_access",
user=example.name,
policy=pulumi.Output.json_dumps({
"Version": "2012-10-17",
"Statement": [{
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": example_bucket_v2.arn,
}],
}))
account_access = aws.s3.BucketPolicy("account_access",
bucket=example_bucket_v2.bucket,
policy=pulumi.Output.json_dumps({
"Version": "2012-10-17",
"Statement": [{
"Action": "s3:*",
"Effect": "Allow",
"Principal": {
"AWS": current.account_id,
},
"Resource": [
example_bucket_v2.arn,
example_bucket_v2.arn.apply(lambda arn: f"{arn}/*"),
],
}],
}))
s3_object_access = aws.iam.get_principal_policy_simulation_output(action_names=["s3:GetObject"],
policy_source_arn=example.arn,
resource_arns=[example_bucket_v2.arn],
resource_policy_json=account_access.policy)
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetCallerIdentity.Invoke();
var example = new Aws.Iam.User("example", new()
{
Name = "example",
});
var exampleBucketV2 = new Aws.S3.BucketV2("example", new()
{
Bucket = "my-test-bucket",
});
var s3Access = new Aws.Iam.UserPolicy("s3_access", new()
{
Name = "example_s3_access",
User = example.Name,
Policy = Output.JsonSerialize(Output.Create(new Dictionary<string, object?>
{
["Version"] = "2012-10-17",
["Statement"] = new[]
{
new Dictionary<string, object?>
{
["Action"] = "s3:GetObject",
["Effect"] = "Allow",
["Resource"] = exampleBucketV2.Arn,
},
},
})),
});
var accountAccess = new Aws.S3.BucketPolicy("account_access", new()
{
Bucket = exampleBucketV2.Bucket,
Policy = Output.JsonSerialize(Output.Create(new Dictionary<string, object?>
{
["Version"] = "2012-10-17",
["Statement"] = new[]
{
new Dictionary<string, object?>
{
["Action"] = "s3:*",
["Effect"] = "Allow",
["Principal"] = new Dictionary<string, object?>
{
["AWS"] = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
},
["Resource"] = new[]
{
exampleBucketV2.Arn,
exampleBucketV2.Arn.Apply(arn => $"{arn}/*"),
},
},
},
})),
});
var s3ObjectAccess = Aws.Iam.GetPrincipalPolicySimulation.Invoke(new()
{
ActionNames = new[]
{
"s3:GetObject",
},
PolicySourceArn = example.Arn,
ResourceArns = new[]
{
exampleBucketV2.Arn,
},
ResourcePolicyJson = accountAccess.Policy,
});
});
package main
import (
"encoding/json"
"fmt"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
if err != nil {
return err
}
example, err := iam.NewUser(ctx, "example", &iam.UserArgs{
Name: pulumi.String("example"),
})
if err != nil {
return err
}
exampleBucketV2, err := s3.NewBucketV2(ctx, "example", &s3.BucketV2Args{
Bucket: pulumi.String("my-test-bucket"),
})
if err != nil {
return err
}
_, err = iam.NewUserPolicy(ctx, "s3_access", &iam.UserPolicyArgs{
Name: pulumi.String("example_s3_access"),
User: example.Name,
Policy: exampleBucketV2.Arn.ApplyT(func(arn string) (pulumi.String, error) {
var _zero pulumi.String
tmpJSON0, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
map[string]interface{}{
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": arn,
},
},
})
if err != nil {
return _zero, err
}
json0 := string(tmpJSON0)
return pulumi.String(json0), nil
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
accountAccess, err := s3.NewBucketPolicy(ctx, "account_access", &s3.BucketPolicyArgs{
Bucket: exampleBucketV2.Bucket,
Policy: pulumi.All(exampleBucketV2.Arn, exampleBucketV2.Arn).ApplyT(func(_args []interface{}) (string, error) {
exampleBucketV2Arn := _args[0].(string)
exampleBucketV2Arn1 := _args[1].(string)
var _zero string
tmpJSON1, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
map[string]interface{}{
"Action": "s3:*",
"Effect": "Allow",
"Principal": map[string]interface{}{
"AWS": current.AccountId,
},
"Resource": []string{
exampleBucketV2Arn,
fmt.Sprintf("%v/*", exampleBucketV2Arn1),
},
},
},
})
if err != nil {
return _zero, err
}
json1 := string(tmpJSON1)
return json1, nil
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
_ = iam.LookupPrincipalPolicySimulationOutput(ctx, iam.GetPrincipalPolicySimulationOutputArgs{
ActionNames: pulumi.StringArray{
pulumi.String("s3:GetObject"),
},
PolicySourceArn: example.Arn,
ResourceArns: pulumi.StringArray{
exampleBucketV2.Arn,
},
ResourcePolicyJson: accountAccess.Policy,
}, nil)
return nil
})
}
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.iam.User;
import com.pulumi.aws.iam.UserArgs;
import com.pulumi.aws.s3.BucketV2;
import com.pulumi.aws.s3.BucketV2Args;
import com.pulumi.aws.iam.UserPolicy;
import com.pulumi.aws.iam.UserPolicyArgs;
import com.pulumi.aws.s3.BucketPolicy;
import com.pulumi.aws.s3.BucketPolicyArgs;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPrincipalPolicySimulationArgs;
import static com.pulumi.codegen.internal.Serialization.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var current = AwsFunctions.getCallerIdentity();
var example = new User("example", UserArgs.builder()
.name("example")
.build());
var exampleBucketV2 = new BucketV2("exampleBucketV2", BucketV2Args.builder()
.bucket("my-test-bucket")
.build());
var s3Access = new UserPolicy("s3Access", UserPolicyArgs.builder()
.name("example_s3_access")
.user(example.name())
.policy(exampleBucketV2.arn().applyValue(arn -> serializeJson(
jsonObject(
jsonProperty("Version", "2012-10-17"),
jsonProperty("Statement", jsonArray(jsonObject(
jsonProperty("Action", "s3:GetObject"),
jsonProperty("Effect", "Allow"),
jsonProperty("Resource", arn)
)))
))))
.build());
var accountAccess = new BucketPolicy("accountAccess", BucketPolicyArgs.builder()
.bucket(exampleBucketV2.bucket())
.policy(Output.tuple(exampleBucketV2.arn(), exampleBucketV2.arn()).applyValue(values -> {
var exampleBucketV2Arn = values.t1;
var exampleBucketV2Arn1 = values.t2;
return serializeJson(
jsonObject(
jsonProperty("Version", "2012-10-17"),
jsonProperty("Statement", jsonArray(jsonObject(
jsonProperty("Action", "s3:*"),
jsonProperty("Effect", "Allow"),
jsonProperty("Principal", jsonObject(
jsonProperty("AWS", current.applyValue(getCallerIdentityResult -> getCallerIdentityResult.accountId()))
)),
jsonProperty("Resource", jsonArray(
exampleBucketV2Arn,
String.format("%s/*", exampleBucketV2Arn1)
))
)))
));
}))
.build());
final var s3ObjectAccess = IamFunctions.getPrincipalPolicySimulation(GetPrincipalPolicySimulationArgs.builder()
.actionNames("s3:GetObject")
.policySourceArn(example.arn())
.resourceArns(exampleBucketV2.arn())
.resourcePolicyJson(accountAccess.policy())
.build());
}
}
resources:
example:
type: aws:iam:User
properties:
name: example
exampleBucketV2:
type: aws:s3:BucketV2
name: example
properties:
bucket: my-test-bucket
s3Access:
type: aws:iam:UserPolicy
name: s3_access
properties:
name: example_s3_access
user: ${example.name}
policy:
fn::toJSON:
Version: 2012-10-17
Statement:
- Action: s3:GetObject
Effect: Allow
Resource: ${exampleBucketV2.arn}
accountAccess:
type: aws:s3:BucketPolicy
name: account_access
properties:
bucket: ${exampleBucketV2.bucket}
policy:
fn::toJSON:
Version: 2012-10-17
Statement:
- Action: s3:*
Effect: Allow
Principal:
AWS: ${current.accountId}
Resource:
- ${exampleBucketV2.arn}
- ${exampleBucketV2.arn}/*
variables:
current:
fn::invoke:
function: aws:getCallerIdentity
arguments: {}
s3ObjectAccess:
fn::invoke:
function: aws:iam:getPrincipalPolicySimulation
arguments:
actionNames:
- s3:GetObject
policySourceArn: ${example.arn}
resourceArns:
- ${exampleBucketV2.arn}
resourcePolicyJson: ${accountAccess.policy}
When using aws.iam.getPrincipalPolicySimulation
to test the effect of a policy declared elsewhere in the same configuration, it's important to use depends_on
to make sure that the needed policy has been fully created or updated before running the simulation.
Return
A collection of values returned by getPrincipalPolicySimulation. //////
Parameters
A collection of arguments for invoking getPrincipalPolicySimulation.
Return
A collection of values returned by getPrincipalPolicySimulation.
Parameters
A set of IAM action names to run simulations for. Each entry in this set adds an additional hypothetical request to the simulation. Action names consist of a service prefix and an action verb separated by a colon, such as s3:GetObject
. Refer to Actions, resources, and condition keys for AWS services to see the full set of possible IAM action names across all AWS services.
A set of additional principal policy documents to include in the simulation. The simulator will behave as if each of these policies were associated with the object specified in policy_source_arn
, allowing you to test the effect of hypothetical policies not yet created.
The ARN of an user that will appear as the "caller" of the simulated requests. If you do not specify caller_arn
then the simulation will use the policy_source_arn
instead, if it contains a user ARN.
Each context
block defines an entry in the table of additional context keys in the simulated request. IAM uses context keys for both custom conditions and for interpolating dynamic request-specific values into policy values. If you use policies that include those features then you will need to provide suitable example values for those keys to achieve a realistic simulation.
A set of permissions boundary policy documents to include in the simulation.
The ARN of the IAM user, group, or role whose policies will be included in the simulation. You must closely match the form of the real service request you are simulating in order to achieve a realistic result. You can use the following additional arguments to specify other characteristics of the simulated requests:
A set of ARNs of resources to include in the simulation. This argument is important for actions that have either required or optional resource types listed in Actions, resources, and condition keys for AWS services, and you must provide ARNs that identify AWS objects of the appropriate types for the chosen actions. The policy simulator only automatically loads policies associated with the policy_source_arn
, so if your given resources have their own resource-level policy then you'll also need to provide that explicitly using the resource_policy_json
argument to achieve a realistic simulation.
Specifies a special simulation type to run. Some EC2 actions require special simulation behaviors and a particular set of resource ARNs to achieve a realistic result. For more details, see the ResourceHandlingOption
request parameter for the underlying iam:SimulatePrincipalPolicy
action.
An AWS account ID to use for any resource ARN in resource_arns
that doesn't include its own AWS account ID. If unspecified, the simulator will use the account ID from the caller_arn
argument as a placeholder.
An IAM policy document representing the resource-level policy of all of the resources specified in resource_arns
. The policy simulator cannot automatically load policies that are associated with individual resources, as described in the documentation for resource_arns
above.
See also
Return
A collection of values returned by getPrincipalPolicySimulation.
Parameters
Builder for com.pulumi.aws.iam.kotlin.inputs.GetPrincipalPolicySimulationPlainArgs.