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

Set only necessary permissions for node lambda functions #23

Closed
IvanVlasic opened this issue Sep 15, 2021 · 10 comments
Closed

Set only necessary permissions for node lambda functions #23

IvanVlasic opened this issue Sep 15, 2021 · 10 comments
Assignees
Labels
bug Something isn't working

Comments

@IvanVlasic
Copy link
Contributor

Currently in terraform all lambdas and roles have all permissions. We should probably narrow this down to only necessary permissions.

@ianic ianic changed the title Role permissions Set only necessary permissions for backend lambda functions Sep 15, 2021
@ianic ianic added this to the single developer milestone Sep 15, 2021
@ianic
Copy link
Member

ianic commented Oct 25, 2021

Ovo takodjer treba osigurati da backend iz jednog workspace nikako ne moze doci do stages koji su vezani za neki drugi workspace.

@ianic ianic added the bug Something isn't working label Oct 27, 2021
@IvanVlasic IvanVlasic self-assigned this Nov 4, 2021
@ianic
Copy link
Member

ianic commented Nov 4, 2021

Maknuti po kodu nagomilane:
// TODO permissions
zamjeniti ispravnim policy.

@ianic ianic changed the title Set only necessary permissions for backend lambda functions Set only necessary permissions for node lambda functions Nov 8, 2021
IvanVlasic pushed a commit that referenced this issue Nov 9, 2021
@IvanVlasic
Copy link
Contributor Author

Krenuo sam sa ws lambdama, implementacija je u gore navedenom commitu.

Na pocetku je potrebno napomenuti da nemaju svi servisi iste opcije permissiona. Npr za invokanje lambdi se ne moze dodati condition po tagovima, cijeli popis svih servisa i opcija je dostupan ovdje.

Permissione sam testirao rucno i preko iam policy simulatora.

Prva je ws_handler lambda koja dobiva requeste od API gatewaya i invoka projektne lambde.
IAM policy izgleda ovako:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:*:*:function:project-dev-*-ep3dmji"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "dynamodb:Query",
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:DescribeTable",
                "dynamodb:DeleteItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:BatchGetItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/project-dev-ws-connections-ep3dmji"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogStream"
            ],
            "Resource": "*"
        }
    ]
}

Lambdi dajem pravo da invoka lambde cije je ime template project-dev-*-ep3dmji sto ce biti samo lambde od tog jednog stagea, prava na dynamodb tablicu koja je kreirana unaprijed specificno za tu potrebu i prava za pisanje logova.

ws_forwarder lambda prima odgovore od projektnih lambdi i salje odgovor preko api gatewaya.
Prava izgledaju ovako:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "execute-api:ManageConnections",
            "Resource": "arn:aws:execute-api:*:*:56832zuocl/*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "dynamodb:Query",
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:DescribeTable",
                "dynamodb:DeleteItem",
                "dynamodb:BatchWriteItem",
                "dynamodb:BatchGetItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/project-dev-ws-connections-ep3dmji"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogStream"
            ],
            "Resource": "*"
        }
    ]
}

Tu se ponavljaju prava za dynamodb tablicu i logove, i dodatno je tu ManageConnections na ws api tog stagea koji lambdi omogucuje da salje odgovore klijentima.

IvanVlasic pushed a commit that referenced this issue Nov 9, 2021
@IvanVlasic
Copy link
Contributor Author

Sljedeca je CLI rola.

