<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joshua Michael Hall</title>
    <description>The latest articles on DEV Community by Joshua Michael Hall (@joshuamichaelhall).</description>
    <link>https://dev.to/joshuamichaelhall</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2964623%2F337fcdca-f581-4c26-947d-0fadba06313d.jpeg</url>
      <title>DEV Community: Joshua Michael Hall</title>
      <link>https://dev.to/joshuamichaelhall</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joshuamichaelhall"/>
    <language>en</language>
    <item>
      <title>Security Architecture Decisions in My Cloud Resume Challenge</title>
      <dc:creator>Joshua Michael Hall</dc:creator>
      <pubDate>Mon, 19 Jan 2026 06:01:45 +0000</pubDate>
      <link>https://dev.to/joshuamichaelhall/security-architecture-decisions-in-my-cloud-resume-challenge-5d14</link>
      <guid>https://dev.to/joshuamichaelhall/security-architecture-decisions-in-my-cloud-resume-challenge-5d14</guid>
      <description>&lt;p&gt;When I deployed my Cloud Resume Challenge project, I made deliberate security decisions at every layer. Some were exactly right. Others were conscious tradeoffs for a portfolio project that I'd handle differently in production.&lt;/p&gt;

&lt;p&gt;Here's what I built, why, and what I'd change for enterprise deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;Standard Cloud Resume Challenge: S3, CloudFront, Lambda, DynamoDB. I added security controls most candidates skip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; S3 → CloudFront (OAI, no public bucket)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; API Gateway → Lambda → DynamoDB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure:&lt;/strong&gt; 100% Terraform, zero console clicking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; WAF, CloudTrail, GuardDuty, encryption, IAM least privilege&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Worked Well
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CloudFront as Security Boundary
&lt;/h3&gt;

&lt;p&gt;My S3 bucket has no public access. All traffic flows through CloudFront via Origin Access Identity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_cloudfront_origin_access_identity"&lt;/span&gt; &lt;span class="s2"&gt;"oai"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"OAI for resume website"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_policy"&lt;/span&gt; &lt;span class="s2"&gt;"website"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;website&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_cloudfront_origin_access_identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iam_arn&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;
      &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${aws_s3_bucket.website.arn}/*"&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No direct bucket enumeration attacks&lt;/li&gt;
&lt;li&gt;CloudFront handles TLS with ACM certificates&lt;/li&gt;
&lt;li&gt;WAF rules apply at the edge&lt;/li&gt;
&lt;li&gt;Defense in depth—every layer enforces policy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  WAF with Rate Limiting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_wafv2_web_acl"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"resume-waf"&lt;/span&gt;
  &lt;span class="nx"&gt;scope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CLOUDFRONT"&lt;/span&gt;

  &lt;span class="nx"&gt;default_action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"RateLimit"&lt;/span&gt;
    &lt;span class="nx"&gt;priority&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;block&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;statement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;rate_based_statement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;limit&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;
        &lt;span class="nx"&gt;aggregate_key_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"IP"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;visibility_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sampled_requests_enabled&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;cloudwatch_metrics_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;metric_name&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"RateLimitRule"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWSManagedRulesCommonRuleSet"&lt;/span&gt;
    &lt;span class="nx"&gt;priority&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

    &lt;span class="nx"&gt;override_action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;none&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;statement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;managed_rule_group_statement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWSManagedRulesCommonRuleSet"&lt;/span&gt;
        &lt;span class="nx"&gt;vendor_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;visibility_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sampled_requests_enabled&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;cloudwatch_metrics_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;metric_name&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CommonRuleSet"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Overkill for a visitor counter? Probably. But it demonstrates application-layer protection, and the managed rules catch common attacks without maintaining signatures.&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM Least Privilege
&lt;/h3&gt;

&lt;p&gt;My Lambda has exactly three permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy"&lt;/span&gt; &lt;span class="s2"&gt;"lambda_dynamodb"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda-dynamodb-policy"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"dynamodb:GetItem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"dynamodb:UpdateItem"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_dynamodb_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visitor_count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;"logs:CreateLogGroup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"logs:CreateLogStream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"logs:PutLogEvents"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:logs:*:*:*"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No wildcards. No &lt;code&gt;AmazonDynamoDBFullAccess&lt;/code&gt;. The table ARN is explicit. Adding a second table means updating the policy—that friction is a feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudTrail with Integrity Validation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_cloudtrail"&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"resume-trail"&lt;/span&gt;
  &lt;span class="nx"&gt;s3_bucket_name&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloudtrail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;include_global_service_events&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;is_multi_region_trail&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;enable_log_file_validation&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;event_selector&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;read_write_type&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"All"&lt;/span&gt;
    &lt;span class="nx"&gt;include_management_events&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;enable_log_file_validation = true&lt;/code&gt; means logs can't be tampered with without detection. When an auditor asks "how do I know these logs weren't modified?", point to the checksum chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conscious Tradeoffs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  No VPC
&lt;/h3&gt;

&lt;p&gt;My architecture is purely serverless. Lambda, API Gateway, DynamoDB, S3, CloudFront—none require a VPC.&lt;/p&gt;

&lt;p&gt;For a portfolio project, this is fine. For production with sensitive data, I'd want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lambda in private subnets&lt;/li&gt;
&lt;li&gt;VPC endpoints for AWS services&lt;/li&gt;
&lt;li&gt;No public internet from compute layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Single Region
&lt;/h3&gt;

&lt;p&gt;Everything lives in us-east-1. If I deployed resources elsewhere, I'd have blind spots.&lt;/p&gt;

&lt;p&gt;For production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GuardDuty in all regions (detect unauthorized activity anywhere)&lt;/li&gt;
&lt;li&gt;Multi-region CloudTrail&lt;/li&gt;
&lt;li&gt;SCPs preventing resource creation in unauthorized regions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  No AWS Config
&lt;/h3&gt;

&lt;p&gt;Config tracks configuration drift and evaluates compliance rules. I skipped it because cost/complexity wasn't justified for a portfolio project.&lt;/p&gt;

&lt;p&gt;For production, Config is essential: "Show me all S3 buckets allowing public access" becomes a one-click query.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Add for Production
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Service Control Policies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"StringNotEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"aws:RequestedRegion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"cloudtrail:StopLogging"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"cloudtrail:DeleteTrail"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SCPs create guardrails that even admins can't bypass. Deny all actions in non-approved regions. Deny disabling CloudTrail. These prevent entire categories of misconfiguration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Response
&lt;/h3&gt;

&lt;p&gt;GuardDuty can trigger Lambda to respond automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compromised credentials detected → revoke immediately&lt;/li&gt;
&lt;li&gt;Unusual API calls from new IP → add to WAF block list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't implement this because complexity wasn't justified. For production, automated response reduces MTTC from hours to seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The IaC Advantage
&lt;/h2&gt;

&lt;p&gt;Everything is in Terraform. Security controls aren't bolt-on afterthoughts—they're part of the infrastructure definition, subject to code review, tracked in Git.&lt;/p&gt;

&lt;p&gt;When an auditor asks "show me your WAF configuration," I don't screenshot the console. I show the Terraform file. When they ask "has this changed?", I show the Git history.&lt;/p&gt;

&lt;p&gt;This is Configuration Management (CM-2, CM-3, CM-6 in NIST 800-171). It's not compliance theater—it's how good engineers naturally work.&lt;/p&gt;

&lt;p&gt;These same controls appear in CMMC Level 2 requirements - the framework I'm now helping DIB contractors achieve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design for audit from the start.&lt;/strong&gt; Terraform configs, CloudTrail logs, IAM policies—every decision has evidence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Understand your tradeoffs.&lt;/strong&gt; No VPC was a conscious choice, not an oversight. Document why, not just what.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layer your controls.&lt;/strong&gt; OAI restricts S3. WAF filters requests. IAM limits Lambda. DynamoDB encrypts at rest. No single control is sufficient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Know when to skip complexity.&lt;/strong&gt; I didn't implement Security Hub because it wasn't justified for my use case. Knowing when NOT to add controls matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Infrastructure as Code.&lt;/strong&gt; Manual configurations drift. Terraform is authoritative.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;The full Terraform code is in my &lt;a href="https://github.com/joshuamichaelhall/federal-cloud-resume" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;. The architecture runs about $15-20/month with all security controls enabled.&lt;/p&gt;

&lt;p&gt;Questions about the implementation? Drop a comment or connect with me on &lt;a href="https://linkedin.com/in/joshuamichaelhall" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>terraform</category>
      <category>cloudresumechallenge</category>
    </item>
    <item>
      <title>AWS SAA to Security Clearance: My Path to Federal Cloud Engineering</title>
      <dc:creator>Joshua Michael Hall</dc:creator>
      <pubDate>Sun, 09 Nov 2025 11:21:41 +0000</pubDate>
      <link>https://dev.to/joshuamichaelhall/aws-saa-to-security-clearance-my-path-to-federal-cloud-engineering-4p0p</link>
      <guid>https://dev.to/joshuamichaelhall/aws-saa-to-security-clearance-my-path-to-federal-cloud-engineering-4p0p</guid>
      <description>&lt;p&gt;Just passed AWS Solutions Architect Associate on my first attempt! But this isn't another "I passed!" post - it's about strategically positioning for federal defense contracting roles where cloud security expertise meets national security needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AWS SAA Matters for Federal Work
&lt;/h2&gt;

&lt;p&gt;Federal contractors aren't just looking for cloud engineers - they need professionals who understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compliance frameworks (FedRAMP, NIST 800-53, RMF)&lt;/li&gt;
&lt;li&gt;Security-first architecture&lt;/li&gt;
&lt;li&gt;Cost optimization for government contracts&lt;/li&gt;
&lt;li&gt;Multi-account strategies for classified/unclassified separation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AWS SAA provides the foundation, but it's just the beginning for federal work.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Unique Path: MSP → Cloud Security → Defense
&lt;/h2&gt;

&lt;p&gt;After founding and scaling an MSP to $250K revenue with &lt;strong&gt;zero security breaches&lt;/strong&gt; across 43+ clients, I learned that production security isn't theoretical - it's operational excellence under pressure. I managed 500+ endpoints and prevented $500K+ in estimated ransomware damages by inheriting and stabilizing environments others couldn't handle. &lt;/p&gt;

&lt;p&gt;That experience translates directly to federal requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HIPAA compliance → FedRAMP understanding&lt;/li&gt;
&lt;li&gt;MSP infrastructure → Multi-tenant security&lt;/li&gt;
&lt;li&gt;24/7 operations → Mission-critical mindset&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Federal Cloud Engineer Stack I'm Building
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;✅ Completed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Solutions Architect Associate (Nov 8, 2025)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🎯 Next 60 Days:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CompTIA Security+ (Nov 22) - DoD 8570 IAT Level II requirement&lt;/li&gt;
&lt;li&gt;AWS Security Specialty (Jan 2026) - Deep cloud security expertise&lt;/li&gt;
&lt;li&gt;Federal Cloud Resume (Dec 2025) - With RMF control mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what makes the Federal Cloud Resume different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Standard Cloud Resume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;S3 static website ✓&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CloudFront CDN ✓&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Lambda visitor counter ✓&lt;/span&gt;

&lt;span class="na"&gt;Federal Cloud Resume adds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;RMF control mapping (AC-17, SC-8, AU-2)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CloudTrail logging with integrity validation&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WAF rules for OWASP Top &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Least privilege IAM documented&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Compliance automation demos&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Cloud Security Engineering
&lt;/h2&gt;

&lt;p&gt;Cloud security engineers are in high demand in the defense sector, especially those with proven operational experience. &lt;/p&gt;

&lt;p&gt;My approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Leverage proven security track record (43+ organizations, zero breaches)&lt;/li&gt;
&lt;li&gt;Build on existing AWS and security certifications&lt;/li&gt;
&lt;li&gt;Apply MSP operational experience to federal requirements&lt;/li&gt;
&lt;li&gt;Focus on mission-critical infrastructure protection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's about applying real security operations experience where it matters most - protecting national security infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Clearance Factor
&lt;/h2&gt;

&lt;p&gt;Federal cloud security work requires understanding both technical implementation and compliance frameworks. Security clearances are typically sponsored by employers for qualified candidates.&lt;/p&gt;

&lt;p&gt;My eligibility advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean background&lt;/li&gt;
&lt;li&gt;Stable family life&lt;/li&gt;
&lt;li&gt;M.Div. (ethics foundation)&lt;/li&gt;
&lt;li&gt;No foreign conflicts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Connecting at AWS re:Invent
&lt;/h2&gt;

&lt;p&gt;I'll be at re:Invent (Dec 1-6) specifically targeting defense contractors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lockheed Martin&lt;/li&gt;
&lt;li&gt;Northrop Grumman&lt;/li&gt;
&lt;li&gt;Raytheon&lt;/li&gt;
&lt;li&gt;Booz Allen Hamilton&lt;/li&gt;
&lt;li&gt;SAIC/Leidos&lt;/li&gt;
&lt;li&gt;General Dynamics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're in defense contracting or know someone who is, let's connect! I'm particularly interested in Huntsville, AL opportunities (Redstone Arsenal).&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;While others chase FAANG, I'm focused on protecting national security infrastructure.&lt;/p&gt;

&lt;p&gt;The foundation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Security+ for DoD compliance ✅ (Nov 22)&lt;/li&gt;
&lt;li&gt;AWS Security Specialty for cloud expertise ✅ (Jan 2026)
&lt;/li&gt;
&lt;li&gt;Federal Cloud Resume for demonstration ✅ (Dec 2025)&lt;/li&gt;
&lt;li&gt;Commitment to Huntsville defense community&lt;/li&gt;
&lt;li&gt;Land cloud security engineer role 🎯&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Let's Connect
&lt;/h2&gt;

&lt;p&gt;Are you in defense contracting? Looking for cloud security engineers with proven operational track records? Building security teams that need someone who's maintained zero breaches under pressure? Let's connect on &lt;a href="https://www.linkedin.com/in/joshuamichaelhall" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The federal cloud sector needs security professionals who understand both operational excellence and mission criticality. With proven experience securing 43+ organizations and preventing $500K+ in damages, I bring real-world security operations to federal requirements.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;AWS SAA certified, Security+ current, building Federal Cloud Resume with RMF controls. Committed to Huntsville's defense community.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cloudsecurity</category>
      <category>federalcontracting</category>
      <category>defense</category>
      <category>clearance</category>
    </item>
  </channel>
</rss>
