thinkinglabs / aws-iam-policy

A TypeScript Node.js module to manipulate AWS IAM Policy documents
MIT License
17 stars 2 forks source link
aws iam-policy javascript nodejs typescript

aws-iam-policy Build Status

A Node.js package for working with AWS IAM Policy documents.

The primary reasons for creating the library were:

Requirements

Node.js lts/gallium (16.x)

Features

Documentation

Install the package.

npm install --save-dev @thinkinglabs/aws-iam-policy

Create a policy document.

import * as iam from '@thinkinglabs/aws-iam-policy';

function kmsKeyPolicy(accountId: string, keyAdminArns: string[], keyUserArns: string[]) {
  return new iam.PolicyDocument([
    new iam.Statement({
      sid: 'Enable IAM User Permissions',
      effect: 'Allow',
      principals: [new iam.RootAccountPrincipal(accountId)],
      actions: ['kms:*'],
      resources: ['*'],
    }),
    new iam.Statement({
      sid: 'Allow access for Key Administrators',
      effect: 'Allow',
      principals: keyAdminArns.map((arn) => new iam.ArnPrincipal(arn)),
      actions: ['kms:*'],
      resources: ['*'],
    }),
    new iam.Statement({
      sid: 'Allow use of the key',
      effect: 'Allow',
      principals: keyUserArns.map((arn) => new iam.ArnPrincipal(arn)),
      actions: [
        'kms:Encrypt',
        'kms:Decrypt',
        'kms:ReEncrypt*',
        'kms:GenerateDataKey*',
        'kms:DescribeKey',
      ],
      resources: ['*'],
    }),
  ]).json;
});

Add a Statement to an existing policy document.

const policy = new iam.PolicyDocument();
policy.addStatements(new iam.Statement({
    sid: 'Enable IAM User Permissions',
    effect: 'Allow',
    principals: [new iam.RootAccountPrincipal(accountId)],
    actions: ['kms:*'],
    resources: ['*'],
  });

Unit testing a statement from a policy document. You can retrieve a single statement using the Sid of that statement.

import {expect} from 'chai';
import * as iam from '@thinkinglabs/aws-iam-policy';

describe('kms key policy', function() {
const accountId = '123456789012';
  const keyAdminArns = [
    `arn:aws:iam::${accountId}:role/admin1`,
    `arn:aws:iam::${accountId}:role/admin2`,
  ];
  const keyUsers = [
    `arn:aws:iam::${accountId}:role/user1`,
  ];
  const policy = sut.kmsKeyPolicy(accountId, keyAdminArns, keyUserArns);

  it('should enable IAM User permissions', function() {
    const statement = policy.getStatement('Enable IAM User Permissions');

    expect(statement).to.deep.equal(new iam.Statement({
      actions: ['kms:*'],
      effect: 'Allow',
      principals: [new iam.RootAccountPrincipal('123456789012')],
      resources: ['*'],
      sid: 'Enable IAM User Permissions',
    }));
  });
}

Serialising to and from JSON.

  const policy = new iam.PolicyDocument();
  const json = policy.json;
  const newPolicy = iam.PolicyDocument.fromJson(json);

Supports different principals.

  // "Principal": {"Service": ["ec2.amazonaws.com"]}
  const servicePrincipal = new iam.ServicePrincipal('ec2.amazonaws.com');

  // "Principal": {"AWS": ["arn:aws:iam::123456789012:user/a/path/user-name"]}
  const userPrincipal = new iam.UserPrincipal('123456789012', 'user-name', '/a/path/')

    // "Principal": {"AWS": ["arn:aws:iam::123456789012:role/a/path/role-name"]}
  const rolePrincipal = new iam.RolePrincipal('123456789012', 'role-name', '/a/path/')

  // "Principal": {"AWS": ["arn:aws:iam::123456789012:role/role-name"]}
  const arnPrincipal = new iam.ArnPrincipal('arn:aws:iam::123456789012:role/role-name');

  // "Principal": {"AWS": ["arn:aws:iam::123456789012:root"]}
  const rootAccountPrincipal = new iam.RootAccountPrincipal('123456789012');

  // "Principal": {"AWS": ["123456789012"]}
  const accountPrincipal = new iam.AccountPrincipal('123456789012');

  // "Principal": {"AWS": ["*"]}
  const anonymousUserPrincipal = new iam.AnonymousUserPrincipal();

  // "Principal" : "*"
  const wildcardPrincipal = new iam.WildcardPrincipal();

Validate a policy document.

  // validate any policy
  // when valid returns an empty list
  // when invalid returns a list of errors
  const errors = policy.validate();
  if (errors) {
    throw errors;
  }

  // validate an IAM policy document
  const errors = policy.validate(PolicyType.IAM);
  if (errors) {
    throw errors;
  }

  //validate a KMS key policy document.
  const errors = policy.validate(PolicyType.KMS);
  if (errors) {
    throw errors;
  }

  //validate an S3 bucket policy document.
  const errors = policy.validate(PolicyType.S3);
  if (errors) {
    throw errors;
  }

  //validate a SecretsManager secret policy document.
  const errors = policy.validate(PolicyType.SecretsManager);
  if (errors) {
    throw errors;
  }