Skip to main content

Lesson 4: Advanced Security

What this lesson covers

  • Least privilege IAM (Identity and Access Management)
  • Secrets management and rotation
  • Supply chain security and code provenance
  • Encryption in transit and at rest

Read time: 12 minutes


Simple Explanation

What it is

Advanced security is about locking down permissions, protecting secrets, and reducing supply-chain risk.

Why we need it

Serverless systems often have powerful IAM roles. A single leaked key can expose entire systems.

Benefits

  • Lower breach risk with least privilege.
  • Safer deployments through code provenance.
  • Better compliance with encryption and audits.

Tradeoffs

  • More setup for policies and rotations.
  • Stricter workflows for developers.

Real-world examples (architecture only)

  • Least privilege IAM -> Reduced blast radius.
  • Secret rotation -> Shorter exposure window.

IAM boundary Secret rotation


Least Privilege IAM

The principle of least privilege: grant only the permissions a function needs, not more.

Serverless functions often have overly permissive roles because developers grant "Action": "*" and "Resource": "*" for speed. This is a critical security gap.

WRONG (too permissive):

{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}

RIGHT (minimal):

{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:ACCOUNT:table/orders"
}

AWS Tool: Use Access Analyzer to identify overly permissive policies and auto-generate minimal permissions.

GCP equivalent: IAM Policy Analyzer identifies over-privileged service accounts.


Secrets Management

Never hardcode secrets (API keys, DB passwords, OAuth tokens) in function code or environment variables.

WRONG:

DB_PASSWORD=MySecurePassword123
API_KEY=sk_live_abc123

RIGHT (AWS):

import json
import boto3

secrets_manager = boto3.client("secretsmanager")


def get_secret(secret_name):
response = secrets_manager.get_secret_value(SecretId=secret_name)
return json.loads(response.get("SecretString", "{}"))


# Function code
db_creds = get_secret("prod/db-password")
api_key = get_secret("stripe-api-key")

RIGHT (GCP):

from google.cloud import secretmanager


def get_secret(project_id, secret_name):
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_name}/versions/latest"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("utf-8")

Rotation: Rotate secrets frequently (30–90 days). Both AWS Secrets Manager and GCP Secret Manager support auto-rotation.


Supply Chain Security

Modern serverless relies on open-source dependencies (PyPI, Maven Central). Dependencies can be compromised.

Hardening:

  1. Vulnerability Scanning:

    • Use pip audit before deployment
    • Integrate SAST (static application security testing) into CI/CD
    • Tools: Snyk, Aqua, Checkmarx
  2. Code Signing:

    • Sign container images and Lambda layers
    • Verify signatures at deployment
  3. Dependency Pinning:

    • Pin exact versions (not ^1.2.3 or ~1.2.3)
    • Keep requirements.txt or poetry.lock in version control
  4. Private Registries:

    • Use private Python registries (AWS CodeArtifact, GCP Artifact Registry) for proprietary packages

Encryption

In Transit (TLS/HTTPS):

  • API Gateway enforces HTTPS (no HTTP)
  • Use TLS 1.2+ for Lambda-to-service calls
  • Validate certificates

At Rest:

# AWS: DynamoDB encryption (enabled by default in 2019+)
# GCP: Firestore/Datastore encrypted by default

# For additional control:
import boto3

kms = boto3.client("kms")


def encrypt_with_kms(plaintext, key_id):
response = kms.encrypt(KeyId=key_id, Plaintext=plaintext)
return response["CiphertextBlob"]

Common Mistakes

  1. Storing secrets in environment variables — They're readable by other functions on the same account
  2. Granting "*" permissions — Makes token theft catastrophic
  3. Forgetting to rotate credentials — If a key leaks, it works forever
  4. Not validating webhooks — Anyone can trigger your function if they know the URL
  5. Logging sensitive data — Passwords/tokens appear in CloudWatch/Stackdriver logs

What Comes Next

  • Lesson 5: Cost engineering (forecasting, right-sizing, reserved capacity)
  • Lesson 6: Chaos and resilience (testing failure scenarios)

Key Takeaway: Security at scale requires automation. Use managed services (Secrets Manager, Access Analyzer), scan dependencies, validate all inputs, and rotate credentials regularly.