JamesWoolfenden / pike

Pike is a tool for determining the permissions or policy required for IAC code

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow pike to run against plan-file to get realistic IAM policy (not maximum)

antonbabenko opened this issue · comments

Is your feature request related to a problem? Please describe.

When running against terraform configs, pike does not take into account what resources will actually be created and suggest maximum policy.

Describe the solution you'd like

pike -plan-file plan.json scan-plan-file or something like that

Describe alternatives you've considered

Don't use pike. :)


Example 1

$ git clone https://github.com/terraform-aws-modules/terraform-aws-acm
$ cd examples/complete-dns-validation
$ pike -d . scan         
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "route53:CreateHostedZone",
                "route53:DeleteHostedZone",
                "route53:GetChange",
                "route53:GetHostedZone",
                "route53:ListHostedZones",
                "route53:ListResourceRecordSets",
                "route53:ListTagsForResource"
            ],
            "Resource": "*"
        }
    ]
}

It does not include acm:... statements because they are related by the module "acm" (sourced from ../../).


Example 2:

$ git clone https://github.com/terraform-aws-modules/terraform-aws-lambda
$ cd terraform-aws-lambda
$ pike -d . scan         
{
    "Version": "2012-10-17",
    "Statement": [
        # ... omitted
        {
            "Sid": "VisualEditor11",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:CreateSecret",
                "secretsmanager:DeleteSecret",
                "secretsmanager:DescribeSecret",
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:PutSecretValue"
            ],
            "Resource": "*"
        },
        # ... omitted
    ]
}

Q: Where does secretsmanager:... come from? It has been mentioned just in one of the examples (examples/event-source-mapping/main.tf)?

I am not sure these issues are connected, TBH :)

i was thinking of doing the plan file at some point soonalready. so great. I think you mean updating the policy with specific resources - you know you want to create a bucket called jimbo (from the plan) so the policy will only create and modify buckets called jimbo? that would be pretty cool.

Limiting value inside of Resource inside of the policy is one thing, but I was thinking about using pike that can make a policy depending on the actual resources that should be created.

User runs terraform plan -out=tfplan and converts tfplan into json. Then pass this json file to pike, and it returns a policy with statements for the required resources.

I have updated the description of an issue with more information and examples.

Ill check your examples but it should walk the modules with the -i flag (for init). Ive had a look at doing a plan version, howvever i was hoping to be able to figure out the resources/arns but its not quite that simple. There's no reason that any resource does support a name attribute and so not sure how to determine arns to restrict the perms. Open to ideas

I agree that plan has not enough information to generate a decent/restrictive policy. The only way to do it is to render/update the policy from the state file after resource creation.

Ive just released an update, there was an issue with init as terraform does not copy modules when they are local references, so any reference to ../../ or similar was missed unless you targeted the root- which also looked at all the examples. so now:

pike -d ../terraform-aws-modules/terraform-aws-lambda/examples/triggers scan
2022/09/07 13:39:00 aws_lambda_layer_version not implemented
2022/09/07 13:39:00 aws_lambda_provisioned_concurrency_config not implemented
2022/09/07 13:39:00 aws_lambda_function_event_invoke_config not implemented
2022/09/07 13:39:00 aws_lambda_event_source_mapping not implemented
2022/09/07 13:39:00 aws_lambda_function_url not implemented
2022/09/07 13:39:00 Provider external was not found
2022/09/07 13:39:00 aws_lambda_layer_version not implemented
2022/09/07 13:39:00 aws_lambda_provisioned_concurrency_config not implemented
2022/09/07 13:39:00 aws_lambda_function_event_invoke_config not implemented
2022/09/07 13:39:00 aws_lambda_event_source_mapping not implemented
2022/09/07 13:39:00 aws_lambda_function_url not implemented
2022/09/07 13:39:00 Provider external was not found
2022/09/07 13:39:00 Provider lambda was not found
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAccountAttributes"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "events:DeleteRule",
                "events:DescribeRule",
                "events:ListTagsForResource",
                "events:ListTargetsByRule",
                "events:PutRule",
                "events:PutTargets",
                "events:RemoveTargets"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:CreatePolicy",
                "iam:CreateRole",
                "iam:DeletePolicy",
                "iam:DeleteRole",
                "iam:DeleteRolePermissionsBoundary",
                "iam:DetachRolePolicy",
                "iam:GetPolicy",
                "iam:GetPolicyVersion",
                "iam:GetRole",
                "iam:ListAttachedRolePolicies",
                "iam:ListInstanceProfilesForRole",
                "iam:ListPolicies",
                "iam:ListPolicyVersions",
                "iam:ListRolePolicies",
                "iam:PassRole",
                "iam:PutRolePermissionsBoundary",
                "iam:TagPolicy",
                "iam:TagRole",
                "iam:UntagPolicy",
                "iam:UpdateRoleDescription"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "lambda:AddPermission",
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction",
                "lambda:GetFunctionCodeSigningConfig",
                "lambda:GetPolicy",
                "lambda:ListVersionsByFunction",
                "lambda:RemovePermission",
                "lambda:TagResource",
                "lambda:UntagResource"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "logs:AssociateKmsKey",
                "logs:CreateLogGroup",
                "logs:DeleteLogGroup",
                "logs:DeleteRetentionPolicy",
                "logs:DescribeLogGroups",
                "logs:DisassociateKmsKey",
                "logs:ListTagsLogGroup",
                "logs:PutRetentionPolicy",
                "logs:TagLogGroup",
                "logs:UntagLogGroup"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor5",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:PutObject"
            ],
            "Resource": "*"
        }
    ]
}

I still see previous behavior using v0.1.65 when I run "example 2" from my comment above.

I think that's because your examples folders use those resources and are being included. I can add an exclude parameter to ignore the examples? WDYT?

The root module does not include code from the examples, but examples use the code in the parent/root folder.

$ cd terraform-aws-lambda
$ pike -d . scan

# Should output policy without scanning any other folders not included in the terraform code natively. So, there should not be any `secretsmanager:...` in this case.

you can now exclude directories from the scan -x, in you case youll need to exclude modules and examples

Well, to my mind, this is wrong. I should not use -x to get valid permissions for the module.

Pike should behave exactly like Terraform, which does not go into directories unless it is instructed to do so (e.g. using terraform module sourced from local directories).

As a user, I don't know what exactly to exclude without looking into the source code of the module I am trying to get policy for.

Could you change pike to scan dirs as terraform?

So the default behaviour is not to recurse? Sure.

I think it's done now. No recursing. Make sense

v0.1.68 works correctly in the root module (where I have *.tf files), but it also works in the examples folder where I have no *.tf files, and thus IAM policy should not be possible to evaluate.

ok ill check that

ok, found and fixed i hope.

Yes, it works well now! Thank you for the work!

I found one more related bug: when terraform code has just module blocks, the policy is always empty.

$ git clone https://github.com/antonbabenko/serverless.tf-playground
$ cd nicconf
$ pike -d . -i scan
2022/09/07 21:45:24 terraform init at .
2022/09/07 21:45:24 Provider api was not found
2022/09/07 21:45:24 Provider dynamodb was not found
2022/09/07 21:45:24 Provider lambda was not found
2022/09/07 21:45:24 Provider lambda was not found
2022/09/07 21:45:24 No permissions found

fixed i hope. v0.1.70

fixed i hope. v0.1.70

No, it has another output but still doesn't work as expected.

$ git clone https://github.com/antonbabenko/serverless.tf-playground
$ cd nicconf
$ pike -d . -i scan
2022/09/08 12:31:02 terraform init at .
2022/09/08 12:31:02 read ../../cost.modules.tf: is a directory

i dont get that with the latest.

I still have it with the latest (pike -v => pike version v0.1.71).

The question is about cost.modules.tf directory as I mentioned in the previous comment. I have this directory, but it is outside the location I run pike at, and there are no references to it from the nicconf directory. Looks like there is an error with the directories pike should scan.

i ran the same here, ive fully reworked the path walk and i dont get it. could it be a dirty repo or a symbolic link?

pike version v0.1.79 seems to work as expected in the case which previously failed!

Great job, James!