Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When running iamlive with terraform apply generated policy document is incomplete #51

Open
marcofranssen opened this issue May 12, 2022 · 19 comments

Comments

@marcofranssen
Copy link
Contributor

marcofranssen commented May 12, 2022

I have noticed that some permissions are not captured in the policydocument.

An example is that my terraform creates a kms key

iamlive is then only capturing the

"kms:CreateKey"

but not "kms:CreateGrant"

This goes for more actions that should have been captured in the policy.

E.g. when creating an eks cluster

    "eks:TagResource",
    "iam:TagOpenIDConnectProvider",
	"ec2:RunInstances",
    "acm:AddTagsToCertificate",
    "acm:DeleteCertificate",
    "acm:DescribeCertificate",
    "acm:GetCertificate",
    "acm:ListTagsForCertificate",

And a few more which I forgot about.

@marcofranssen
Copy link
Contributor Author

marcofranssen commented May 13, 2022

Run it again and got following policy. See the below diff for the actions I had to add myself. I hope this can help in resolving the issue.

diff --git a/iamlive.json b/files/default-example-policy.json
index 4e3ffe0..234f5d6 100644
--- a/iamlive.json
+++ b/files/default-example-policy.json
@@ -4,8 +4,10 @@
     {
       "Effect": "Allow",
       "Action": [
+        "acm:AddTagsToCertificate",
         "acm:DeleteCertificate",
         "acm:DescribeCertificate",
+        "acm:GetCertificate",
         "acm:ListTagsForCertificate",
         "acm:RequestCertificate",
         "ec2:AllocateAddress",
@@ -20,7 +22,13 @@
         "ec2:CreateTags",
         "ec2:CreateVpc",
         "ec2:DeleteInternetGateway",
+        "ec2:DeleteLaunchTemplate",
+        "ec2:DeleteNatGateway",
+        "ec2:DeleteRoute",
+        "ec2:DeleteRouteTable",
         "ec2:DeleteSubnet",
+        "ec2:DeleteTags",
+        "ec2:DeleteVpc",
         "ec2:DescribeAccountAttributes",
         "ec2:DescribeAddresses",
         "ec2:DescribeAvailabilityZones",
@@ -39,16 +47,23 @@
         "ec2:DescribeVpcClassicLinkDnsSupport",
         "ec2:DescribeVpcs",
         "ec2:DetachInternetGateway",
+        "ec2:DisassociateRouteTable",
+        "ec2:DisassociateRouteTable",
         "ec2:ModifySubnetAttribute",
         "ec2:ModifyVpcAttribute",
         "ec2:ReleaseAddress",
+        "ec2:RunInstances",
         "eks:CreateAddon",
         "eks:CreateCluster",
         "eks:CreateNodegroup",
+        "eks:DeleteAddon",
+        "eks:DeleteCluster",
+        "eks:DeleteNodegroup",
         "eks:DescribeAddon",
         "eks:DescribeAddonVersions",
         "eks:DescribeCluster",
         "eks:DescribeNodegroup",
+        "eks:TagResource",
         "iam:AddRoleToInstanceProfile",
         "iam:AttachRolePolicy",
         "iam:CreateInstanceProfile",
@@ -57,8 +72,10 @@
         "iam:CreateRole",
         "iam:CreateServiceLinkedRole",
         "iam:DeleteInstanceProfile",
+        "iam:DeleteOpenIDConnectProvider",
         "iam:DeletePolicy",
         "iam:DeleteRole",
+        "iam:DeleteRolePolicy",
         "iam:DetachRolePolicy",
         "iam:GetInstanceProfile",
         "iam:GetOpenIDConnectProvider",
@@ -74,15 +91,21 @@
         "iam:PutRolePolicy",
         "iam:RemoveRoleFromInstanceProfile",
         "iam:TagInstanceProfile",
+        "iam:TagOpenIDConnectProvider",
+        "iam:TagPolicy",
+        "iam:TagRole",
         "kms:CreateKey",
+        "kms:CreateGrant",
         "kms:DescribeKey",
         "kms:EnableKeyRotation",
         "kms:GetKeyPolicy",
         "kms:GetKeyRotationStatus",
         "kms:ListResourceTags",
         "kms:PutKeyPolicy",
+        "kms:ScheduleKeyDeletion",
         "kms:TagResource",
         "logs:CreateLogGroup",
+        "logs:DeleteLogGroup",
         "logs:DescribeLogGroups",
         "logs:ListTagsLogGroup",
         "logs:PutRetentionPolicy",
@@ -92,7 +115,8 @@
         "route53:ListHostedZones",
         "route53:ListResourceRecordSets",
         "route53:ListTagsForResource",
         "ssm:GetParameter"
       ],
       "Resource": "*"
     }

@iann0036
Copy link
Owner

Hi @marcofranssen,

Thanks for raising!

Would it be possible to get a sanitized copy of the Terraform files you are using to generate the policy? This will help me narrow down the actual API calls being used, and the difference when called.

@timblaktu
Copy link

@marcofranssen do you have any update on this issue? Has this misbehavior been reproducible and consistent using your setup?

Also, what is your setup, i.e. how are you running iamlive, what "client" is it monitoring, and how exactly are you controlling/starting/stopping the monitoring process?

@marcofranssen
Copy link
Contributor Author

marcofranssen commented Aug 29, 2022

Yes it is still relevant. It happens when running Terraform. We are using the following modules in our setup:

As well we are using a bunch of AWS provider resources like things for KMS and Route53 and ACM.

We have been running the client on local in a different terminal. Killing it minutes after the terraform apply using ctrl+c. As well we have been running it in GitHub action workflows using https://github.com/marcofranssen/setup-iamlive.

Still need to find the time to isolate a reproducible example in a Gist, as currently I can't share the proprietary setup.

🤞 hopefully this info already helps.

@cedricbastin
Copy link

Maybe it makes sense for the policies to change when running 'terraform apply' multiple times, sometimes terraform only created new resources, sometimes it has to destroy old ones before recreating them.

@OttawaCloudConsulting
Copy link

I wanted to add the experience that we are seeing with this.
We run IAMLive as part of our code review to generate a pipeline deployment policy.
Using a simple terraform module to generate SNS Topics, it would appear that certain calls are not captured by IAMLive.

Terraform

resource "aws_sns_topic" "this" {
    name = var.topic_name
}

resource "aws_sns_topic_policy" "email" {
  count = var.protocol == "email" ? 0 : 1
  arn    = aws_sns_topic.this.arn
  policy = data.aws_iam_policy_document.email.json
}


resource "aws_sns_topic_subscription" "this" {
 
  for_each  = toset(var.endpoint)
  topic_arn = aws_sns_topic.this.arn
  protocol  = var.protocol
  endpoint  = each.key
}

Terraform Trace Logs for permissions failed

"sts:GetCallerIdentity"

{
  "@caller": "github.com/hashicorp/aws-sdk-go-base/v2@v2.0.0-beta.24/logging/logger.go:41",
  "@level": "debug",
  "@message": "HTTP Request Sent",
  "@module": "aws.aws-base",
  "@timestamp": "2023-03-09T13:35:15.983972Z",
  "aws.operation": "GetCallerIdentity",
  "aws.region": "ca-central-1",
  "aws.sdk": "aws-sdk-go-v2",
  "aws.service": "STS",
  "http.method": "POST",
  "http.request.body": "Action=GetCallerIdentity&Version=2011-06-15",
  "http.request.header.amz_sdk_invocation_id": "dd9a9657-a53a-45f8-a37e-9151eb61d600",
  "http.request.header.amz_sdk_request": "attempt=1; max=25",
  "http.request.header.authorization": "AWS4-HMAC-SHA256 Credential=[redacted]/20230309/ca-central-1/sts/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;content-length;content-type;host;x-amz-date;x-amz-security-token, Signature=*****",
  "http.request.header.content_type": "application/x-www-form-urlencoded",
  "http.request.header.x_amz_date": "20230309T133515Z",
  "http.request.header.x_amz_security_token": "*****",
  "http.request_content_length": 43,
  "http.url": "https://sts.ca-central-1.amazonaws.com/",
  "http.user_agent": "APN/1.0 HashiCorp/1.0 Terraform/1.3.9 (+https://www.terraform.io) terraform-provider-aws/4.57.1 (+https://registry.terraform.io/providers/hashicorp/aws) aws-sdk-go-v2/1.17.5 os/linux lang/go/1.19.3 md/GOOS/linux md/GOARCH/amd64 api/sts/1.18.5",
  "net.peer.name": "sts.ca-central-1.amazonaws.com",
  "tf_mux_provider": "*schema.GRPCProviderServer",
  "tf_provider_addr": "registry.terraform.io/hashicorp/aws",
  "tf_req_id": "63391968-8f93-c975-60c9-63cf63f108d0",
  "tf_rpc": "ConfigureProvider",
  "timestamp": "2023-03-09T13:35:15.983Z"
}

