<?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: László Tóth</title>
    <description>The latest articles on DEV Community by László Tóth (@tothl74).</description>
    <link>https://dev.to/tothl74</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3386895%2Fac9d100c-5174-41d4-b891-482756559761.jpg</url>
      <title>DEV Community: László Tóth</title>
      <link>https://dev.to/tothl74</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tothl74"/>
    <language>en</language>
    <item>
      <title>From One-Off FTR Evidence to Scheduled Security and Recovery Controls in GitLab</title>
      <dc:creator>László Tóth</dc:creator>
      <pubDate>Tue, 28 Jul 2026 12:38:57 +0000</pubDate>
      <link>https://dev.to/tothl74/from-one-off-ftr-evidence-to-scheduled-security-and-recovery-controls-in-gitlab-4eo</link>
      <guid>https://dev.to/tothl74/from-one-off-ftr-evidence-to-scheduled-security-and-recovery-controls-in-gitlab-4eo</guid>
      <description>&lt;p&gt;A security check that runs once is evidence, while a security check that keeps running, has a controlled scope, produces reviewable artifacts, and fails visibly can become an engineering control.&lt;/p&gt;

&lt;p&gt;We learned this while preparing WP Suite Deployment Access for the AWS Foundational Technical Review.&lt;/p&gt;

&lt;p&gt;The final FTR validation was fast. AWS Partner Central now accepts AWS Well-Architected Framework Review reports and automatically checks whether they satisfy the required validation controls.&lt;/p&gt;

&lt;p&gt;The work that mattered happened before we uploaded the report.&lt;/p&gt;

&lt;p&gt;Answering the Well-Architected questions honestly forced us to compare the architecture we described with the system we had actually deployed. That process exposed a recurring problem: many of our security and recovery statements were true at a point in time, but we did not yet have a repeatable way to prove that they would remain true after the next release.&lt;/p&gt;

&lt;p&gt;A successful scanner run could support one review. It could not tell us whether a future API change weakened an authorization boundary, whether a browser-dependent reCAPTCHA flow still worked on the CI runner, or whether an AWS Backup recovery point could actually be restored.&lt;/p&gt;

&lt;p&gt;So we turned the evidence work into two scheduled GitLab pipelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a controlled security-assurance pipeline;&lt;/li&gt;
&lt;li&gt;a separate reliability and disaster-recovery pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article explains the structure, the mistakes we found while automating it, and why neither pipeline is allowed to approve itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product boundary came first
&lt;/h2&gt;

&lt;p&gt;WP Suite Deployment Access launches optional backend infrastructure into the buyer's AWS account through AWS Marketplace and CloudFormation.&lt;/p&gt;

&lt;p&gt;The supported architecture can include components for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon Cognito identity;&lt;/li&gt;
&lt;li&gt;AI and knowledge-base APIs;&lt;/li&gt;
&lt;li&gt;form and workflow processing;&lt;/li&gt;
&lt;li&gt;protected static delivery;&lt;/li&gt;
&lt;li&gt;scheduled backup and recovery resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The public CloudFormation templates show buyers and reviewers what the deployment intends to create. Private runtime artifacts are staged only during an authorized deployment.&lt;/p&gt;

&lt;p&gt;That architecture creates an important testing constraint.&lt;/p&gt;

&lt;p&gt;Our assurance jobs must never treat customer production accounts as scanner targets.&lt;/p&gt;

&lt;p&gt;Before selecting any testing tool, we defined the control boundary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all automated tests run against a dedicated, production-like test deployment;&lt;/li&gt;
&lt;li&gt;targets are explicitly allowlisted;&lt;/li&gt;
&lt;li&gt;test data is disposable;&lt;/li&gt;
&lt;li&gt;destructive operations are limited to pipeline-created fixtures;&lt;/li&gt;
&lt;li&gt;denial-of-service, stress, flooding, password spraying, and uncontrolled destructive testing are excluded;&lt;/li&gt;
&lt;li&gt;availability degradation, unexpected cost, unintended data access, or secret exposure are stop conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This boundary matters more than the scanner configuration.&lt;/p&gt;

&lt;p&gt;A technically capable security tool pointed at the wrong environment is not an assurance control. It is an operational risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The security pipeline shape
&lt;/h2&gt;

&lt;p&gt;The resulting security pipeline runs on a schedule and can also be started through controlled manual or evidence-producing paths.&lt;/p&gt;

&lt;p&gt;At a high level, the stages look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prepare
  ↓
application security regression
  ↓
browser-dependent validation
  ↓
API scan
  ↓
fixture cleanup
  ↓
evidence generation
  ↓
human review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real pipeline contains several jobs, but this simplified sequence captures the responsibility of each phase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5byx33m8h1onvvr62qj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5byx33m8h1onvvr62qj2.png" alt="The recurring security pipeline combines allowlisted targets, application-specific regression tests, browser-dependent validation, API scanning, and human-reviewed evidence." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Prepare
&lt;/h3&gt;

&lt;p&gt;The preparation stage validates the approved targets and creates only the disposable resources required by that run.&lt;/p&gt;

&lt;p&gt;For workflow tests, for example, the pipeline creates data with identifiers derived from the pipeline run. Cleanup can therefore distinguish test fixtures from pre-existing data.&lt;/p&gt;

&lt;p&gt;Preparation also records the tool versions and relevant test configuration required to interpret the results later.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Application-specific security regression
&lt;/h3&gt;

&lt;p&gt;Generic scanners are useful, but they do not understand all of the invariants that matter to an application.&lt;/p&gt;

&lt;p&gt;We use Node.js regression tests for controls such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expected Cognito authorization boundaries;&lt;/li&gt;
&lt;li&gt;denial of administrative operations to non-administrative identities;&lt;/li&gt;
&lt;li&gt;reCAPTCHA enforcement and replay behavior;&lt;/li&gt;
&lt;li&gt;rejection of tokens generated for the wrong action;&lt;/li&gt;
&lt;li&gt;webhook-signature validation;&lt;/li&gt;
&lt;li&gt;mutation resistance for presigned upload URLs;&lt;/li&gt;
&lt;li&gt;signed-cookie behavior for protected static routes;&lt;/li&gt;
&lt;li&gt;the rule that credentialed CORS must never be combined with a wildcard origin.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tests express product-specific expectations directly.&lt;/p&gt;

&lt;p&gt;If an endpoint begins returning a valid HTTP response while silently ignoring an authorization rule, a generic scanner may not recognize the business impact. An explicit regression assertion can.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Browser-dependent validation
&lt;/h3&gt;

&lt;p&gt;Some security paths cannot be tested accurately with a plain HTTP client.&lt;/p&gt;

&lt;p&gt;reCAPTCHA is a good example. A meaningful test may require a token produced by a real browser context, followed by a backend request that verifies the token's action, validity, and replay behavior.&lt;/p&gt;

&lt;p&gt;We use Playwright for these browser-dependent cases.&lt;/p&gt;

&lt;p&gt;This layer also taught us an important lesson about incomplete automation.&lt;/p&gt;

&lt;p&gt;During an early run, the reCAPTCHA script behaved differently on the CI runner than it did in our local and deployed browser tests. The affected checks remained pending.&lt;/p&gt;

&lt;p&gt;The wrong response would have been to treat the rest of the green pipeline as a pass.&lt;/p&gt;

&lt;p&gt;Instead, the evidence report had to preserve the incomplete state until the runner-specific problem was understood and corrected.&lt;/p&gt;

&lt;p&gt;A missing test is not a successful test.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. API scanning
&lt;/h3&gt;

&lt;p&gt;The pipeline exports the current API definitions from the deployed test environment and uses OWASP ZAP to scan the intended API surface.&lt;/p&gt;

&lt;p&gt;ZAP adds a different type of coverage from the application-specific tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;passive response analysis;&lt;/li&gt;
&lt;li&gt;API-driven exploration;&lt;/li&gt;
&lt;li&gt;detection of common web and API weaknesses;&lt;/li&gt;
&lt;li&gt;an independent view of the deployed interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scan is deliberately bounded.&lt;/p&gt;

&lt;p&gt;Targets are allowlisted, concurrency is limited, and testing classes that could create availability or cost risk are excluded.&lt;/p&gt;

&lt;p&gt;ZAP is one layer of the process, not the approval authority.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Cleanup
&lt;/h3&gt;

&lt;p&gt;Cleanup is a first-class pipeline phase rather than a shell command appended to a test job.&lt;/p&gt;

&lt;p&gt;The pipeline verifies that temporary workflow records, uploaded objects, and other run-specific fixtures are removed.&lt;/p&gt;

&lt;p&gt;Cleanup evidence matters for two reasons.&lt;/p&gt;

&lt;p&gt;First, disposable data should not gradually turn a test environment into an unreviewable collection of stale records.&lt;/p&gt;

&lt;p&gt;Second, cleanup behavior is itself part of operational correctness. A test that succeeds but leaves unexpected resources behind has found another problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Evidence generation
&lt;/h3&gt;

&lt;p&gt;The pipeline produces private artifacts containing the summaries, structured results, logs, tool versions, and cleanup evidence needed for review.&lt;/p&gt;

&lt;p&gt;Automating this stage produced one of the more instructive failures in the project.&lt;/p&gt;

&lt;p&gt;An early summarizer confused a scanner's confidence classification with its risk classification.&lt;/p&gt;

&lt;p&gt;The scan itself had run correctly. The generated evidence represented part of the result incorrectly.&lt;/p&gt;

&lt;p&gt;That is a serious defect because reviewers usually consume the summary before they inspect every raw artifact.&lt;/p&gt;

&lt;p&gt;We corrected the summarizer and added validation around the evidence transformation.&lt;/p&gt;

&lt;p&gt;The lesson was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Evidence generation is production code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A pipeline can execute every test correctly and still produce a misleading assurance record if its reporting layer is wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the pipeline does not approve itself
&lt;/h2&gt;

&lt;p&gt;A green CI pipeline is not the final approval.&lt;/p&gt;

&lt;p&gt;After every evidence-producing run, a separate review item is created for a human reviewer.&lt;/p&gt;

&lt;p&gt;The reviewer checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;security findings and their actual risk;&lt;/li&gt;
&lt;li&gt;failed, skipped, pending, or manually validated controls;&lt;/li&gt;
&lt;li&gt;the boundaries and exclusions of the run;&lt;/li&gt;
&lt;li&gt;cleanup evidence;&lt;/li&gt;
&lt;li&gt;tool and target versions;&lt;/li&gt;
&lt;li&gt;whether the result supports the intended assurance claim.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final disposition is recorded separately from the pipeline status.&lt;/p&gt;

&lt;p&gt;This separation prevents several common problems.&lt;/p&gt;

&lt;p&gt;A script cannot silently redefine its own acceptance criteria. A newly skipped test cannot disappear inside an otherwise green result. A scanner warning cannot automatically become either a release blocker or an accepted risk without context.&lt;/p&gt;

&lt;p&gt;Automation collects and organizes evidence, a responsible person remains accountable for interpreting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recovery required a different pipeline
&lt;/h2&gt;

&lt;p&gt;Security testing and disaster-recovery validation have different operational characteristics, so we do not run them as one large assurance job.&lt;/p&gt;

&lt;p&gt;The security pipeline runs more frequently.&lt;/p&gt;

&lt;p&gt;The reliability and DR path runs monthly and performs slower, more stateful validation.&lt;/p&gt;

&lt;p&gt;Its most important rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not test only whether backups exist. Test whether selected recovery points can be restored.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvr22hc8d8wb1fnx00sit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvr22hc8d8wb1fnx00sit.png" alt="Recovery validation uses real backup restores: a bounded sample is restored into isolated resources, checked, cleaned up, and reviewed." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A backup job can report success while recovery is still blocked by permissions, encryption configuration, missing dependencies, an invalid procedure, or assumptions that have never been tested.&lt;/p&gt;

&lt;p&gt;Our monthly process therefore works with actual AWS Backup recovery points.&lt;/p&gt;

&lt;p&gt;At a high level, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;identifies fresh recovery points for the protected test resources;&lt;/li&gt;
&lt;li&gt;selects a bounded restore sample;&lt;/li&gt;
&lt;li&gt;restores DynamoDB and S3 data into isolated resources;&lt;/li&gt;
&lt;li&gt;validates known canary data or checksums;&lt;/li&gt;
&lt;li&gt;records the observed recovery behavior;&lt;/li&gt;
&lt;li&gt;removes the restored resources;&lt;/li&gt;
&lt;li&gt;generates evidence for human review.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The restore sample is intentionally bounded.&lt;/p&gt;

&lt;p&gt;It does not claim that every protected resource is restored during every monthly run. Backup coverage and restore sampling are reported as separate concepts so a successful sample cannot accidentally be presented as proof that every resource was restored.&lt;/p&gt;

&lt;p&gt;This distinction made the report more honest and more useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  From internal control to product capability
&lt;/h2&gt;

&lt;p&gt;The recovery work did not remain only inside our assurance repository.&lt;/p&gt;

&lt;p&gt;WP Suite Deployment Access now includes an optional backup and disaster-recovery component in the deployment model.&lt;/p&gt;

&lt;p&gt;When selected, it can configure scheduled AWS Backup recovery points for supported, deployment-tagged S3 and DynamoDB resources and copy them to a second AWS Region chosen by the buyer.&lt;/p&gt;

&lt;p&gt;This is a recovery capability, not an active-active architecture.&lt;/p&gt;

&lt;p&gt;It should not be described as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic regional failover;&lt;/li&gt;
&lt;li&gt;continuous replication;&lt;/li&gt;
&lt;li&gt;point-in-time recovery for every resource;&lt;/li&gt;
&lt;li&gt;a permanently running secondary production stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The intended model is simpler and more explicit: a separate regional copy remains available so selected data can be restored if the primary Region experiences a serious outage or the primary recovery points are unavailable.&lt;/p&gt;

&lt;p&gt;The infrastructure definition is deployed into the buyer's AWS account, alongside the other selected WP Suite components.&lt;/p&gt;

&lt;p&gt;The recurring assurance pipelines remain vendor-side controls against our dedicated test deployment. They do not scan customer production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the AWS review changed
&lt;/h2&gt;

&lt;p&gt;The AWS Well-Architected review began as a validation requirement, but it became a way to find places where architectural claims were not yet represented by repeatable operational behavior.&lt;/p&gt;

&lt;p&gt;By the time we submitted the WAFR report:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;security testing had become scheduled and reviewable;&lt;/li&gt;
&lt;li&gt;browser-dependent and application-specific controls complemented API scanning;&lt;/li&gt;
&lt;li&gt;incomplete automation remained visible rather than being counted as a pass;&lt;/li&gt;
&lt;li&gt;evidence generation had its own validation requirements;&lt;/li&gt;
&lt;li&gt;recovery testing used real backup restores;&lt;/li&gt;
&lt;li&gt;human approval was separated from CI success;&lt;/li&gt;
&lt;li&gt;a useful recovery control had become a buyer-selectable deployment capability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WP Suite Deployment Access subsequently passed AWS Foundational Technical Review.&lt;/p&gt;

&lt;p&gt;That statement applies to the named solution and the submitted review scope.&lt;/p&gt;

&lt;p&gt;It does not mean AWS audited our source code, performed our penetration test, or guaranteed that the product has no risk.&lt;/p&gt;

&lt;p&gt;The durable result is not the badge. The durable result is that the questions asked during the review continue to be answered after the review is over.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcyg74a6a2lnbk0kqpa1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcyg74a6a2lnbk0kqpa1b.png" alt="Automation becomes an engineering control only when its scope is bounded, incomplete checks remain visible, evidence is reviewed, and sensitive data stays protected." width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical takeaways
&lt;/h2&gt;

&lt;p&gt;For teams building similar assurance workflows, these are the lessons I would carry forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define the boundary before choosing the tools
&lt;/h3&gt;

&lt;p&gt;Decide what can be tested, where it can be tested, and which activities are excluded before configuring a scanner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combine generic and application-specific tests
&lt;/h3&gt;

&lt;p&gt;A scanner can identify broad classes of weaknesses. It cannot automatically understand every authorization, workflow, tenancy, or business invariant in your product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a browser when the control depends on browser behavior
&lt;/h3&gt;

&lt;p&gt;Do not replace browser-generated security context with a mock and then claim that the complete production path was tested.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make incomplete controls visible
&lt;/h3&gt;

&lt;p&gt;Pending, skipped, and manual checks belong in the evidence summary. They must not disappear behind the overall pipeline status.&lt;/p&gt;

&lt;h3&gt;
  
  
  Treat reporting code as production code
&lt;/h3&gt;

&lt;p&gt;A wrong summary can invalidate otherwise correct test execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test restores, not backup configuration
&lt;/h3&gt;

&lt;p&gt;The existence of a vault, plan, or recovery point is not proof that your recovery procedure works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep a human approval step
&lt;/h3&gt;

&lt;p&gt;Automation should make review faster and more consistent, not eliminate accountability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Productize controls only when the boundary remains clear
&lt;/h3&gt;

&lt;p&gt;A useful internal control can become a customer-facing capability, but its limits must remain explicit. Scheduled cross-Region backups are valuable without being presented as automatic failover.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public references
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/partners/foundational-technical-review/" rel="noopener noreferrer"&gt;AWS Foundational Technical Review&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/partner-central/latest/builder-guide/requesting-ftr.html" rel="noopener noreferrer"&gt;AWS Partner Central FTR validation process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/smartcloudsol/wpsuite-deployment-templates" rel="noopener noreferrer"&gt;WP Suite Deployment Access public templates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/smartcloudsol/wpsuite-deployment-templates/blob/main/docs/architecture.md" rel="noopener noreferrer"&gt;WP Suite Deployment Access architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>security</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>Scaling Carmen Cloud: From Containers to Lambda SnapStart</title>
      <dc:creator>László Tóth</dc:creator>
      <pubDate>Mon, 15 Sep 2025 14:40:59 +0000</pubDate>
      <link>https://dev.to/tothl74/scaling-carmen-cloud-from-containers-to-lambda-snapstart-57n2</link>
      <guid>https://dev.to/tothl74/scaling-carmen-cloud-from-containers-to-lambda-snapstart-57n2</guid>
      <description>&lt;p&gt;At Adaptive Recognition, we run &lt;strong&gt;Carmen Cloud&lt;/strong&gt; for ANPR &amp;amp; MMR recognition. Our neural-network engines have been evolving for 30+ years – for us, "AI" is business as usual.  &lt;/p&gt;

&lt;p&gt;The real challenge: &lt;strong&gt;scaling&lt;/strong&gt;. On ECS Fargate + EC2, startup + engine init took ~60 seconds. Not acceptable.  &lt;/p&gt;




&lt;h2&gt;
  
  
  The Fargate/ECS Approach
&lt;/h2&gt;

&lt;p&gt;Our first deployment ran on &lt;strong&gt;ECS Fargate&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;predictable workloads&lt;/strong&gt;, this is often good enough. You can define scaling rules or even schedule tasks so that capacity matches traffic (e.g. higher during business hours, lower at night).  &lt;/p&gt;

&lt;p&gt;But our workload is the opposite of predictable. Recognition requests come from &lt;strong&gt;many customers, across multiple regions&lt;/strong&gt;, at almost random times. Bursts can hit at 2 a.m. from one continent and spike again an hour later from another.  &lt;/p&gt;

&lt;p&gt;With that traffic pattern, Fargate's trade-offs became painful:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scale-up lag:&lt;/strong&gt; EC2 boot + engine init ~60s.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idle cost:&lt;/strong&gt; keeping containers pre-warmed all the time.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ops overhead:&lt;/strong&gt; building/pushing images, patching, managing ECR.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's when we started looking for a new approach.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Early Adoption of SnapStart
&lt;/h2&gt;

&lt;p&gt;When &lt;strong&gt;AWS Lambda SnapStart (Java 21)&lt;/strong&gt; was released, we migrated &lt;strong&gt;immediately&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;That made us among the first to see just how well it scales – and how much money it saves.  &lt;/p&gt;

&lt;p&gt;Years later, those benefits are still holding true.  &lt;/p&gt;




&lt;h2&gt;
  
  
  The Shift: API Gateway + Lambda SnapStart + CRaC
&lt;/h2&gt;

&lt;p&gt;Key trick: &lt;strong&gt;CRaC (Coordinated Restore at Checkpoint)&lt;/strong&gt; pre-initializes our engines at checkpoint time.  &lt;/p&gt;

&lt;p&gt;But SnapStart has a serious limitation: it doesn't support &lt;strong&gt;&amp;gt;512 MB of ephemeral storage, nor EFS&lt;/strong&gt;. Our recognition engines for a single region (EUR, NAM) are much larger than that.  &lt;/p&gt;

&lt;p&gt;So we built a &lt;strong&gt;staged engine loading mechanism&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During handler initialization, we download a batch of engine data from S3.
&lt;/li&gt;
&lt;li&gt;Engines are initialized into memory (via our &lt;code&gt;VehicleHandler&lt;/code&gt; class).
&lt;/li&gt;
&lt;li&gt;Temporary &lt;code&gt;.dat&lt;/code&gt; files are deleted to free up space.
&lt;/li&gt;
&lt;li&gt;The next batch is downloaded and initialized.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps us under the 512 MB limit while still giving us full coverage. Initialization is more complex, but the scalability and cost benefits make it well worth it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.Context&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.RequestHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VehicleHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RequestHandler&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;crac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Resource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Load engines in batches at checkpoint time from S3&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;beforeCheckpoint&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;crac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;crac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Close network connections – CRaC cannot persist them&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;afterRestore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;crac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;crac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Re-open connections on restore&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;APIGatewayProxyResponseEvent&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;APIGatewayProxyRequestEvent&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Process image with the chosen engine&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;APIGatewayProxyResponseEvent&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Supporting AWS Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway&lt;/strong&gt; – entry point
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda (SnapStart)&lt;/strong&gt; – recognition engines
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognito&lt;/strong&gt; – user auth
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt; – API keys, billing records
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNS/EventBridge&lt;/strong&gt; – async billing + subscription events
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3, SSM, CloudFront, WAF, Route53&lt;/strong&gt; – storage, config, delivery, security
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ol&gt;
&lt;li&gt;Even heavy neural engines can scale serverless.
&lt;/li&gt;
&lt;li&gt;CRaC makes SnapStart viable by restoring pre-initialized state.
&lt;/li&gt;
&lt;li&gt;Closing &amp;amp; reopening network connections is essential.
&lt;/li&gt;
&lt;li&gt;Staged loading solves ephemeral storage/EFS limits.
&lt;/li&gt;
&lt;li&gt;Being an &lt;strong&gt;early adopter&lt;/strong&gt; of SnapStart saved us both &lt;strong&gt;time and cost&lt;/strong&gt; from day one.
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/eIU-TlzeVBA"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;👉 More about Carmen Cloud: &lt;a href="https://carmencloud.com" rel="noopener noreferrer"&gt;carmencloud.com&lt;/a&gt;&lt;br&gt;
👉 Corporate homepage: &lt;a href="https://adaptiverecognition.com" rel="noopener noreferrer"&gt;adaptiverecognition.com&lt;/a&gt;&lt;br&gt;
👉 My side project for WordPress + Cognito login: &lt;a href="https://wpsuite.io" rel="noopener noreferrer"&gt;Gatey&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>snapstart</category>
      <category>saas</category>
    </item>
    <item>
      <title>Add Social &amp; Enterprise SSO to WordPress (Even on Static Sites) with Amazon Cognito + Gatey</title>
      <dc:creator>László Tóth</dc:creator>
      <pubDate>Sun, 14 Sep 2025 12:38:17 +0000</pubDate>
      <link>https://dev.to/tothl74/add-social-enterprise-sso-to-wordpress-even-on-static-sites-with-amazon-cognito-gatey-1ja3</link>
      <guid>https://dev.to/tothl74/add-social-enterprise-sso-to-wordpress-even-on-static-sites-with-amazon-cognito-gatey-1ja3</guid>
      <description>&lt;p&gt;WordPress was never built for OIDC or SAML. Export it as a static site to S3 + CloudFront and the built-in login system stops working completely.&lt;/p&gt;

&lt;p&gt;The fix? &lt;strong&gt;Amazon Cognito + Gatey&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure Cognito User Pools &amp;amp; Hosted UI (no client secret needed, SPA app type)&lt;/li&gt;
&lt;li&gt;Connect Social IdPs (Google, Facebook, Apple, Amazon)&lt;/li&gt;
&lt;li&gt;Add Enterprise IdPs (OIDC, SAML: Okta, Azure AD, Auth0, Ping)&lt;/li&gt;
&lt;li&gt;Wire it into WordPress with Gatey (User Pools, General, Custom Providers)&lt;/li&gt;
&lt;li&gt;(Optional) Enable IAM so authenticated users can call your AWS APIs directly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Full guide with screenshots on &lt;a href="https://wpsuite.io/blog/social-enterprise-sso/" rel="noopener noreferrer"&gt;wpsuite.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Static-friendly, secure, and no secrets stored in WordPress.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>aws</category>
      <category>cognito</category>
      <category>sso</category>
    </item>
    <item>
      <title>Behind the Scenes: Building WordPress Static Site Guardian with Kiro</title>
      <dc:creator>László Tóth</dc:creator>
      <pubDate>Wed, 10 Sep 2025 12:00:00 +0000</pubDate>
      <link>https://dev.to/tothl74/behind-the-scenes-building-wordpress-static-site-guardian-with-kiro-4onh</link>
      <guid>https://dev.to/tothl74/behind-the-scenes-building-wordpress-static-site-guardian-with-kiro-4onh</guid>
      <description>&lt;p&gt;In a recent post I explained how to secure static WordPress exports on AWS with Cognito, CloudFront, and signed cookies. This is the follow-up: a look at how the project itself came together with the help of Kiro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting point
&lt;/h2&gt;

&lt;p&gt;I'm comfortable working with AWS architecture, but I had little hands-on experience with CloudFormation. Writing a full stack by hand would have been slow and error-prone. For the hackathon I wanted to see how far I could get by asking Kiro to generate the stack for me.&lt;/p&gt;

&lt;p&gt;The initial prompt described the core idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 bucket for the static export&lt;/li&gt;
&lt;li&gt;CloudFront with signed cookies for protection&lt;/li&gt;
&lt;li&gt;API Gateway + Lambda to issue cookies&lt;/li&gt;
&lt;li&gt;integration points for Cognito through the Gatey plugin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first generated template wasn't perfect, but it was good enough to get the stack running within a few hours. I only needed to fix some details and adjust resource lifecycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reverse specification
&lt;/h2&gt;

&lt;p&gt;Once the implementation was working, I asked Kiro to generate a "reverse spec" of the actual system. This produced requirements, design, and task lists that matched what I had already built. It might sound redundant, but it was valuable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it confirmed the design was consistent,&lt;/li&gt;
&lt;li&gt;it gave me a checklist of remaining tasks,&lt;/li&gt;
&lt;li&gt;and it created documentation that I could share later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Extra features and validation
&lt;/h2&gt;

&lt;p&gt;Using the spec as a guide, I added missing pieces: cache policies, end-to-end tests, and deployment cleanup checks. I also asked Kiro to validate the system against the spec, which helped catch a few oversights.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I took away
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Kiro didn't magically solve everything, but it accelerated the boring parts - large CloudFormation scaffolds that I wasn't used to writing.&lt;/li&gt;
&lt;li&gt;Having a generated spec after the fact turned out to be a useful way to organize and document the project.&lt;/li&gt;
&lt;li&gt;With only limited CloudFormation background, I could still publish a complete SAR template in a short amount of time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're curious about the solution itself, see my earlier post: &lt;a href="https://dev.to/tothl74/static-wordpress-authentication-with-amazon-cognito-and-aws-sar-template-2j5j"&gt;Static WordPress authentication with Amazon Cognito and AWS SAR template&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kirodotdev</category>
      <category>kiro</category>
      <category>aws</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Static WordPress Authentication with Amazon Cognito and AWS SAR Template</title>
      <dc:creator>László Tóth</dc:creator>
      <pubDate>Fri, 05 Sep 2025 10:13:32 +0000</pubDate>
      <link>https://dev.to/tothl74/static-wordpress-authentication-with-amazon-cognito-and-aws-sar-template-2j5j</link>
      <guid>https://dev.to/tothl74/static-wordpress-authentication-with-amazon-cognito-and-aws-sar-template-2j5j</guid>
      <description>&lt;p&gt;Static sites are great. They're &lt;strong&gt;fast, cheap, and secure by default&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
But if you've ever tried to add &lt;strong&gt;login or user-only content&lt;/strong&gt; to a static WordPress export… you know the pain.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;/wp-login.php&lt;/code&gt; doesn't exist anymore. PHP is gone. And yet, users still expect a sign-in flow that feels smooth and professional.  &lt;/p&gt;

&lt;p&gt;That's exactly the challenge we faced - and here's how we solved it with &lt;strong&gt;Amazon Cognito + API Gateway + Lambda + CloudFront signed cookies&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Even Bother With Static WordPress?
&lt;/h2&gt;

&lt;p&gt;Static WordPress exports (via plugins, S3 + CloudFront, or Netlify) are becoming popular because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: HTML served directly from a CDN
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: no dynamic servers to manage
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: surface area is tiny
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the trade-off is obvious: all the built-in WP authentication features vanish.  &lt;/p&gt;

&lt;p&gt;We wanted the best of both worlds: keep WordPress &lt;strong&gt;static and fast&lt;/strong&gt;, but add &lt;strong&gt;real authentication&lt;/strong&gt; powered by AWS.&lt;/p&gt;




&lt;h2&gt;
  
  
  The AWS Approach
&lt;/h2&gt;

&lt;p&gt;Instead of bending WordPress to handle login, we let AWS handle it at the edge.  &lt;/p&gt;

&lt;p&gt;Here's the high-level design:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Cognito&lt;/strong&gt; handles user sign-up, login, MFA, and tokens.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway + Lambda&lt;/strong&gt; exchange Cognito tokens for &lt;strong&gt;CloudFront signed cookies&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront&lt;/strong&gt; enforces access, serving protected resources only to users with valid cookies.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No PHP callbacks, no secrets stored in WordPress. Just clean, serverless authentication.  &lt;/p&gt;




&lt;h2&gt;
  
  
  How It Feels for Users
&lt;/h2&gt;

&lt;p&gt;From the user's perspective:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They click &lt;strong&gt;Sign In&lt;/strong&gt; on the WordPress site.
&lt;/li&gt;
&lt;li&gt;They see a branded Cognito-powered login (integrated with &lt;a href="https://wordpress.org/plugins/gatey/" rel="noopener noreferrer"&gt;Gatey&lt;/a&gt; blocks).
&lt;/li&gt;
&lt;li&gt;On success, they get signed cookies behind the scenes.
&lt;/li&gt;
&lt;li&gt;CloudFront now lets them access members-only pages, media, or even entire routes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It feels just like a "normal" site, but under the hood it's 100% serverless.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quick Architecture Sketch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ User ] → [ WordPress (static) ]
       ↘ Sign-In → [ Amazon Cognito ]
                    ↘ Tokens → [ API Gateway + Lambda ]
                                  ↘ Issue Signed Cookies → [ CloudFront ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CloudFront becomes the gatekeeper. If your cookies are valid, you're in. If not, you're redirected to login.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Rocks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; - static WordPress stays lightning-fast
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; - Cognito &amp;amp; signed cookies &amp;gt; old-school PHP sessions
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; - runs natively on AWS infra
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt; - protect full sites or just specific routes
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly: it keeps your &lt;strong&gt;WordPress database completely out of the authentication loop&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Membership sites hosted statically
&lt;/li&gt;
&lt;li&gt;Documentation portals with role-based access
&lt;/li&gt;
&lt;li&gt;Hybrid sites where only certain routes need login
&lt;/li&gt;
&lt;li&gt;SaaS dashboards powered by WordPress as the frontend
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already using CloudFront, this pattern feels very natural.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Full Tutorial with Code &amp;amp; Screenshots
&lt;/h2&gt;

&lt;p&gt;This post was just the overview.&lt;br&gt;&lt;br&gt;
We wrote up the &lt;strong&gt;step-by-step guide with SAR template, Lambda code, and WordPress integration&lt;/strong&gt; here:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://wpsuite.io/blog/static-wordpress-authentication-made-simple-deploy-with-the-aws-sar-template/" rel="noopener noreferrer"&gt;Static WordPress Authentication Made Simple - Deploy with the AWS SAR Template&lt;/a&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Static WordPress doesn't mean static functionality.&lt;br&gt;&lt;br&gt;
With Cognito + CloudFront signed cookies, you can have &lt;strong&gt;speed, security, and scalability&lt;/strong&gt; - without giving up authentication.  &lt;/p&gt;

&lt;p&gt;Curious what you think: would you ever run WordPress in static mode if authentication "just worked"? Drop your thoughts below.  &lt;/p&gt;




</description>
      <category>aws</category>
      <category>cognito</category>
      <category>wordpress</category>
      <category>cloudfront</category>
    </item>
  </channel>
</rss>
