Learn LocalStack - IAM & Authentication
Episode 14 of 23

Learn LocalStack - IAM & Authentication

Why the fake test/test credentials are accepted without question, how basic IAM policy evaluation works in LocalStack, the use of resource-based policies, and the IAM emulation limitations you must know about.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In the previous episode 13 we pointed SDKs and the CLI at http://localhost:4566 via endpoint injection and awslocal. But one question still nags: the AWS CLI always demands credentials, yet LocalStack never refuses. How does authentication actually work in the emulator? This episode answers that: the fake test/test credentials, the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY variables, how LocalStack evaluates IAM policies, resource-based policies, and the emulation limitations you need to know before carrying production assumptions into your local environment.

Fake Credentials: Why test/test Is Accepted

LocalStack's default does not verify credentials. All access key and secret key combinations are accepted, as long as the format is valid. This is deliberate, so production SDKs and CLIs run without modifications beyond the endpoint URL. The most common pair is test/test with region us-east-1 — exactly what awslocal uses automatically.

We can prove it with the AWS CLI pointed at the emulator:

Verifikasi identitas
aws --endpoint-url=http://localhost:4566 sts get-caller-identity

LocalStack responds with the default account identity 000000000000:

Output get-caller-identity
{
    "UserId": "AKIAIOSFODNN7EXAMPLE",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:root"
}

Again: LocalStack doesn't check whether AKIAIOSFODNN7EXAMPLE really belongs to you. Account 000000000000 is the default account used by all local resources.

Setting Credentials via Environment Variables

For SDKs and the CLI, the cleanest way is environment variables:

Set kredensial lokal
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
export AWS_ENDPOINT_URL=http://localhost:4566

After this, any production code runs as-is — no line changes beyond the endpoint.

Connecting SDKs with Fake Credentials

boto3 (Python) uses the env vars above without needing explicit credentials:

Pythonboto3 ke LocalStack
import boto3
 
s3 = boto3.client(
    "s3",
    region_name="us-east-1",
    endpoint_url="http://localhost:4566",
    aws_access_key_id="test",
    aws_secret_access_key="test",
)
print(s3.list_buckets())

Note: aws_access_key_id="test" is just a formality value. The same value is accepted in other SDKs (aws-sdk-js, aws-sdk-go) too.

Tip

Keep these fake credentials in a .env that's versioned, not in a secret store. Since LocalStack doesn't verify them, they're safe to share among developers — this is precisely their main advantage over real credentials.

Basic IAM Policy Evaluation

LocalStack mimics an allow-by-default model: as long as no policy denies, access is permitted. But LocalStack can still evaluate policies attached to users, groups, and roles. Let's try: create a user, attach a read-only S3 policy, then inspect.

Buat user dan attach policy
awslocal iam create-user --user-name dev
awslocal iam attach-user-policy \
  --user-name dev \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
awslocal iam list-attached-user-policies --user-name dev

We can also create a custom policy with a JSON document and attach it:

policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": ["s3:GetObject"],
            "Resource": ["arn:aws:s3:::assets/*"]
        }
    ]
}

The policy above is stored via awslocal iam create-policy then attached to the dev user. As a result, an s3:PutObject operation not listed can be denied in some services — this is the basis of authorization emulation in LocalStack.

Resource-Based Policies

Besides identity-based policies, AWS also has resource-based policies attached to resources — most commonly on S3 buckets. LocalStack evaluates them in a limited way. Here's an example bucket policy granting s3:GetObject access to the dev user:

bucket-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::000000000000:user/dev"},
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::assets/*"
        }
    ]
}

Apply it with the following commands:

Pasang bucket policy
awslocal s3 mb s3://assets
awslocal s3api put-bucket-policy \
  --bucket assets --policy file://bucket-policy.json

IAM Emulation Limitations

It's important to know what is not simulated. Don't put your security trust in the emulator:

IAM AspectStatus in LocalStackNotes
Credential validationNot checkedAll credentials are accepted
Policy evaluationPartialHighly dependent on the service
Deny precedenceLimitedAllow-by-default logic dominates
STS assume-roleMockSessions created without real session policies
SCP & OrganizationsNot supportedNo organization-level policies
KMS key policyPartialOnly certain services

The implication: use IAM emulation to test your code flow, not to test security. Real authorization must still be verified on a real AWS account in staging or a production-like environment.

Warning

Never treat LocalStack policy evaluation results as proof of safety. Because it's allow-by-default, access that should be denied can slip through the emulator and then be rejected on real AWS — or the other way around.

Closing

This episode opened LocalStack's authentication black box:

  • LocalStack doesn't verify credentials; test/test with region us-east-1 is the default you can freely use.
  • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY just need to be pointed via env vars, and the endpoint via AWS_ENDPOINT_URL.
  • Basic IAM policy evaluation and resource-based policies work, but on an allow-by-default model.
  • IAM emulation is for testing code flow, not for proving security.

Now that credentials and policies are understood, the next question is the security of the environment itself: where to store data, how to isolate state between developers, and how to treat PERSISTENCE. In the next episode 15 we discuss Security & Best Practice — principles for using LocalStack comfortably without creating production risks. See you there!

Learn LocalStack - IAM & Authentication | Learn LocalStack