Njezina prava su:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::mantil-*-ep3dmji/*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:FilterLogEvents",
                "logs:DescribeLogStreams"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:resourceTag/MANTIL_KEY": [
                        "ep3dmji"
                    ],
                    "aws:resourceTag/MANTIL_WORKSPACE": [
                        "ivlasic"
                    ]
                }
            }
        }
    ]
}

Njoj dajem prava za pisanje u s3 buckete cije je ime teamplatea mantil-*-ep3dmji sto zadovoljava buckete svih projekata i stageova u nodu; glavni bucket u koji idu funkcije i public buckete u koji idu frontend asseti. PutObject ne podrzava tagove pa to nisam mogao rijesiti preko toga.

Za log grupe koristim tagove i dajem prava samo za one koji imaju key i workspace tag, sto ce ponovno biti sve log grupe tog nodea.

Dodatno ce se ovi permissioni jos vise suziti u security lambdi. Za s3 buckete cemo dodati specificna imena koja ce morati zadovoljavati gore navedeni template, a log grupe filtriramo po prefixu, no opet, sve grupe koje zadovoljavaju taj prefix ce ujedno morati i imati gore navedene tagove.

IvanVlasic pushed a commit that referenced this issue Nov 9, 2021
preparation for more granulated lambda permissions in #23
IvanVlasic pushed a commit that referenced this issue Nov 9, 2021
add separate module for node functions to encapsulate permissions for #23
IvanVlasic pushed a commit that referenced this issue Nov 10, 2021
@IvanVlasic
Copy link
Contributor Author

IvanVlasic commented Nov 10, 2021

Dodao sam permissione za security i authorizer lambdu.

Security ima samo permissione za logove i assume cli-role.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::216684349989:role/mantil-cli-user-pp773ii"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogStream"
            ],
            "Resource": "*"
        }
    ]
}

Authorizer ima permissione za logove:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

Ove preostale tri lambde - setup, deploy i destroy su se malo zakomplicirale jer se tu koristi jako puno permissiona pa gledam kako je najbolji nacin to posloziti.
Jedna stvar koju sam primjetio do sad je da cemo mozda morati poraditi na imenima stage lambdi. Conditioni za lamda permissione se mogu stavljati samo na ime, a nemamo neki template koji koristimo za imena lambdi u stageu koji se moze reusati kao npr za setup gdje imamo mantil-*-id pa s trenutnim imenima jedina opcija je dati prava svim lambdama, sto nije bas optimalno, @ianic

@ianic
Copy link
Member

ianic commented Nov 10, 2021

A *-id ne moze funkcionirati?

@IvanVlasic
Copy link
Contributor Author

Ah, glup sam. :D Svi projekti i stageovi ce imati isti node id, u pravu is. :)

IvanVlasic pushed a commit that referenced this issue Nov 11, 2021
@IvanVlasic
Copy link
Contributor Author

Prava za lambde koje koriste terraform su malo opsirnija i teze je doci do njih. Trebamo ukljuciti sve api pozive koje radi terraform. Tu sam si pomogao sa IAM access analyzerom i cloudtrailom koji logira sve akcije pa tamo mogu vidjeti kakve sve permissione koristi koja rola, no nije savrseno pa ima malo metode pokusaja i pogreske.

Za deploy lambdu ima malo vise permissiona, no to je jedini nacin da ne obuhvacamo stvari koje ne bi trebali.
Npr ne mogu staviti iam:* jer iam pored rola ima i druga prava poput usera i onda bi lambdi morao dati i prava na usere na aws accountu, sto nije prihvatljivo. Onda je jedina opcija imati ovako detaljnije granuliranje.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "apigateway:TagResource",
                "apigateway:PUT",
                "apigateway:POST",
                "apigateway:PATCH",
                "apigateway:GET",
                "apigateway:DELETE"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:UpdateLogDelivery",
                "logs:PutResourcePolicy",
                "logs:ListLogDeliveries",
                "logs:GetLogDelivery",
                "logs:DescribeResourcePolicies",
                "logs:DescribeLogGroups",
                "logs:CreateLogDelivery"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mantil-releases*/*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "lambda:UpdateFunctionConfiguration",
                "lambda:UpdateFunctionCode",
                "lambda:ListVersionsByFunction",
                "lambda:GetPolicy",
                "lambda:GetFunctionConfiguration",
                "lambda:GetFunctionCodeSigningConfig",
                "lambda:GetFunction",
                "lambda:CreateFunction",
                "lambda:AddPermission"
            ],
            "Resource": "arn:aws:lambda:*:*:function:*-n3isbby"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:PutRetentionPolicy",
                "logs:PutLogEvents",
                "logs:ListTagsLogGroup",
                "logs:CreateLogStream",
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:*-n3isbby:log-stream:*",
                "arn:aws:logs:*:*:log-group:*-n3isbby"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "iam:TagRole",
                "iam:PutRolePolicy",
                "iam:PassRole",
                "iam:ListRolePolicies",
                "iam:ListAttachedRolePolicies",
                "iam:GetRolePolicy",
                "iam:GetRole",
                "iam:CreateRole"
            ],
            "Resource": "arn:aws:iam::*:role/*-n3isbby"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutBucketWebsite",
                "s3:PutBucketTagging",
                "s3:PutBucketPolicy",
                "s3:PutBucketAcl",
                "s3:ListBucket",
                "s3:GetReplicationConfiguration",
                "s3:GetObject",
                "s3:GetLifecycleConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetBucketWebsite",
                "s3:GetBucketVersioning",
                "s3:GetBucketTagging",
                "s3:GetBucketRequestPayment",
                "s3:GetBucketPolicy",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetBucketLogging",
                "s3:GetBucketLocation",
                "s3:GetBucketCORS",
                "s3:GetAccelerateConfiguration",
                "s3:CreateBucket"
            ],
            "Resource": [
                "arn:aws:s3:::mantil-*-n3isbby/*",
                "arn:aws:s3:::mantil-*-n3isbby"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "dynamodb:TagResource",
                "dynamodb:ListTagsOfResource",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:CreateTable"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/*-n3isbby"
        }
    ]
}

IvanVlasic pushed a commit that referenced this issue Nov 11, 2021
@IvanVlasic
Copy link
Contributor Author

Permissionsi za destroy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "apigateway:PUT",
                "apigateway:POST",
                "apigateway:PATCH",
                "apigateway:GET",
                "apigateway:DELETE"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "lambda:RemovePermission",
                "lambda:ListVersionsByFunction",
                "lambda:GetPolicy",
                "lambda:GetFunctionCodeSigningConfig",
                "lambda:GetFunction",
                "lambda:DeleteFunction"
            ],
            "Resource": "arn:aws:lambda:*:*:function:*-nbiissi"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:ListTagsLogGroup",
                "logs:DeleteLogGroup",
                "logs:CreateLogStream"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:*-nbiissi:log-stream:*",
                "arn:aws:logs:*:*:log-group:*-nbiissi"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:ListLogDeliveries",
                "logs:DescribeLogGroups",
                "logs:DeleteLogDelivery"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "iam:ListRolePolicies",
                "iam:ListInstanceProfilesForRole",
                "iam:ListAttachedRolePolicies",
                "iam:GetRolePolicy",
                "iam:GetRole",
                "iam:DeleteRolePolicy",
                "iam:DeleteRole"
            ],
            "Resource": "arn:aws:iam::*:role/*-nbiissi"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:GetReplicationConfiguration",
                "s3:GetObject",
                "s3:GetLifecycleConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetBucketWebsite",
                "s3:GetBucketVersioning",
                "s3:GetBucketTagging",
                "s3:GetBucketRequestPayment",
                "s3:GetBucketPolicy",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetBucketLogging",
                "s3:GetBucketLocation",
                "s3:GetBucketCORS",
                "s3:GetAccelerateConfiguration",
                "s3:DeleteObjectVersion",
                "s3:DeleteObject",
                "s3:DeleteBucketPolicy",
                "s3:DeleteBucket"
            ],
            "Resource": [
                "arn:aws:s3:::mantil-*-nbiissi/*",
                "arn:aws:s3:::mantil-*-nbiissi"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "dynamodb:ListTagsOfResource",
                "dynamodb:DescribeTimeToLive",
                "dynamodb:DescribeTable",
                "dynamodb:DescribeContinuousBackups",
                "dynamodb:DeleteTable"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/*-nbiissi"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "tag:GetResources",
            "Resource": "*"
        }
    ]
}

IvanVlasic pushed a commit that referenced this issue Nov 11, 2021
IvanVlasic pushed a commit that referenced this issue Nov 11, 2021
@IvanVlasic
Copy link
Contributor Author

I evo na kraju i setup:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "apigateway:GET",
                "apigateway:POST",
                "apigateway:PATCH",
                "apigateway:DELETE",
                "apigateway:PUT",
                "apigateway:TagResource"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::mantil-releases*/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:CreateFunction",
                "lambda:AddPermission",
                "lambda:ListVersionsByFunction",
                "lambda:GetFunction",
                "lambda:GetFunctionCodeSigningConfig",
                "lambda:GetPolicy",
                "lambda:DeleteFunction",
                "lambda:RemovePermission",
                "lambda:GetLayerVersion"
            ],
            "Resource": [
                "arn:aws:lambda:*:*:function:mantil-*-zc2ucsa",
                "arn:aws:lambda:*:*:layer:*:*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:GetRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:GetRolePolicy",
                "iam:ListAttachedRolePolicies",
                "iam:CreateRole",
                "iam:ListRolePolicies",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:DeleteRole",
                "iam:ListInstanceProfilesForRole",
                "iam:TagRole",
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/mantil-*-zc2ucsa",
                "arn:aws:iam::*:role/APIGatewayPushToCloudWatchLogsRole"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:CreateBucket",
                "s3:PutBucketTagging",
                "s3:PutLifecycleConfiguration",
                "s3:DeleteBucket",
                "s3:ListBucket",
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:DeleteObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::mantil-*-zc2ucsa",
                "arn:aws:s3:::mantil-*-zc2ucsa/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DeleteLogGroup",
                "logs:ListTagsLogGroup"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:*-zc2ucsa",
                "arn:aws:logs:*:*:log-group:*-zc2ucsa:log-stream:*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "logs:PutResourcePolicy",
                "logs:DescribeResourcePolicies",
                "logs:PutRetentionPolicy",
                "logs:CreateLogGroup",
                "logs:DescribeLogGroups",
                "logs:GetLogDelivery",
                "logs:CreateLogDelivery",
                "logs:UpdateLogDelivery",
                "logs:ListLogDeliveries",
                "logs:DeleteLogDelivery"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ]
}

S time sam zavrsio sve lambde. Sad samo moramo pripaziti kada nesto mjenjamo da promjene uskladimo sa permissionima.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants