This module allows you to dynamically manage IAM group membership through an authenticated HTTPS endpoint.
This module is available on the Terraform Registry
API Gateway that performs authorization.
On-demand Lambda function (linked to API Gateway method POST|DELETE /membership
): to add/remove IAM group memberships on-demand
group_test.json
["user_test1", "user_test2"]
Continuous Lambda function: to clean up expired memberships
This is the Lambda function that runs add-user-to-group
and
remove-user-from-group
on-demand on the given IAM group.
Steps:
1. Authenticate the user via AWS IAM (Signature Version 4).
Eligibility to authenticate is set in a policy outside of this module.
The user will provide an AWS v4 signature for authentication.
Return **403** if not authorized.
3. If the request is a `POST /membership`
- The function will issue a `add-user-to-group` action for the user.
- An inline `fake-policy-[group_name]` is attached to user and used as a rule
that indicates the "time" that this membership was added.
- Return **200**.
4. If the request is a `DELETE /membership`
- If the user is in the IAM group, issue a `remove-user-from-group` on it
- If the user is not in the IAM group, do nothing
- Return **200**.
5. If any request has errors, e.g. a user / a group not found, internal API failed.
- Return **400** and error details
6. Return **500** for other errors
7. Done.
This is the Lambda function that runs remove-user-from-group
on the
given IAM group on user access expiry.
This AWS Lambda function runs every X seconds, and its sole task is to clean out the IAM group that has stale membership.
Steps:
1. The function will describe all rules in the given IAM group.
2. For every rule, it will check the time of last update.
- If the elapsed time is less than the configured X seconds, don't do anything.
- If the elapsed time is more than the configured X seconds, it means that the
rule has expired, and it should execute `revoke-iam-group` on it.
(e.g., if all rules are expired, the IAM group should now contain no rules)
3. Done.
Click to see complete example config
provider "aws" {
region = "us-west-2"
}
locals {
bucket_name = "example-dynamic-iam-groups-bucket",
iam_groups = ["group_test1.json", "group_test2.json"] // [group_name].json
}
resource "aws_s3_bucket" "this" {
bucket = "${local.bucket_name}"
acl = "private"
}
/* S3 files upload */
resource "aws_s3_bucket_object" "this" {
count = "${length(local.iam_groups)}"
bucket = "${aws_s3_bucket.this.bucket}"
key = "${element(local.iam_groups, count.index)}"
source = "${element(local.iam_groups, count.index)}"
}
/* module config */
module "dynamic-iamgroup" {
source = "../../"
name = "example-dynamic-iam-groups"
bucket_name = "${local.bucket_name}"
description = "example usage of terraform-aws-authenticating-iam"
time_to_expire = 300
log_level = "DEBUG"
}
resource "aws_iam_policy" "this" {
description = "Policy Developer IAM Access"
policy = "${data.aws_iam_policy_document.access_policy_doc.json}"
}
data "aws_iam_policy_document" "access_policy_doc" {
statement {
effect = "Allow"
actions = [
"execute-api:Invoke"
]
resources = [
"${module.dynamic-iamgroup.execution_resources}"]
}
}
/* outputs */
output "dynamic-iamgroup-api-invoke-url" {
value = "${module.dynamic-iamgroup.invoke_url}"
}
AWS IAM has certain limits that affect this module's operations, including:
Some works around:
Check out aws-authenticating-secgroup-scripts