"sns:DeleteTopic"

{
  "@caller": "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2@v2.0.0-beta.25/logger.go:90",
  "@level": "debug",
  "@message": "HTTP Request Sent",
  "@module": "aws",
  "@timestamp": "2023-03-09T13:35:38.630935Z",
  "aws.operation": "DeleteTopic",
  "aws.region": "ca-central-1",
  "aws.sdk": "aws-sdk-go",
  "aws.service": "SNS",
  "http.flavor": "1.1",
  "http.method": "POST",
  "http.request.body": "Action=DeleteTopic&TopicArn=arn%3Aaws%3Asns%3Aca-central-1%[redacted]-developers-approvals-email&Version=2010-03-31",
  "http.request.header.authorization": "AWS4-HMAC-SHA256 Credential=[redacted]/20230309/ca-central-1/sns/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token, Signature=*****",
  "http.request.header.content_type": "application/x-www-form-urlencoded; charset=utf-8",
  "http.request.header.x_amz_date": "20230309T133538Z",
  "http.request.header.x_amz_security_token": "*****",
  "http.request_content_length": 126,
  "http.url": "https://sns.ca-central-1.amazonaws.com/",
  "http.user_agent": "APN/1.0 HashiCorp/1.0 Terraform/1.3.9 (+https://www.terraform.io) terraform-provider-aws/4.57.1 (+https://registry.terraform.io/providers/hashicorp/aws) aws-sdk-go/1.44.214 (go1.19.3; linux; amd64)",
  "net.peer.name": "sns.ca-central-1.amazonaws.com",
  "tf_mux_provider": "*schema.GRPCProviderServer",
  "tf_provider_addr": "registry.terraform.io/hashicorp/aws",
  "tf_req_id": "56c1a4fa-eee8-2c6f-caa7-c9712a5dd689",
  "tf_resource_type": "aws_sns_topic",
  "tf_rpc": "ApplyResourceChange",
  "timestamp": "2023-03-09T13:35:38.630Z"
}

Neither of these two permissions appear, despite Terraform performing a clean 'destroy' on the resources.

@iann0036
Copy link
Owner

Hi @OttawaCloudConsulting,

Apologies for the delayed response. I wasn't able to replicate your issue whilst running in proxy mode for the sns.DeleteTopic issue.

For sts:GetCallerIdentity, the omission of a permission is intentional, as this permission is implied and never actually required (i.e. a permission-less principal has authority to perform this call).

@s1dn3y
Copy link

s1dn3y commented Feb 14, 2024

Facing similar issue here, like the one reported by @marcofranssen. I'm using terraform to create a very simple AWS Lambda Function (for teaching purpose). IAMLIVE prints out only some IAM related policies, but no lambda's related.

terraform:

terraform {
  backend "http" {}
}

provider "aws" {
  region  = "sa-east-1"
}

resource "aws_iam_role" "lambda_role" {
  assume_role_policy = <<-EOF
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Principal": {
          "Service": "lambda.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": ""
      }
    ]
  }
  EOF
}

resource "aws_iam_policy" "iam_policy_for_lambda" {
  path         = "/"
  policy = <<-EOF
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ],
        "Resource": "arn:aws:logs:*:*:*",
        "Effect": "Allow"
      }
    ]
  }
  EOF
}
 
resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role" {
  role        = aws_iam_role.lambda_role.name
  policy_arn  = aws_iam_policy.iam_policy_for_lambda.arn
}

data "local_file" "lambda_processar_contatos" {
  filename = "${path.module}/../../lambda-processar-contatos.zip"
}

resource "aws_lambda_function" "lambda_processar_contatos" {
  function_name    = "lambda-processar-contatos"
  handler          = "main.lambda_handler"
  runtime          = "python3.11"
  filename         = data.local_file.lambda_processar_contatos.filename
  source_code_hash = data.local_file.lambda_processar_contatos.content_base64sha256
  timeout          = 3
  memory_size      = 128
  role             = aws_iam_role.lambda_role.arn
}

printed out policies:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:GetPolicy",
                "iam:GetRole",
                "iam:GetPolicyVersion",
                "iam:ListRolePolicies",
                "iam:ListAttachedRolePolicies",
                "iam:AttachRolePolicy"
            ],
            "Resource": "*"
        }
    ]
}

@iann0036
Copy link
Owner

Hey @s1dn3y,

Do you happen to know if the Lambda call is actually logged if you run iamlive with --debug?

@s1dn3y
Copy link

s1dn3y commented Feb 14, 2024

I forgot to mention iamlive's version: iamlive-v1.1.6-linux-amd64

@s1dn3y
Copy link

s1dn3y commented Feb 14, 2024

yes, the call is logged, and the lambda is effectively created on aws.

@iann0036
Copy link
Owner

iann0036 commented Feb 14, 2024

Oh, are you targeting non-AWS endpoints? Like LocalStack or something?

The proxy is configured to only look for AWS endpoints currently.

I personally can't replicate:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:ListFunctions",
                "sts:GetCallerIdentity"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreatePolicy",
                "iam:GetPolicy",
                "iam:GetPolicyVersion"
            ],
            "Resource": "arn:aws:iam::-:policy/terraform-20240214022957358800000001"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:GetRole",
                "iam:ListRolePolicies",
                "iam:PassRole",
                "iam:AttachRolePolicy"
            ],
            "Resource": "arn:aws:iam::-:role/terraform-20240214022957358800000002"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:ListAttachedRolePolicies"
            ],
            "Resource": "arn:aws:iam::-:role//terraform-20240214022957358800000002"
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction"
            ],
            "Resource": "arn:aws:lambda:sa-east-1:-:function:lambda-processar-contatos"
        }
    ]
}

@s1dn3y
Copy link

s1dn3y commented Feb 15, 2024

Yes, I am. I'll repeat the process saving state locally. Then I update the results. Thanks

@iann0036
Copy link
Owner

Oh okay. I think the proxy isn't configured to intercept Localstack endpoints. Relates to #50

@s1dn3y
Copy link

s1dn3y commented Feb 16, 2024

It worked. Thanks @iann0036, for the help and for the nice tool

@iann0036
Copy link
Owner

Hey @s1dn3y,

Thanks for the update.

Could you confirm what changed / worked for you? Did you happen to use the custom build in the other issue or did you directly target the AWS endpoints or something different?

@s1dn3y
Copy link

s1dn3y commented Feb 17, 2024

I just ran iamlive on proxy mode and did a "pre execution" of terraform's cycle (init, plan, apply and destroy), storing the state locally. Then I got the printed policy and applied it to the AWS user used on CI/CD pipeline. Also restored the config to save terraform state on backend. The captured policies had a minor problem: one occurence of an ARN was printed with a double slash (I dont know why, because all other occurences of the same ARN were printed correctly), causing an access error at CI/CD's execution. I fixed the wrong generated ARN and everything went well.

UPDATE

image

iann0036 added a commit to iann0036/iam-dataset that referenced this issue Feb 17, 2024
@iann0036
Copy link
Owner

Hi @s1dn3y,

Thanks for the update. I've added a fix for the double / issue which should be in version 1.1.7.

@iann0036
Copy link
Owner

Hey @s1dn3y,

A little bit more tweaking was needed. Check version 1.1.8 for a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants