Security Guidelines

Security best practices for deploying and operating the SG Provisioner Tool.

Table of Contents

Credential Management

AWS Credentials

Never hardcode credentials. Use one of these methods:

  1. IAM Roles (Recommended for EC2/ECS)

    # No credentials needed — automatic from instance metadata
    docker run --rm \
      -v $(pwd)/sg/configs:/app/configs:ro \
      -v $(pwd)/sg/reports:/app/reports \
      sg-provisioner:latest \
      -con my-config.yaml \
      -act create-security-groups --force
    
  2. AWS Profiles (Recommended for Developers)

    # Docker
    -v ~/.aws:/home/sguser/.aws:ro
    
    # Local
    export AWS_PROFILE=production
    
  3. Environment Variables

    -e AWS_ACCESS_KEY_ID=<access_key>
    -e AWS_SECRET_ACCESS_KEY=<secret_key>
    -e AWS_DEFAULT_REGION=us-west-2
    

Credential Rotation

  • Rotate access keys every 90 days

  • Use temporary credentials (STS AssumeRole) when possible

  • Monitor credential age with IAM Credential Report

Security Group Design Principles

1. Least Privilege

Only allow traffic that is explicitly required:

# ✅ Good — specific port, specific source
ingress:
  - protocol: tcp
    port: 5432
    source_tier: app
    description: PostgreSQL from app tier only

# ❌ Bad — all ports, all sources
ingress:
  - protocol: tcp
    port_range: 0-65535
    source: 0.0.0.0/0

2. Defense in Depth

Layer security controls:

  • Security Groups (instance level)

  • Network ACLs (subnet level)

  • VPC design (network level)

  • IAM policies (API level)

3. Tier Isolation

Use cross-tier references instead of broad CIDRs:

# ✅ Good — only app tier can reach database
ingress:
  - protocol: tcp
    port: 5432
    source_tier: app

# ❌ Bad — entire VPC can reach database
ingress:
  - protocol: tcp
    port: 5432
    source: 10.0.0.0/16

4. Deny by Default

Security groups deny all inbound traffic by default. Only add rules for traffic you explicitly need. Keep egress rules minimal.

Rule Best Practices

Ingress Rules

Pattern

Risk

Recommendation

0.0.0.0/0 on port 22

HIGH

Use bastion host or SSM Session Manager

0.0.0.0/0 on port 3389

HIGH

Use VPN or SSM Fleet Manager

0.0.0.0/0 on DB ports

CRITICAL

Never expose databases to internet

0.0.0.0/0 on port 443

LOW

Acceptable for public web tier

source_tier: web

LOW

Preferred — uses SG reference

Egress Rules

Pattern

Risk

Recommendation

All traffic to 0.0.0.0/0

MEDIUM

Restrict to needed ports

Port 443 to 0.0.0.0/0

LOW

Acceptable for AWS API access

DB port to destination_tier

LOW

Preferred — uses SG reference

No egress rules

SAFE

Database tier — fully isolated

Port Ranges

Avoid broad port ranges:

# ❌ Bad — too broad
- protocol: tcp
  port_range: 1024-65535
  source: 0.0.0.0/0

# ✅ Good — specific port
- protocol: tcp
  port: 8443
  source_tier: web

CIDR Restrictions

Public Access (0.0.0.0/0)

Only acceptable for:

  • Web tier ingress on ports 80/443

  • Egress on port 443 (AWS APIs, package repos)

Never use for:

  • Database ports (3306, 5432, 1521, 1433, 5439, 27017)

  • SSH (22) or RDP (3389)

  • Application ports (8080, 8443, 9090)

IPv6 (::/0)

Same rules apply as IPv4. The scenario validator flags ::/0 on dangerous ports.

Internal CIDRs

When you must use CIDRs instead of tier references:

# ✅ Narrow — specific subnet
source: 10.0.11.0/24

# ⚠️ Broad — entire VPC
source: 10.0.0.0/16

# ❌ Never — entire internet
source: 0.0.0.0/0

CloudFormation Security

Stack Protection

  • Use --force flag only when intentional

  • Review templates before deployment (validate-prov-template)

  • Use show-changes to preview modifications

  • Run check-drift regularly to detect manual changes

Drift Remediation

If drift is detected:

  1. Identify who made the change (CloudTrail)

  2. Determine if the change is desired

  3. Either update your config to match, or redeploy to revert

Test Deployments

Always test in isolation first:

docker run --rm \
  -v ~/.aws:/home/sguser/.aws:ro \
  -v $(pwd)/sg/configs:/app/configs:ro \
  -v $(pwd)/sg/reports:/app/reports \
  sg-provisioner:latest \
  -con my-config.yaml \
  -act test-deploy

This creates a separate stack with a random suffix — no impact on production.

Docker Security

Image Verification

# Scan image before use
trivy image sg-provisioner:latest

Runtime Security

# Read-only credentials
-v ~/.aws:/home/sguser/.aws:ro

# Read-only config
-v $(pwd)/sg/configs:/app/configs:ro

# No privileged mode
# No host networking
# No extra capabilities

Logging and Monitoring

Audit Logs

Every action generates a log file in reports/:

globalbank-prod-c001-us-west-2-sg-create-security-groups-20260505_101914_057.log

CloudTrail

Monitor for:

  • CreateSecurityGroup / DeleteSecurityGroup events

  • AuthorizeSecurityGroupIngress / RevokeSecurityGroupIngress events

  • CreateStack / DeleteStack events

  • PutParameter / DeleteParameter events

CloudWatch Alarms

Set alarms for:

  • Security group rule changes outside CloudFormation

  • Stack deletion events

  • Failed API calls (AccessDenied)

Compliance

Tagging for Governance

tags:
  cost_center: Fraud Operations
  project: Fraud Detection
  owner: fraud-team
  compliance: pci-dss
  data_classification: confidential

Regular Audits

  • Review security group rules quarterly

  • Run check-drift weekly

  • Audit IAM permissions monthly

  • Rotate credentials every 90 days

Documentation

  • Keep configs in version control

  • Document all overrides with descriptions

  • Maintain change log for production deployments

Security Checklist

Before production deployment:

  • IAM policy generated and scoped to company prefix

  • VPC exists and is verified

  • Scenario reviewed — no overly permissive rules

  • Overrides reviewed — descriptions provided

  • Template validated locally (validate-prov-template)

  • Review report generated and approved (create-review-report)

  • Test deployment successful (test-deploy)

  • No database ports open to 0.0.0.0/0

  • No SSH/RDP open to the world

  • Egress rules are minimal

  • Tags applied for cost allocation and governance

  • CloudTrail enabled for audit

  • Credentials are temporary or recently rotated

  • Docker image scanned for vulnerabilities


References