Skip to content

Latest commit

 

History

History
566 lines (507 loc) · 11.5 KB

File metadata and controls

566 lines (507 loc) · 11.5 KB

🔐 IAM Policies & Security Configuration

Required IAM Permissions

The FinOps system requires specific IAM permissions to function properly. This document outlines the minimal required permissions following the principle of least privilege.

Scanner Lambda Permissions

Core Scanning Permissions

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EC2ResourceScanning",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeVolumes",
        "ec2:DescribeInstances",
        "ec2:DescribeSnapshots",
        "ec2:DescribeNetworkInterfaces",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeRegions",
        "ec2:DescribeAvailabilityZones"
      ],
      "Resource": "*"
    },
    {
      "Sid": "RDSResourceScanning",
      "Effect": "Allow",
      "Action": [
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        "rds:DescribeDBSnapshots",
        "rds:ListTagsForResource"
      ],
      "Resource": "*"
    },
    {
      "Sid": "CloudWatchMetricsAccess",
      "Effect": "Allow",
      "Action": [
        "cloudwatch:GetMetricStatistics",
        "cloudwatch:GetMetricData",
        "cloudwatch:ListMetrics"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DynamoDBAccess",
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutItem",
        "dynamodb:UpdateItem",
        "dynamodb:BatchWriteItem"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:*:table/finops-cleanup-*",
        "arn:aws:dynamodb:*:*:table/finops-cleanup-*/index/*"
      ]
    },
    {
      "Sid": "SNSNotifications",
      "Effect": "Allow",
      "Action": ["sns:Publish"],
      "Resource": ["arn:aws:sns:*:*:finops-*"]
    }
  ]
}

Analysis Lambda Permissions

Stream Processing & Updates

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DynamoDBStreamAccess",
      "Effect": "Allow",
      "Action": [
        "dynamodb:DescribeStream",
        "dynamodb:GetRecords",
        "dynamodb:GetShardIterator",
        "dynamodb:ListStreams"
      ],
      "Resource": ["arn:aws:dynamodb:*:*:table/finops-cleanup-*/stream/*"]
    },
    {
      "Sid": "DynamoDBTableUpdates",
      "Effect": "Allow",
      "Action": ["dynamodb:UpdateItem", "dynamodb:PutItem", "dynamodb:GetItem"],
      "Resource": ["arn:aws:dynamodb:*:*:table/finops-cleanup-*"]
    },
    {
      "Sid": "SNSAlertPublishing",
      "Effect": "Allow",
      "Action": ["sns:Publish"],
      "Resource": ["arn:aws:sns:*:*:finops-*"]
    }
  ]
}

API Lambda Permissions

Dashboard & Cleanup Operations

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DynamoDBReadAccess",
      "Effect": "Allow",
      "Action": [
        "dynamodb:Scan",
        "dynamodb:Query",
        "dynamodb:GetItem",
        "dynamodb:BatchGetItem"
      ],
      "Resource": [
        "arn:aws:dynamodb:*:*:table/finops-cleanup-*",
        "arn:aws:dynamodb:*:*:table/finops-cleanup-*/index/*"
      ]
    },
    {
      "Sid": "DynamoDBWriteAccess",
      "Effect": "Allow",
      "Action": ["dynamodb:UpdateItem", "dynamodb:DeleteItem"],
      "Resource": ["arn:aws:dynamodb:*:*:table/finops-cleanup-*"]
    },
    {
      "Sid": "ResourceCleanupPermissions",
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteVolume",
        "ec2:TerminateInstances",
        "ec2:DeleteSnapshot",
        "ec2:DeleteNetworkInterface",
        "ec2:DeleteSecurityGroup",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "rds:DeleteDBInstance",
        "rds:DeleteDBCluster",
        "rds:CreateDBSnapshot",
        "rds:AddTagsToResource"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": ["us-east-1", "us-west-2"]
        }
      }
    },
    {
      "Sid": "ResourceTaggingPermissions",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateTags",
        "ec2:DeleteTags",
        "rds:AddTagsToResource",
        "rds:RemoveTagsFromResource"
      ],
      "Resource": "*"
    }
  ]
}

Production Security Enhancements

Resource-Based Conditions

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PreventProtectedResourceDeletion",
      "Effect": "Deny",
      "Action": [
        "ec2:DeleteVolume",
        "ec2:TerminateInstances",
        "rds:DeleteDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/finops:protect": "true"
        }
      }
    },
    {
      "Sid": "RequireReasonForDeletion",
      "Effect": "Deny",
      "Action": ["ec2:DeleteVolume", "ec2:TerminateInstances"],
      "Resource": "*",
      "Condition": {
        "Null": {
          "aws:RequestTag/finops:deletion-reason": "true"
        }
      }
    }
  ]
}

Time-Based Access Control

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BusinessHoursCleanupOnly",
      "Effect": "Deny",
      "Action": [
        "ec2:DeleteVolume",
        "ec2:TerminateInstances",
        "rds:DeleteDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "DateGreaterThan": {
          "aws:CurrentTime": "18:00Z"
        },
        "DateLessThan": {
          "aws:CurrentTime": "08:00Z"
        }
      }
    }
  ]
}

Multi-Account Setup

Cross-Account Scanner Role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CrossAccountAssumeRole",
      "Effect": "Allow",
      "Action": ["sts:AssumeRole"],
      "Resource": [
        "arn:aws:iam::ACCOUNT-1:role/FinOpsScanner",
        "arn:aws:iam::ACCOUNT-2:role/FinOpsScanner",
        "arn:aws:iam::ACCOUNT-3:role/FinOpsScanner"
      ]
    }
  ]
}

Target Account Trust Policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::CENTRAL-ACCOUNT:role/FinOpsCentralScanner"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "finops-scanner-12345"
        }
      }
    }
  ]
}

Environment-Specific Policies

Development Environment

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AggressiveDevCleanup",
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteVolume",
        "ec2:TerminateInstances",
        "rds:DeleteDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Environment": [
            "dev",
            "development",
            "test",
            "staging"
          ]
        }
      }
    }
  ]
}

Production Environment

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ProductionSafeguards",
      "Effect": "Deny",
      "Action": [
        "ec2:DeleteVolume",
        "ec2:TerminateInstances",
        "rds:DeleteDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Environment": ["prod", "production", "live"]
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

KMS Encryption Permissions

Encrypted Resource Access

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "KMSKeyAccess",
      "Effect": "Allow",
      "Action": [
        "kms:Describe*",
        "kms:List*",
        "kms:Decrypt",
        "kms:CreateGrant"
      ],
      "Resource": ["arn:aws:kms:*:*:key/*"],
      "Condition": {
        "StringEquals": {
          "kms:ViaService": [
            "ec2.*.amazonaws.com",
            "rds.*.amazonaws.com",
            "dynamodb.*.amazonaws.com"
          ]
        }
      }
    }
  ]
}

VPC and Network Security

VPC Endpoint Access

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VPCEndpointAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ACCOUNT:role/FinOpsLambdaRole"
      },
      "Action": ["dynamodb:*", "sns:*"],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:SourceVpce": ["vpce-dynamodb-12345", "vpce-sns-67890"]
        }
      }
    }
  ]
}

Security Group Rules

# Lambda VPC Security Group
FinOpsLambdaSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Security group for FinOps Lambda functions
    VpcId: !Ref VpcId
    SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIp: 0.0.0.0/0
        Description: HTTPS outbound for AWS API calls
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
        Description: HTTP outbound for package downloads
    Tags:
      - Key: Name
        Value: finops-lambda-sg

Monitoring & Audit

CloudTrail Event Monitoring

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudTrailLogging",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
      ],
      "Resource": ["arn:aws:logs:*:*:log-group:/aws/lambda/finops-*"]
    }
  ]
}

Cost and Billing Access

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BillingAndCostAccess",
      "Effect": "Allow",
      "Action": [
        "ce:GetCostAndUsage",
        "ce:GetReservationCoverage",
        "ce:GetReservationPurchaseRecommendation",
        "ce:ListCostCategoryDefinitions",
        "ce:GetReservationUtilization"
      ],
      "Resource": "*"
    }
  ]
}

Service-Linked Roles

Auto-Generated Permissions

The system automatically creates service-linked roles for:

  • Lambda execution: Basic Lambda execution permissions
  • DynamoDB streams: Stream record processing
  • EventBridge: Scheduled scan triggering

Custom Service Role Template

FinOpsServiceRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName: FinOpsServiceRole
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com
          Action: sts:AssumeRole
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Policies:
      - PolicyName: FinOpsCustomPolicy
        PolicyDocument: !Ref FinOpsCustomPolicyDocument

Security Best Practices

1. Regular Permission Audits

# Audit unused permissions quarterly
aws iam get-account-authorization-details \
  --filter Role \
  --max-items 50 | \
  jq '.Roles[] | select(.RoleName | contains("FinOps"))'

2. Implement Resource Tagging

# Required tags for all FinOps resources
RequiredTags:
  - finops:managed: "true"
  - finops:environment: "prod|dev|staging"
  - finops:owner: "team@company.com"

3. Enable MFA for High-Risk Actions

{
  "Condition": {
    "Bool": {
      "aws:MultiFactorAuthPresent": "true"
    },
    "NumericLessThan": {
      "aws:MultiFactorAuthAge": "3600"
    }
  }
}

4. Implement Request Logging

# Lambda function logging template
import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info({
        'action': 'resource_cleanup',
        'resources': event.get('resources', []),
        'user': context.aws_request_id,
        'timestamp': datetime.utcnow().isoformat()
    })

Next Reading: