Skip to content

Serverless Security — Lambda, Functions & Cloud Run Security Guide

DodaTech Updated 2026-06-24 5 min read

In this tutorial, you'll learn about Serverless Security. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Serverless security addresses the unique challenges of ephemeral, event-driven compute by enforcing least-privilege IAM roles, validating all event payloads, and managing secrets outside the function code across AWS Lambda, Azure Functions, and GCP Cloud Run.

What You Will Learn

How to secure Serverless functions at every stage: code, dependencies, IAM configuration, event sources, and runtime monitoring.

Why It Matters

Serverless functions expand the attack surface. Each function is an API endpoint with IAM permissions, a runtime environment, and access to cloud resources. A single over-permissioned function can expose an entire data store.

Real-World Use

A payment processing company runs 200 Lambda functions handling credit card transactions. Each function has a narrowly scoped IAM role. Functions are scanned for secrets in environment variables using a secrets scanner in the CI pipeline.

Serverless Security Architecture

flowchart LR
  Trigger["Event Source\nAPI Gateway / S3 / PubSub"] --> Function[Serverless Function]
  Function --> IAM[Least-Privilege IAM Role]
  Function --> Secrets[Secrets Manager\nNo env var secrets]
  Function --> VPC["VPC / Private Networking"]
  
  subgraph Security Controls
    Scan[Code & Dependency Scan]
    Validate[Event Validation]
    Audit[Execution Audit Logs]
    Limit[Resource Limits]
  end
  
  Function --> Scan
  Function --> Validate
  Function --> Audit
  Function --> Limit
  
  style IAM fill:#f90,color:#fff

AWS Lambda Security

Lambda security starts with the execution role. Grant only the permissions the function needs.

# Create a least-privilege Lambda execution role
aws iam create-role \
  --role-name process-orders-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "lambda.amazonaws.com"},
      "Action": "sts:AssumeRole]
    }]
  }'

# Attach only the specific DynamoDB read policy
aws iam put-role-policy \
  --role-name process-orders-role \
  --policy-name dynamo-read-orders \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Action": "dynamodb:GetItem",
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/orders]
    }]
  }'

# Configure function with VPC access and reserved concurrency
aws lambda update-function-configuration \
  --function-name process-orders \
  --vpc-config SubnetIds=subnet-abc,subnet-def,SecurityGroupIds=sg-123 \
  --reserved-concurrent-executions 10

# Encrypt environment variables with KMS
aws lambda update-function-configuration \
  --function-name process-orders \
  --kms-key-arn arn:aws:kms:us-east-1:123456789012:key/abc123

Azure Functions Security

Azure Functions use managed identities instead of keys for authenticating to other services.

# Enable system-assigned managed identity
az functionapp identity assign \
  --name process-orders-function \
  --resource-group prod-rg

# Grant the identity access to Key Vault
az keyvault set-policy \
  --name prod-keyvault-01 \
  --object-id <managed-identity-principal-id> \
  --secret-permissions get list

# Configure function with access restriction
az functionapp config access-restriction add \
  --resource-group prod-rg \
  --name process-orders-function \
  --rule-name allow-vnet \
  --action Allow \
  --priority 100 \
  --vnet-name prod-vnet \
  --subnet function-subnet

az functionapp config access-restriction show \
  --resource-group prod-rg \
  --name process-orders-function
# Output:
# [
#   {
#     "ruleName": "allow-vnet", "#     "priority": 100", "#     "action": "Allow"",
#     "vnetSubnetId": "/subscriptions/.../subnets/function-subnet]
#   }
# ]

GCP Cloud Run Security

Cloud Run runs containers in a sandboxed environment. Use the least-privilege service account and enable VPC egress through a VPC connector.

# Create a dedicated service account for Cloud Run
gcloud iam service-accounts create process-orders-sa \
  --display-name "Process Orders Service Account"

# Grant minimal permissions
gcloud projects add-iam-policy-binding my-project \
  --member "serviceAccount:process-orders-sa@my-project.iam.gserviceaccount.com" \
  --role "roles/datastore.user"

# Deploy with the service account and VPC connector
gcloud run deploy process-orders \
  --image gcr.io/my-project/process-orders \
  --service-account process-orders-sa@my-project.iam.gserviceaccount.com \
  --vpc-connector prod-connector \
  --vpc-egress private-ranges-only \
  --cpu-throttling \
  --concurrency 80

# Verify service account
gcloud run services describe process-orders \
  --format="value(spec.template.spec.serviceAccountName)"
# Output:
# process-orders-sa@my-project.iam.gserviceaccount.com

Event Validation

Never trust event payloads. Validate structure, size limits, and expected fields before processing.

# AWS: Validate Lambda event payload structure
def lambda_handler(event, context):
    if not isinstance(event.get("body"), dict):
        raise ValueError("Invalid payload structure")

Common Mistakes

  1. Over-permissioned function roles: A common pattern is granting DynamoDB:* to every function. Scope IAM policies to specific tables and actions.
  2. Secrets in environment variables: Environment variables appear in CloudTrail logs, function versions, and error messages. Use a secrets manager instead.
  3. Ignoring dependency vulnerabilities: Serverless functions include libraries too. Scan dependencies in the CI pipeline before deployment.
  4. No event validation: Functions that process user input without validation are vulnerable to injection attacks and malformed payloads.
  5. Functions in public subnets: Functions without VPC access communicate over the internet. Place functions in private subnets when accessing private resources.

Practice Questions

  1. Why should Lambda functions use execution roles instead of IAM user credentials?
  2. How do Azure managed identities improve Serverless security?
  3. What is the role of a VPC connector in GCP Cloud Run?
  4. Why should environment variables never contain secrets?
  5. How does least-privilege IAM reduce the Blast Radius of a compromised function?

Challenge

Deploy a three-function Serverless application. The first function receives HTTP requests from API Gateway. The second writes to DynamoDB (or Firestore). The third reads from S3 (or GCS). Each function has a dedicated IAM role with only the specific actions and resources it needs. Validate all event payloads. Use a secrets manager for database credentials. Enable VPC access for functions that need it.

FAQ

What is Serverless security?

The practice of securing event-driven, ephemeral compute functions through least-privilege IAM, input validation, and secrets management.

How does Lambda execution role security work?

Each Lambda function assumes an IAM role that grants access to specific AWS resources. The role is assumed at invocation time.

Can Azure Functions use managed identities?

Yes. Managed identities let Functions authenticate to Azure services without storing credentials.

What is Cloud Run's security model?

Cloud Run runs each request in a sandboxed container with a user-defined service account and optional VPC networking.

Why is event validation important in Serverless?

Functions process untrusted input from many sources. Validation prevents injection attacks, malformed data processing, and denial-of-wallet attacks.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro