# IAM Floyd: a typed fluent interface over the AWS IAM action catalogue

> IAM Floyd generates AWS IAM policy statements through a chainable API with a class per service and a method per action, resource type and condition key, published for TypeScript, JavaScript, Python, Java, C# and Go from one generated source. It suits a team that writes policies by hand and keeps mistyping action names, and its own documentation tells you to pin the version.

**udondan/iam-floyd** — AWS IAM policy statement generator with a fluent interface, for TypeScript, JavaScript, Python, Java, C# and Go.

- Repository: https://github.com/udondan/iam-floyd
- Website: https://iam-floyd.readthedocs.io/
- Stars: 571 · Forks: 20
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/udondan-iam-floyd

## The catalogue size, and what the fluent chain actually does

IAM Floyd is an AWS IAM policy statement generator with a fluent interface, and the numbers in the project documentation are the argument for it: support for 456 services, 22137 actions, 2332 resource types and 2502 condition keys.

The structure is uniform across that catalogue. There is a class for every AWS service, a method for every action, a method per resource type and a method per condition key. The example in the documentation is a complete statement in five chained calls:

```ts
import { Statement } from 'iam-floyd';

const statement = new Statement.Ec2()
  .allow()
  .toStartInstances()
  .toStopInstances()
  .ifResourceTag('Owner', '${aws:username}');
```

The chain reads in the order the policy is written, and each call returns the statement so the calls compose. The output is plain IAM policy JSON:

```json
{
  "Condition": {
    "StringLike": {
      "ec2:ResourceTag/Owner": "${aws:username}"
    }
  },
  "Action": ["ec2:StartInstances", "ec2:StopInstances"],
  "Resource": "*",
  "Effect": "Allow"
}
```

The specific benefit is named precisely in the documentation: your IDE completes the actions and shows their documentation, so you neither look up action names and ARN formats, nor deploy policies with typos. A policy is a security object, and a typo in an action name is either a permission that silently does not apply or, worse, a resource pattern that matches more than you meant.

The other thing this buys is discovery. An editor listing every action a service supports is how you find out that a permission you did not know existed is available, which is not something the AWS console makes easy.

## Access levels, regex matching and ARN construction

The feature list describes three things beyond the plain per-action methods, and each one removes a different kind of hand-written string.

Access levels let you add all the actions of a level, with methods such as allReadActions() and allWriteActions(). A read-only role for a service is then a single call rather than a list of thirty actions, and the list is maintained by the generator rather than by you.

Regular expressions do the same job with more control: allMatchingActions('/vpn/i') adds every action that matches a pattern, with the case-insensitive flag visible in the example. That is how you get a scoped set of actions for a family of features without reading the full catalogue by hand.

Resource construction is the third. ARNs are built with a method per resource type, for example onBucket('example-bucket'), with defaults for the partition, the region and the account. A hard-coded ARN in a policy has three places to get wrong, and a helper that fills in the account from configuration removes one of them, while the defaulting behaviour means a policy written once works across accounts, which matters in a multi-account setup where the same policy template is deployed into several regions.

Conditions are handled the same way, with a method per condition key and operators such as ForAnyValue:StringEquals or IfExists. The difference between ForAnyValue and ForAllValues decides whether a condition passes when one element of a set matches or only when all of them do, and getting that wrong is the kind of mistake that turns a restrictive condition into a permissive one without any error being raised. Naming the operator in the method call makes the choice visible in review.

## Two packages, one API, and the Node.js question

IAM Floyd comes in two variants, and the documentation is careful to say they have the same API and the same version number in every language.

The iam-floyd package creates statements as JSON, for the AWS SDKs, CloudFormation, Terraform or anything else that takes an IAM policy. The packages have no dependencies, and in Python, Java, C# and Go they are native and do not need Node.js.

The cdk-iam-floyd package creates statements of the AWS CDK v2. In Python, Java, C# and Go these are built with jsii, like the AWS CDK itself, and they need Node.js.

That single difference is the most consequential thing in the packaging. A Python team that has no Node.js toolchain can still use the plain package, but the moment they want the CDK variant they inherit a JavaScript build step. The plain package being dependency-free is also what makes it usable inside a Lambda bundle or a container image where adding a package manager step is a cost.

The cdk variant is not just a JSON generator with extra steps. Its statements are an iam.PolicyStatement of the AWS CDK, and the on* methods take constructs, for example onBucket(bucket) where bucket is a Bucket construct rather than a bucket name string. The type of the argument changes what the code can do, because a construct carries the region and the account it was created in.

The distribution table covers six targets for both packages: npm for TypeScript and JavaScript, PyPI for Python, Maven Central for Java, NuGet for .NET and Go modules for Go, and the project is also published to the Construct Hub as cdk-iam-floyd.

The install commands are one per ecosystem:

```bash
# TypeScript / JavaScript
npm install iam-floyd           # or cdk-iam-floyd

# Python
pip install iam-floyd           # or cdk-iam-floyd
```

with the Java, .NET and Go equivalents given in the same block. The version warning sits right underneath: IAM Floyd has not reached 1.0.0 yet, and the API can still change between releases, so pin the exact version.

## The parts that go beyond statement building

Four features in the list are not about a single statement, and they are the ones a team that has been burned by IAM limits will care about.

Policies are the first. A policy document that knows the maximum size of its type, validates its estimated size and splits itself into several policies. IAM has hard size limits per policy and per role, and exceeding them is a deployment failure that appears at the worst possible moment. A library that estimates the size before you deploy and splits the document is turning a runtime error into a build-time one.

Collections are the second: collections of common statements, and the names of all AWS managed policies. Managed policies are the AWS-authored ones, and knowing their exact names matters because a role that attaches a managed policy is granting a fixed set of permissions that changes under AWS's control, so being able to reference the name precisely rather than from memory is useful.

The policy converter is the third: it turns an existing JSON policy into IAM Floyd code, and there is an online converter for it. That is the migration path. The realistic way this library gets adopted is not a greenfield rewrite, it is taking a policy that exists as JSON, running it through the converter, and getting a typed version of it that a reviewer can read.

The fourth is the documentation, which explains all features with examples in every language, and a demo recording of the auto completion, which is the feature that has to be seen rather than described.

The repository structure backs all of this up. There are language directories for python/, java/, dotnet/, go/ and cdk/, a lib/ directory holding the generator and the generated models, an examples/ directory with a large set of focused cases, from access-levels-list and actions-matching through arn-defaults-override and conditions-operator-if-exists, a skills/ directory, and a Makefile whose LANGUAGES variable defaults to typescript python java dotnet go, with separate targets for the jsii packages and for the transpiled native ones.

## How it is generated, and how often

The library is generated code, and the repository says so plainly: the service models and the code generated from them are derived from the AWS documentation, and the class and function names and their descriptions are therefore the property of AWS. The project also states that it is not affiliated with, funded by, or in any way associated with AWS, and that AWS and its services are trademarks.

That legal framing explains the architecture. There is no hand-maintained list of 22137 actions, because that would be unmaintainable and would drift from AWS within weeks. Instead, the generate script in the package metadata, npx ts-node bin/generate.ts, produces the classes from a source, and the documentation states that the library is complete, generated from the AWS documentation and updated every week. There is a separate step to index the managed policies and another to index the service principals, the latter of which the Makefile notes needs AWS credentials and must run after the managed policy index.

The versioning follows from that. The recent releases are v0.850.0 from 2026-10-05, v0.849.0 from 2026-10-04 and v0.848.0 from 2026-10-04, so a version is cut when the weekly regeneration changes something, and the numbers in the 0.8xx range are a running count of the generation cycles. The last push to the repository was on 2026-10-19.

The package metadata marks the stability as experimental, which is a formal statement of what the pre-1.0 warning says in prose. The tooling around it is thorough for a project of this shape: release-please for the version and changelog, Renovate for dependency updates, Trivy with a trivy.yaml and a .trivyignore for vulnerability scanning, ruff for the Python side, eslint for the TypeScript side, and separate tsconfig files for the main build, the types, the lint and each CDK test suite.

The licence is Apache 2.0, with the note that dependencies might be released under different licences.

## Where IAM Floyd is the wrong tool

The first limit is that it is pre-1.0 and explicitly experimental, and the documentation says the API can still change between releases and tells you to pin the exact version. A weekly regeneration plus a moving API means your dependency needs deliberate updating, and a team that does not want to review IAM library bumps should think twice.

The second is that the value depends on you writing policies in code. A team that grants permissions in the AWS console, or that maintains a small number of hand-written JSON policies, gets very little from a fluent interface. The library earns its keep where there are many policies, many services and many engineers, which is exactly the situation it targets and also exactly the situation where a policy is being reviewed by people who do not read the underlying JSON anyway.

The third is the cost of the CDK variant in a non-JavaScript shop. The plain packages have no dependencies and are native in Python, Java, C# and Go, but the CDK packages are built with jsii and need Node.js. In a Python-only organisation that means adding a Node.js toolchain to the build for the CDK integration, which is a real cost for a convenience feature.

The fourth is the size of the generated surface. 22137 action methods and 2332 resource types is a large API surface, and while the editor only shows what is relevant, the shipped package is big, the type definitions are large, and a TypeScript project that compiles the whole thing pays for it in build time. The iam-floyd package having no runtime dependencies does not mean it has no footprint.

The fifth is that it does not make policies correct. It makes them well-formed and it makes their action names checkable, which removes a class of mistake, but the difference between a policy that allows what you meant and a policy that allows more than you meant is still a decision somebody has to make. A library that generates the string does not generate the intent, and the conditions that make a statement narrow are the part the fluent syntax cannot infer.

And the sixth is the pipeline dependency on AWS. The models come from AWS documentation and are refreshed weekly, which means the library's contents track a third party that changes without notice. When an action is added, your pinned version does not have it, which is exactly why the documentation tells you to pin and to update deliberately.

## Conclusion

IAM Floyd is worth adopting if your team writes IAM policies in code rather than in a console, because the method names are the action names, so a renamed or misspelled action fails at compile time instead of at deploy time, and because the resource and condition helpers remove the ARN string arithmetic that is where policy bugs usually hide. It is the wrong tool if you author policies in the AWS console or in raw JSON by hand, and it is the wrong tool if you want a stable API contract. Before you adopt it, check three things: that the version you pin has the action you need, since the library has not reached 1.0.0, the package metadata marks it as experimental, and the documentation says the API can still change between releases, and it is regenerated from the AWS service reference every week; that you pick the right package, since cdk-iam-floyd produces AWS CDK v2 PolicyStatement objects through jsii and needs Node.js at build time while the plain iam-floyd package has no dependencies; and that you read the legal note, because the class and function names are derived from the AWS documentation and are stated to be the property of AWS.

## FAQ

### How do I install IAM Floyd?

Use npm install iam-floyd for TypeScript and JavaScript, pip install iam-floyd for Python, dotnet add package IAM.Floyd for .NET, and go get udondan.github.io/iam-floyd/go/iamfloyd for Go, with the cdk-iam-floyd variants available in each ecosystem. The plain packages have no dependencies and do not need Node.js outside TypeScript, while the CDK variants are built with jsii and do need Node.js.

### How do I add all read or write actions for a service in IAM Floyd?

The access level methods do it, for example allReadActions() or allWriteActions() on a service statement, and allMatchingActions('/vpn/i') adds every action matching a regular expression. The catalogue is generated from the AWS documentation and covers 456 services, 22137 actions, 2332 resource types and 2502 condition keys.

### Is IAM Floyd safe to depend on in production?

The project states that it has not reached 1.0.0 yet, that the API can still change between releases and that you should pin the exact version, and the package metadata marks the stability as experimental. The library is regenerated from the AWS documentation every week, so an action added by AWS appears in a later release rather than in the one you have pinned.

## Sources

- [License: Apache-2.0](https://github.com/udondan/iam-floyd/blob/main/LICENSE)
- [Project website](https://iam-floyd.readthedocs.io/)
- [README](https://github.com/udondan/iam-floyd/blob/main/README.md)
- [Releases](https://github.com/udondan/iam-floyd/releases)
- [udondan/iam-floyd on GitHub](https://github.com/udondan/iam-floyd)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/udondan-iam-floyd
