Post Syndicated from Matt Granger original https://www.youtube.com/watch?v=q0I_c-IlIMk
[$] Understanding Nix flakes
Post Syndicated from jzb original https://lwn.net/Articles/1094226/
Nix flakes are an
experimental feature of the Nix package-management
tool designed to build projects in a more self-contained and reproducible
way. Despite the feature’s experimental status, it has become increasingly
popular for open-source projects to publish flake.nix files that offer
predefined development environments and build automation even when those
repositories may not offer an upstream package or module for the NixOS Linux distribution. Although
Nix flakes have a complicated history, and the path for stabilization is
uncertain, flakes can provide useful capabilities for projects that choose to
include them.
Introducing full transaction detection for Cloudflare WAF
Post Syndicated from Daniele Molteni original https://blog.cloudflare.com/full-transaction-waf/
Today, we are expanding our web application firewall (WAF) by adding two new capabilities: full transaction detections and response rules. Full transaction detections evaluate each HTTP request alongside its response to identify evidence of exploitation. It helps answer both "Does this request look malicious?" and "What happened when the application handled it?" Response rules can then block the origin’s response before it reaches the requester.
These are valuable protections because the latest frontier models are uncovering vulnerabilities buried deep in widely used software, giving defenders clarity on what to fix — and attackers new paths to exploit. The recent php2shell vulnerability shows the stakes: a flaw in a common software component can put applications across the Internet at risk. AI agents scanning for vulnerabilities can be extremely persistent, adapting payloads using feedback, and chaining vulnerabilities, credentials, and permissions. An application's response can reveal whether an attempt worked and give an attacker information that helps them go deeper.
Inspecting incoming requests remains essential for stopping recognizable attacks before they reach an application. But some threats become clear only when the request is considered alongside what the origin returns. A suspicious input followed by a response exposing sensitive information tells a different story from the same input followed by a rejection or an error.
With these new capabilities, customers can use Cloudflare-managed protections or build their own policies combining request and response properties. This extends our always-on application security framework, with detection results available in Security Analytics to support investigation. Our first managed protections using this capability address the recently disclosed php2shell vulnerability.
And the best part? We are making these new capabilities generally available to all Cloudflare customers, including Free plans.
Request inspection is not enough
Cloudflare WAF protects websites and APIs with managed rules, custom rules, and rate limiting. Managed rules provide protection for known attack techniques and vulnerabilities while custom rules let teams create their own policies using parameters such as an IP address, URL path, headers, and request body. These controls operate at the request level to stop exploits or unwanted traffic from reaching the origin.
For many threats, this is the right place to act. However, treating every suspicious request as a confirmed exploit creates a difficult choice. Broad request signatures can catch more potential attacks, but they can also show “false positives”, such as matching legitimate traffic — which then breaks the applications. Deploying only rules that do not trigger false positives reduces that risk, but can leave more room for more ambiguous traffic to reach the server.
The response provides the missing evidence. Cloudflare can now correlate it with the request that produced it, so detections can account for the outcome of the entire HTTP transaction.
As an illustrative example, consider an application that lets users download files. An attacker manipulates the file parameter to request a private configuration file outside the permitted directory:
GET /download?file=../../config/database.ini
Request inspection can recognize this path traversal attempt and block it before it reaches the application. The request alone, however, cannot establish whether the application would expose the file. It might reject the request, ignore the traversal, or return an error. If the request reaches the origin, a response like this provides additional evidence:
200 OK
Content-Type: text/plain
[database]
username=app_service
password=EXAMPLE_SECRET
Full transaction detection provides a missing piece: it can correlate the attempted file access with response content characteristic of a private configuration file. Configuration-like text can legitimately appear in documentation or example downloads; combining it with a traversal attempt provides stronger evidence of sensitive data exposure than either signal alone. A response rule can then replace the origin response with a Cloudflare WAF block page and HTTP 403 before it reaches the requester, effectively blocking the exploit by preventing sensitive information from reaching the attacker.
Detection and mitigation are separate by design
Full transaction detection extends the always-on detection framework we introduced earlier this year. Detections analyze traffic and attach metadata to the request and response, rules then decide what to do with those results.
Separating those jobs gives customers visibility before they design a policy. Security teams can inspect detections in their own traffic, understand which endpoints and signatures are involved, and choose the response that fits their application. Similar to the approach for the request-based Attack Signature Detection, the outcome of the detections are stored in fields that can be accessed in the response custom rules or used in managed detections to block traffic.
Mirroring the request detection fields, the following new fields are added to our platform:
|
Field |
Description |
|
cf.waf.signature.response.confidence |
Confidence values associated with matching signatures |
|
cf.waf.signature.response.categories |
Categories associated with matching signatures |
|
cf.waf.signature.response.ref |
Signature reference IDs, up to 10 |
The first full transaction detections focus on exploit confirmation for high profile vulnerability. It correlates suspicious input with response signals that indicate an exploit may have succeeded.
We will expand coverage over time by supporting other use cases, including detecting data exposure and exfiltration signals. This is important for the Internet beyond any one application: defenses can distinguish probing from evidence of impact, while detection of exposed data and services can reach customers that do not have a dedicated security team tuning every WAF rule.
Create rules on the response
Detecting evidence of exploitation is most useful if you can act on it in real time. Response custom rules turn full transaction detections into inline protection by blocking a matching origin response before it reaches the requester, although it cannot undo actions already performed at the origin.
Security teams can now combine request and response properties with detection results to decide which responses to block. When a blocking rule matches, Cloudflare replaces the origin response with a WAF block page or a custom response.
Response phase controls are available in the Cloudflare dashboard at the bottom of the Security > Security Rules page, with both managed protections and custom rules.
We have released both managed and custom rules to all plans, including Free plans. Over time, we will follow the same approach we use for request detections, where managed detections for free plans focus on high-profile vulnerabilities, while paying customers get a richer catalog of detections.
Managed detections
All customers get the protection of the full array of transaction detections through the Cloudflare Managed Response Firewall Default ruleset, which is designed for a simple one-click deploy and simplified configurability. When a signature matches, the managed detection will block the response and return a standard WAF block page.
You can edit the Cloudflare Managed Response Firewall Default scope to run detections only on a portion of their applications, for example by excluding or restricting the detection to a specific path. Paying customers can use detection fields in custom response rules to create more tailored policies.
Custom rules
Custom response rules are designed to give customers full control of the rule logic. A useful rule can stop an administration interface from being exposed when an authentication gateway has not marked the request as internal. For example:
http.request.uri.path starts_with "/admin" and not http.request.headers["x-internal-user"][0] eq "true" and http.response.code eq 200 and http.response.headers["content-type"][0] contains "text/html"
This blocks only when an unauthenticated request targets `/admin` and the origin actually returns a successful HTML administration page. It does not block ordinary authentication failures, redirects, or non-administration traffic.
All customers can create up to three custom response rules supporting Log and Block actions. The fields and functions available in response to custom rules mirrors what your plan gives you access to in request custom rules already. Creating rules on the response body is not yet available.
Following the Attack Signature Detection approach, paying customers also have access to the outcome of attack detections through the cf.waf.signature.response.* fields listed above. These fields can be combined with other parameters (such as a hostname, URL path, source IP, request header) to enable protection on a single path, or limit the policy to application-specific context. We are currently rolling out the response fields to all our accounts. If you don’t have access to them yet, please contact your account team.
Investigating matching requests
When a managed or custom response rule logs or blocks a transaction, the event is available in Security Events. This means responders can trace any detection back to the full context of the request and the specific rule that took action.
At the moment, both request-only rules and full-transaction rules are shown together in the same analytics page. In Security Events, the events generated by response rules are part of the Managed Rules or Custom Rules service. You can filter events belonging to a specific rule ID in the relative rule list section.
Get started today
Full transaction detection is generally available for all zones proxying traffic through Cloudflare. To verify that you’re protected, go to Security > Security Rules in the Cloudflare dashboard. If you want to customize your policy, start by reviewing full transaction detections in Security Analytics, then create the response phase policy that fits your application.
Cloudflare deploys protections against php2shell vulnerability
Post Syndicated from Daniele Molteni original https://blog.cloudflare.com/php-vulnerabilities-waf-protection/
Today, Calif.io, Wiz, OpenAI and Quarkslab disclosed two vulnerabilities in PHP, tracked as CVE-2026-109618 and CVE-2026-109619 and known as php2shell. The vulnerabilities affect all web servers running PHP 5.4 or later and they may allow an attacker to cause denial of service, remote code execution, and data exposure when an application processes specially crafted HTTP traffic.
Cloudflare has been part of a coordinated effort to deploy mitigations to protect the Internet, working with PHP foundation, OpenAI and Wiz among others. Cloudflare has developed and deployed web application firewall (WAF) protections since early October 2026, which were deployed about 9 hours ahead of public disclosure. Starting on October 21 3:02 am UTC, Cloudflare customers using our free or paid WAF were protected by default against php2shell.
Cloudflare successfully deployed multiple mitigations for all its customers while the vulnerability was leaked before the official release date and we observed attack traffic targeting our customers. We observed how attackers were mutating the attack payload to try to bypass our protections by tracking the volume of matches and cross-referencing with the rule logic.
Protecting against php2shell required more than standard request-based rules. Request data alone does not always provide enough evidence to distinguish an exploit from legitimate traffic. The origin’s response adds context, helping identify whether an exploit succeeded while reducing the risk of false positives.
To deliver this protection, we developed full transaction detection, a new Cloudflare WAF capability that combines signals from the request and response within the same HTTP transaction. Response rules can then block a matching origin response before it reaches the requester. The php2shell protections are the first managed detections we have released using this capability.
Customers should patch their PHP repos even with WAF protections providing an additional layer of defense-in-depth mitigation. Our security analysts continue monitoring attack activity and update the rules when and if new techniques and variations emerge in the hours and days ahead. You can track new rules in the changelog.
The protections are available and deployed automatically on all plans with WAF deployed, including Free users.
What we know about the vulnerabilities
PHP is used by almost 70% of websites. The php2shell vulnerabilities affect the PHP runtime itself and can allow attackers to execute malicious code on vulnerable servers, expose customer data, or disrupt services. Because PHP underpins widely used platforms such as WordPress and Magento, these flaws could potentially affect a large number of applications across the Internet.
The two vulnerabilities involve how PHP handles memory when something goes wrong while processing a HTTP request. Normally, PHP allocates memory to store the data it needs to process a request, then releases it when that work finishes. If processing stops unexpectedly, for example because it runs out of memory, PHP fails to clean up the memory safely. These vulnerabilities arise when PHP handles an error and then tries to use data that was not fully set up or memory that has already been released.
An attacker can send specially crafted HTTP requests to trigger these conditions. Large requests are one way to put memory under pressure, but the problem goes beyond consuming server resources. By manipulating the data PHP encounters in this invalid memory, an attacker may be able to crash a PHP process, expose sensitive information, or execute code provided by the attacker.
The two vulnerabilities differ in when the unsafe memory access happens:
|
Vulnerability |
What goes wrong |
|
CVE-2026-109618 |
PHP runs out of memory and interrupts its work before some internal data has been properly initialized. During cleanup of that request, PHP may use this unfinished data as though it were valid. |
|
CVE-2026-109619 |
A fatal error interrupts a request, leaving PHP holding references to memory that is released when the request ends. When the same PHP process handles a later request, it may follow those outdated references and access memory that is no longer valid and expose sensitive data. |
These flaws are in the PHP runtime, so updating website code or a plugin(s) alone does not fix these vulnerabilities. Administrators need to update the PHP software running their applications. If a hosting provider manages PHP, ask the provider to apply the security update.
Administrators can follow the PHP advisory for affected versions and remediation instructions. Keep Cloudflare WAF protections enabled while patching. Restricting unnecessary uploads and limiting upload sizes can also reduce exposure, but these measures do not replace the PHP fix.
New rules
For Free customers, new rules have been released under the Cloudflare Managed Free Ruleset (Ruleset ID 77454fe2d30c4220b5701f6fdfb893ba). Free customers don’t have to take any actions to enable the protection. To override the ruleset behavior you can refer to our documentation.
|
Rule Description |
Rule ID |
|
Generic Rules – Anomalous Execution – 1 |
4e315666e8e344cdb64119a3b5ccf32f |
|
Generic Rules – Anomalous Execution – 2 |
00c10e6cc4da4bd08722adeebcd95984 |
|
Generic Rules – Anomalous Execution – 3 |
48ddf592361e4fdb97a8a85982dab691 |
|
Generic Rules – Anomalous Execution – 4 |
3556683d512a47f2937899c524b1a4c6 |
|
Generic Rules – Anomalous Execution – 5 |
da07c85852e34625bb478496302ede46 |
|
Generic Rules – Anomalous Execution – 6 |
19373a83abb840e18ab3ce5a7975ce1b |
|
Generic Rules – Anomalous Execution – 7 |
07f0b6ddaabf40b1b2042dade8d613fa |
Protection for paid plans has been released as part of the Cloudflare Managed Ruleset (Ruleset ID efb7b8c949ac4650a09736fc376e9aee). If you are on a Professional, Business, or Enterprise plan, review your Managed Ruleset deployment to confirm it’s deployed block mode.
|
Rule Description |
Rule ID |
|
Generic Rules – Anomalous Execution – 1 |
c1d409ad838f47f59446f21cc438d5dd |
|
Generic Rules – Anomalous Execution – 2 |
f9a45927414245e3a64bb12d0a0c2f64 |
|
Generic Rules – Anomalous Execution – 3 |
771c654ae1154d4daa72f4e1545d163c |
|
Generic Rules – Anomalous Execution – 4 |
217005865f0145f392300bac212afcc9 |
|
Generic Rules – Anomalous Execution – 5 |
38efdb17ea594501bb55a1d71867b12e |
|
Generic Rules – Anomalous Execution – 6 |
4148ae686fdb4d01be673fab9d9c073d |
|
Generic Rules – Anomalous Execution – 7 |
1389aa259617437392ce149c48143645 |
To better identify exploit attempts, Cloudflare developed full transaction detection, a new WAF capability that analyzes both sides of the same HTTP transaction. While some malicious payloads can be identified using the request alone, the response contains useful signals that can be used to create rules with higher confidence, reducing false positives. A matching full transaction rule can block the origin response before it reaches the requester. Learn how it works in our full transaction detection blog post.
The following rules have been deployed to the new Cloudflare Managed Response Firewall Default for customers on all plans, including Free:
|
Rule Description |
Rule ID |
|
Default block for High confidence Signatures |
afffe22785674c80a31875c848d2242a |
Note: rule descriptions will be updated soon.
Review events and customize protection
To analyze blocked requests, visit Security > Security Analytics > Events. Filter by the rule IDs in the table above and inspect the matched request, action, and path. Events identify whether the action came from a managed or custom rule. Customers who need to tailor the protection can update the scope of the Managed Ruleset to the parts of an application where it is relevant.
Update PHP and keep the protection enabled
Cloudflare customers using our Managed Ruleset are protected by default. We recommend following the advisory recommendation and applying the vendor update to your PHP repos as soon as possible while keeping the WAF protection enabled as an additional protection. Our WAF analysts will continue to update protections as new techniques emerge.
PHP patches released for two critical RCEs
Post Syndicated from jzb original https://lwn.net/Articles/1102014/
The PHP project has published PHP
versions 8.5.12,
8.4.27, 8.3.36 and 8.2.35 to address
two critical vulnerabilities that could allow unauthenticated remote code
execution.
Who is at risk: all PHP installations serving web requests,
including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. We
consider the risk highest for mod_php, with a demonstrated exploit where an
unauthenticated request can trigger the attack before any application code
runs.The vulnerabilities:
- RCE via OOM corruption, CVE-2026-109618 (GHSA-w8hw-w9fx-j79w): out-of-memory
handling can interrupt PHP while internal request data is only partially initialized. Request cleanup may then treat the invalid data as valid.- RCE via stale global state, CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp): request-owned
internal state can survive after its backing memory has been freed. A later
request handled by the same worker may use that stale state before normal
initialization resets it.
PHP versions older than 8.1 will not receive updates from the project, though
the project has provided some patches for PHP
7.4, PHP
8.0, and PHP
8.1 to assist in creating backports. According to the
announcement, Linux distributions and vendors received patches in advance, so
updated packages should be coming soon.
Four stable kernels for Wednesday
Security updates for Wednesday
Post Syndicated from jzb original https://lwn.net/Articles/1102005/
Security updates have been issued by AlmaLinux (bubblewrap, emacs, gimp:2.8, glibc, jackson-databind, kernel, kernel-rt, librabbitmq, openexr, openssh, postgresql:16, postgresql:18, python3, resteasy, wireshark, xorg-x11-server, and xorg-x11-server-Xwayland), Debian (ca-certificates, firefox-esr, git-lfs, and libssh), Fedora (aom, assimp, bind, bind-dyndb-ldap, freerdp, ghostscript, gopass, gopass-jsonapi, ImageMagick, libpng12, libpng15, nebula, perl-GD-SecurityImage, perl-Net-IDN-Encode, perl-Net-Whois-Raw, rust-backtrace, rust-object, rust-object0.37, rust-object0.38, rust-object0.39, rust-ruzstd, and xen), Gentoo (ca-certificates), Mageia (x11-server, x11-server-wayland, tigervnc), Oracle (bubblewrap, ca-certificates, emacs, fetchmail, gimp:2.8, hostapd, jackson-databind, librabbitmq, lrzsz, openexr, openssh, openssl, postgresql:18, python-urllib3, python3, python3.12-urllib3, resteasy, webkit2gtk3, wireshark, and xorg-x11-server-Xwayland), Red Hat (.NET 8.0, dogtag-pki, flatpak-builder, ghostscript, glycin-loaders, go-toolset:rhel8, golang, gvfs, jackson-core, jackson-databind, librsvg2, multiple packages, pki-core, pki-core:10.6, sudo, xorg-x11-server, and xorg-x11-server-Xwayland), Slackware (c-ares, ca-certificates, mozilla-firefox, mozilla-nss, mozilla-thunderbird, and python-certifi), SUSE (agama, aspell, bcel, bind, bouncycastle, busybox, chromium, containerd, coredns, cosign, cpp15, cups-filters, cyrus-sasl, fetchmail, firefox, gcc13, gh, ghostscript, gitoxide, glibc, go1.26, go1.27, google-osconfig-agent, grafana, grok-build, hashcat, hawk2, helm, ImageMagick, inspektor-gadget, iperf, jupyter-jupyterlab-templates, kernel, kernel-devel, libheif, libpng16, librsvg, libX11, libXi, libxls, libXpm, libxreaderdocument3, mutt, ntfs-3g_ntfsprogs, openssl-1_0_0, openssl-3, openvpn, pacemaker, perl-DBI, perl-XS-Parse-Keyword, pgvector, podman, putty, python-anyio, python-hpack, python-joserfc, python-jwcrypto, python-oauthlib, python-PyJWT, python-tornado6, python-urllib3, python-virtualenv, python-WebOb, python3, python311, rekor, squid, strongswan, stunnel, suseconnect-ng, tinyproxy, traefik, unbound, varnish, virtiofsd, webkit2gtk3, and xwayland), and Ubuntu (ca-certificates, dotnet8, dotnet10, dotnet11, protobuf, rust-sudo-rs, squid, squid3, and xz-utils).
How Commerce.com and Cloudflare are getting storefronts ready for AI agents
Post Syndicated from Jenny Lea original https://blog.cloudflare.com/webmcp-commerce/
AI can write code and pass the bar exam, but it still struggles to buy a pair of shoes online.
That’s because websites were built for humans, not agents. Most agents that shop for someone today work from a site’s HTML — they look at the page, guess which button does what, click, and try again when they get it wrong. This process is slow, uses a lot of tokens, and something as seemingly innocuous as a theme change can break it.
Enter WebMCP: a browser standard from Google that gives AI agents structured tools on a page, like search_products. Instead of hunting for buttons, the agent calls the exact tool it needs directly, making shopping faster, cheaper, and far more reliable. Because WebMCP is still an experimental proposed browser standard in early preview, it’s currently available behind experimental Chrome flags (chrome://flags/#enable-webmcp-testing), in Chrome Origin Trials, in some agentic browsers, and across developer environments like Cloudflare Kitesurf.
In August, we launched edge implementation of WebMCP in beta. Turn it on, and Cloudflare injects a tiny script at the edge to make those tools available automatically, without site owners writing a single line of code.
Commerce.com, a flexible commerce platform built for the age of AI, already uses Cloudflare to run their almost 100,000 domains. So when the preview came out, they asked: Can we turn this on for all of our stores at once?
Here’s why Commerce.com wanted WebMCP, how we built edge-level opt-outs to give every merchant control, and what we learned along the way.
Why Commerce.com wanted WebMCP
Kristina Pototska, Product Management Director at Commerce.com, explains why this matters for storefronts:
“Merchants keep asking us how they can keep up with agentic shopping. When a shopper asks an agent to find something, merchants want their store to be in the answer. They want to keep the customer, keep control of the checkout, and do it without rebuilding their site. WebMCP helps with all three. The agent gets real tools to search products, check details, build a cart, and get a checkout link, so it doesn’t have to guess its way around the page. The human shopper stays on the merchant’s site, and the merchant keeps the relationship.
We wanted to turn this on in a secure way, and without asking merchants to edit their theme or do anything by hand. That’s where the Cloudflare partnership worked perfectly.
WebMCP also works side by side with our server-side MCP, and together they cover the different ways people shop with agents. Server-side MCP supports agents that connect to a store directly, like an assistant helping someone shop across several sites. WebMCP supports agents that work in the shopper’s browser. It’s the same set of shopping tools in both cases, so merchants don’t have to choose between the two or manage them separately.”
Under the hood, this integration relies on two key principles. First, the WebMCP tools execute directly inside the shopper's active browser session on the storefront's domain, ensuring the agent sees the same prices and cart. No credentials go to a third party, and the visit still happens on the merchant's site. Second, Cloudflare serves as the edge delivery layer for Commerce.com’s backend MCP server, proxying tool definitions and actions unchanged so merchants maintain full control over their tool logic.
What a shopper's agent sees
When visiting an enabled Commerce.com storefront, an AI assistant no longer has to guess how to navigate the site. Instead, it can instantly discover tools via WebMCP.
Suppose you tell your agent: "Find me a waterproof trail running shoe under $140 in size 10 and add it to my cart."
Without WebMCP: The agent attempts to simulate human clicks, only to get blocked by cookie banners, misinterpret variant drop-downs, or get tripped up by bot challenges that try to distinguish automated traffic from real customers.
With WebMCP: The agent detects the store's tools on document.modelContext and makes two clean calls:
search_products({ query: "trail running shoe", max_price: 140, size: 10 })add_to_cart({ product_id: "shoe_123" })
Because the agent runs inside your active browser session on the store's domain, your cart updates in real time. Commerce.com’s backend MCP server determines the commerce flow: when you’re ready to complete the purchase, you click checkout yourself — keeping your payment details secure and leaving you in complete control of the final buy.
What we built together
When Commerce.com asked to turn on WebMCP across almost 100000 storefronts, we ran into a practical challenge: WebMCP was originally designed as a single on-or-off switch for an entire domain zone.
Commerce wanted to enable our mcp-server-client toolpack, which acts as an edge bridge — proxying tool definitions and requests directly from Commerce.com’s backend MCP server to the visitor's browser. Because Commerce.com uses Cloudflare for SaaS to host thousands of merchant vanity domains on shared zones, we needed a way to deliver this platform-wide while giving individual store owners an easy way to opt out.
1. On for all stores on Commerce.com, with an opt-out for each merchant
Instead of building a complex custom allowlist, we hooked WebMCP into the existing Cloudflare concepts of Configuration Rules and custom hostname metadata.
Commerce.com turns WebMCP on for their main zone, then adds a rule at the edge that checks merchant metadata. If a merchant flips the "opt-out" switch in their Commerce.com dashboard, Cloudflare bypasses WebMCP for that specific storefront automatically:
{
"action": "set_config",
"expression": "cf.hostname.metadata.webmcp_opt_out eq \"true\"",
"action_parameters": {
"webmcp_enabled": false
}
}
Because Cloudflare evaluates these rules at the edge before serving the page, an opted-out store gets zero extra latency, no remote lookups, and no injected scripts.
2. Tailored endpoints and safe fallbacks
As with any preview release, working with a partner in the real world revealed a few practical details we hadn't accounted for:
Custom MCP paths: When the mcp-server-client toolpack was enabled, our bridge originally expected to find every site's MCP server at /mcp. Commerce.com’s server lives at /api/mcp. To handle this, we added a configurable MCP URL setting at the zone level. When this is set, we pass the custom path into the injected script tag:
<script type="module"
src="/.webmcp/bridge.js"
data-packs="c2pa,mcp-server-client"
data-mcp-url="/api/mcp"></script>
Seamless fallbacks: If a store's MCP server is offline or a customer's browser doesn't support WebMCP, the script exits. The storefront loads normally and human shoppers aren't affected.
What's next
We'll keep investing in WebMCP as the standard evolves, starting with helping agents find a site's tools more easily. Cloudflare and Commerce.com will continue to work together to make shopping with agents fast, reliable and safe for both merchants and shoppers.
If you're at Cloudflare Connect in San Francisco on October 21, 2026, come see us at Getting your storefront agent ready for peak season, a panel discussion featuring Kristina Pototska (Product Management Director, Commerce), Justis Blasco (CTO and Co-Founder, Popmenu), Ross Harvey (Head of Infrastructure, Fruugo), and Josh Mills (VP of Engineering, Gopuff).
The Korean War: 1871
Post Syndicated from The History Guy: History Deserves to Be Remembered original https://www.youtube.com/watch?v=xb7Aa_rcLI0
Workshop on Economics and Information Security (WEIS) Archive
Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2026/10/workshop-on-economics-and-information-security-weis-archive.html
There’s a new archive of all the papers from twenty-five years of the Workshop on Economics and Information Security (WEIS).
Really nice resource. It’s fun to reread my 2002 essay on the economics of information security.
Preparing young people for frontier technologies: Our new partnership with the UK government
Post Syndicated from Dan Fisher original https://www.raspberrypi.org/blog/preparing-young-people-for-frontier-technologies-our-new-partnership-with-the-uk-government/

Around the world, governments are grappling with the same question: how do you prepare young people for careers shaped by emerging technologies? In the UK, part of the answer is TechFirst, and we’re proud to be playing a central role in it.
Through the new TechFirst partnership with the Department for Digital, Culture, Media and Sport (DCMS), we are expanding Ada Computer Science, the free computing education platform we have built with the University of Cambridge for UK students and teachers. It’s one of the ways the UK government plans to bring frontier tech education to a million secondary students (11- to 18-year-olds) over the next three years.
What’s happening in the UK
TechFirst is the UK government’s £187 million tech skills initiative, designed to open up pathways into the country’s tech sector. It supports people at every stage, from students in school to university researchers and career changers.
Backed by major tech employers, the programme focuses on six frontier technologies: cybersecurity, artificial intelligence, quantum computing, engineering biology, semiconductors, and advanced connectivity technologies.
Ada Computer Science sits at the heart of TechFirst’s schools strand. With DCMS funding, we’re adding new content and features to the platform, and everything stays completely free.
For the first time, Ada Computer Science now covers ages 11 to 19, with new teaching and learning materials for 11- to 14-year-olds added alongside everything we already offer for ages 14 to 19. Thanks to the new materials, students can start exploring computing and frontier technologies earlier, and build on that learning all the way through to the end of secondary education.
Alongside the expansion of the Ada CS platform, DCMS is funding Regional Delivery Partners to bring hands-on technology activities into secondary schools across the UK, giving students practical experience and a real sense of where a tech career could take them.
Beyond the economic opportunities that understanding frontier technologies opens up for young people, gaining this knowledge and skills helps young people have agency and power in a world where technology plays an ever greater role in their lives.
We are pleased to offer the new frontier technologies materials, like all our teaching and learning resources, at no cost to teachers and students. This is one way in which we support equal access to a high-quality computing and AI education for all young people.
What’s coming next
We will add new content and features to Ada CS in phases, including:
- Learning content on artificial intelligence, cybersecurity, quantum computing, engineering biology, semiconductors, and advanced connectivity technologies
- Learning content designed specifically for 11- to 14-year-olds, covering a wide range of computing topics and building digital literacy
- Interactive student challenges and self-paced projects
- Careers content, including real-life case studies
- Links to workshops, events, and activities run by Regional Delivery Partners
Find out more
If you’re a teacher or student in the UK, you can explore the first TechFirst content release on the Ada Computer Science website. Create a free account to be first to hear about the new content and features.
The post Preparing young people for frontier technologies: Our new partnership with the UK government appeared first on Raspberry Pi Foundation.
Мирослава Кацарова: В музиката се откриваш като свободен човек
Post Syndicated from Ина Иванова original https://www.toest.bg/miroslava-katsarova-v-muzikata-se-otkrivash-kato-svoboden-chovek/

Мирослава Кацарова е сред най-запомнящите се гласове в българския джаз през последните две десетилетия. Умно, елегантно и с безупречна дикция тя пее на няколко езика, сред които български, френски и португалски, а предаванията ѝ по Радио Jazz FM Singin’n’swingin и Desafinado информират и са предизвикателство за истински претенциозните меломани.
Мира Кацарова и нейната компания „Блу Ем“ са лицето на „Пловдив Джаз Фест“, на чиято сцена ежегодно музицират световни артисти – икони в импровизационната музика. Да формира вкус и да създава жива, дишаща общност е сред талантите ѝ; това обяснява защо за концертите на „Пловдив Джаз Фест“ се стича публика от цялата страна.
И макар че невинаги е живяла в Пловдив, за Мирослава Кацарова градът е един от важните топоси в личната ѝ география.
Преживявам този град като отражение на моите спомени от детските години. Днешното пренаселване на градовете е враждебно, губи се очарованието на тази романтична провинция, в която аз съм израснала. Къщите в Пловдив бяха с дворове, бяха естествена градина със смокинови и нарови дръвчета, с асми, които проектираха дантели върху камъните. Моята баба гледаше рози и хортензии. Помня ароматите им, както и мириса на камък и дърво. А Старият град тогава беше фокус, хората отиваха там, за да се разхождат.
Нейният дядо е футболната легенда Никола Щерев – Старика, един от най-важните играчи във футболния клуб „Ботев“ Пловдив през 20-те и 30-те години на миналия век. Той създава първата детско-юношеска футболна школа в България, внасяйки от Виена модел за изграждането на младите спортисти в екип. Съвместявал е тази мисия с кариерата си на активен футболист и капитан на отбора. Никола Щерев се е интересувал от олимпийски спортове и е водил кореспонденция с бащата на съвременните олимпийски игри Пиер дьо Кубертен. Притежавал работилница, произвеждаща ски, а там, където днес са Пеещите фонтани, е имало естествено езеро. През зимата, когато замръзвало, то се превръщало в пързалка, неотменна част от градската култура. Никола Щерев откривал сезона – на кънки и с грамофона, който донесъл на съпругата си Мария от Париж.
Имали са много красива любов с баба, която е била с 13 години по-млада от него.
Никола е бил и планинар, запален турист, който през зимата е търсил възможност със специални ски да проправя пътеки извън пистите, стигал е по този начин от Пловдив до Пампорово.
Дъщеря му Снежанка, майката на Мира Кацарова, от пет-шестгодишна се е спускала красиво и стремглаво по известната днес писта „Стената“. Семейната легенда твърди, че заради близкото познанство на Никола Щерев с влиятелни генерали връх Снежанка е кръстен на „най-малката скиорка“. А разбира се, и заради факта, че по онова време е бил вечно бял.
Майка ми до много късни години караше ски в този елегантен стил, който вече не се вижда. Аз също бях научена на него – той е фин, без агресия, но по пистите вече има съвсем други отношения.
Говорим за отминалите кодове на старата градска култура, но нейните производни са свързани със съвременността. Тази чувствителност към вкусовете, ароматите, утопичното е силно осезаема в текстовете, които Мира Кацарова сама пише за авторските си песни.
Песните, които се опитвам да изпълнявам, са свързани с пределите между световете. И аз внимателно навлизам в тази реалност, опитвам се да я проучвам издълбоко. Не искам да изляза и да пея като шампион, не харесвам този вид отношение към музиката. Когато пея, искам това да е една човешка история – с цялата ми уязвимост, съмнения, несигурност и страхове. В музиката ти се откриваш като свободен човек, без предразсъдъци и съображения с дребното. С музиката можеш да кажеш неща, които са неназовими, затова аз възприемам тези песни като сънища, които не си спомняш докрай.
Философските търсения на Мирослава Кацарова са в диалог с идеите, стабилизирани от богословското ѝ образование. Преди това в Езиковата гимназия тя учи френски език и е пленена от символистите, от декадентския чар на Рембо и Бодлер, а и от екзистенциалистите – чете Сартр, Камю, търсейки себе си.
Бях истински Боготърсач. Борих се с идеите на екзистенциализма, че смисъл няма, че сме като Сизиф. И когато прочетох Ортодокса на Павел Евдокимов, осъзнах, че много дълбоко споделям философията на православното християнство, но не по начина, по който е профанизирана тази дълбока идея. Разбрах, че съм религиозен човек и че откривам човешкото във всичките му проявления като сила, тъй като православното християнство ни спасява от онзи плашещ, непристъпен Бог. Така стигнах и до изкуството като смисъл на човешките отношения. За мен това са музиката, литературата, живописта, киното, театърът – те са моят смисъл. Те са начинът тихо, ненатрапливо да пренареждаме този свят.
Успоредно с всичко, което преживява и търси, Мирослава Кацарова пее.
Открих джаза в гимназията през песните на Били Холидей, макар че вкъщи майка и татко слушаха инструментален джаз. После Майлс Дейвис и Джон Колтрейн, после Чик Кърия, Хърби Хенкок, Кийт Джарет, Йелоу Джакетс, Ян Гарбарек – този свят ме завладя лавинообразно. Благодарение на тях усетих абстракцията. Много ходех по джаз срещи и поисках да пея, но нямаше кой да те научи тогава как да импровизираш с гласа си. Единствената голяма джаз певица по онова време беше Йълдъз Ибрахимова; Камелия Тодорова не беше в България през 80-те. И аз се пуснах на един джемсешън, знаех няколко джаз стандарта от слушане, знаех блус схемата пак от слушане, без да съм наясно, че това е блус схема. Импровизирах. Аналитична съм и това много ми помогна, но цялата работа беше един огромен късмет, попаднах точно на хората. Чуха ме Рупето, Веселин Веселинов – Еко, Васил Петров, по-късно Христо Йоцов. Аз не наричах себе си джаз певица, казвах, че пея джаз, без да ползвам дефиниции.
В изкуството обаче късметът на начинаещия е само първата стъпка за възможната реализация. Професионалистите в една сфера виждат таланта, но оценяват вътрешната подготвеност на артиста да продължи личните си търсения. Постепенно Мирослава Кацарова намира своята сцена, канена е да прави гигове, следва концертиране, създаване на албуми, джазът се превръща в път.
Работата ѝ с публики и желанието ѝ да променя средата естествено я отвеждат до идеята за истински форум, свързан с импровизационната музика. През 2015 г. стартира „Пловдив Джаз Фест“ – Мира в щастлива колаборация със съпруга си Танко Кацаров използва всичките си лични контакти за да осигури допълнителни спонсорства.
Тогава чух новия албум на Кърт Елинг, в който има една песен по текст на Джеймс Джойс – Where love is, – и си рекох: хайде да доведем тук артисти, които ни вълнуват до сълзи. И понеже имам луд мъж, той се обади на агентката на Кърт Елинг. Оказа се, че има свободна дата на 2 ноември. Така започна всичко.
Оттогава тя програмира фестивала, а българските меломани имат шанса да чуят на живо иконични артисти, като в последните години е добавено и лятно издание под открито небе.
По време на „Пловдив Джаз Фест“ като съпътстваща програма млади изпълнители получават възможност за творчески работилници и джемсешъни, както и за близък, неформален контакт със знаменитостите. Ежегодно в един от фестивалните дни тематично е подбрана и литературна среща.
Как обаче става селекцията? Още повече когато се налага програмата да бъде синхронизирана с тежкия график на световен артист, обичайно запълнен за няколко години напред. Влиятелните имена в музиката, както и във всяко изкуство внимателно подбират сцените си и тук негласно, но императивно важи репутацията. Изграждането на доверие между екипите на изпълнителя и фестивала е многогодишен процес, в който няма място за грешки.
Сложно е на много нива, но аз тръгвам винаги от мечтата. Слушам страшно много музика и мога да кажа, че интуицията на един професионалист се отглежда. Ако не залагаш на суетна показност, а на реален интерес – а при мен е така, аз не мога да живея без тази музика, – виждаш, че сетивата ти се изострят за тенденциите. После започва другото: дали можем да си ги разрешим финансово. Ако е на ръба, ние го правим. Рисково. За световните имена се налага да съобразим и дали артистът е на турне в Европа – обратното е убийствено за бюджета на един фестивал.
За да се случи магията на сцената, договорите имат технически и хоспиталити изисквания, които – заедно с обезпечаване на финансирането – изискват целогодишен труд.
Тази година на 6, 7 и 8 ноември в Пловдив ще концертират Арън Паркс, Шай Маестро, Елина Дуни, Ема Смит, Дженк Ердоган, а първият ден е отделен за специален проект, посветен на 100-годишнината на Майлс Дейвис по идея на Росен Захариев – Роко – ще участват Стив Хамилтън (пиано), Васил Хаджигрудев (контрабас), Борислав Петров (барабани) и двамата гост-музиканти Петър Момчев (тенор саксофон) и бийтбоксърът Александър Деянов – Скилър.
Какво според Мирослава Кацарова е важно на сцената? Самоконтрол, концентрация, за да следиш всеки тон на колегите си, и борба с егото.
Имам свободата да избирам с кого да работя, и съм благодарна, че това са музиканти, които са много талантливи, можещи и освен че имат любопитство към света, те са откриватели и приключенци. Всичко това ги отличава от занаятчиите. Обменяме идеи и по този начин растем.
Хората, които тихо и кротко променят средата, формират общности и задават посоки, в които има смисъл да тръгнем заедно. Тук ви срещаме с тях. Това са „Тези хора“.
Любов в ада
Post Syndicated from Вера Краузе original https://www.toest.bg/lyubov-v-ada/

„Ергенът“ идва всяка година точно като сезонните алергии и с приблизително същия ефект върху организма. Напролет сервират рози и романтични сълзи по поръчка, наесен пък скандали, за които човек се срамува, че изобщо ги знае. После социалните мрежи избухват с гневни коментари: „Ужас, това повече няма да го гледам.“ До следващия епизод.
С годините зрителите са приели неписан договор с продукцията: едните ще прекрачват грубо границите, а другите ще сядат пред екрана. Това е най-странното постижение на формата.
Погазването на етични норми се е превърнало в зрителско очакване, което от своя страна служи на продуцентите за алиби.
Само че тазгодишният „есенен Ерген“ поставя въпроса докъде може да стигне това алиби. Има основателни причини да не го подминаваме с умора. Защото в ефир участничка говори за самоубийство, друга преживява криза, наложила лекарска намеса, а заплахите за физическа саморазправа стават все по-брутални.
Когато психическата криза стане телевизионен сюжет
В епизодите от 29 и 30 септември 2026 г. една участничка е отчаяна, защото е принудена да спи в стая с петима мъже без нейно съгласие. Тя има порив да напусне предаването, а след това изрича желание за самоубийство. Участничката споменава и начина. По време на сцената не се появява информация къде зрителите, които преживяват суицидна криза, могат да потърсят помощ. Действителното психическо състояние на участничката не може да се установи от телевизионните кадри. Остава неясно дали е просто фраза, или наистина симптом на крайно отчаяние. Но само по себе си изказването е достатъчно тревожно, за да постави въпроса за отговорността на продукцията.
Световната здравна организация има ясни професионални препоръки за медийното представяне на суицидни мисли и поведение. Сред тях са избягването на сензацията, ненужното повторение и конкретизирането на метода за самоубийство, както и предоставянето на информация за достъпна помощ. Изследвания показват, че начинът на медийно представяне може да увеличи рисковете за уязвими хора или обратно – да има предпазващо въздействие.
Тези препоръки сами по себе си не представляват законова забрана. Те съществуват именно за ситуации, в които редакционното решение може да има последствия отвъд непосредствения зрителски интерес. Защо информацията за помощ не е намерила място в монтажното решение?
Няколко дни по-късно друга участничка преживява тежка криза пред камерите. Състоянието ѝ се влошава, тя крещи неистово, че умира. Впоследствие има лекарски екип на терен. Медицинска помощ очевидно е потърсена. Това е важно и трябва да бъде отбелязано. Но остава другият въпрос:
защо момент на тежка криза се превръща в публично зрелище? В една телевизионна продукция камерите могат да бъдат изключени.
Кадрите могат да останат неизлъчени. И в двата случая отговорността не може да бъде прехвърлена върху участниците.
„Ще ти разбия главата“, или речникът на последния сезон
Психическите кризи далеч не са единствената тревожна особеност. Вербалната агресия между участниците твърде често придобива характер на открита заплаха за физическа саморазправа. Особено тревожна е конкретността на заплахите, които се отправят в ефир. Това не са абстрактни обиди, а подробно описани сценарии на насилие: разбити глави, влачене по пода, насилствено подстригване, затваряне в багажници.
Няма нужда да гадаем дали заплахите биха били изпълнени. Достатъчно е, че са произнесени и излъчени. Разбира се, в риалити телевизията има жанрово очакване хората да се карат и напрежението да ексалира. Заплахата за физическа саморазправа обаче е нещо друго: тя е насочена към тялото на конкретен човек и законът я третира като престъпление, когато може да събуди основателен страх.
Още по-показателно е, че регулаторът вече е изразявал опасения за съдържанието на формата. През септември 2025 г. Съветът за електронни медии (СЕМ) установява нарушения на Закона за радиото и телевизията в „Ергенът: Любов в рая“. В по-късни документи на СЕМ се разглеждат проблемни сцени, включително вербална агресия и расистки коментари. Въпросът за границите на допустимото следователно е поставян и преди. Сходни прояви обаче продължават да намират място в ефир.
Особено показателни са конфликтите, в които личните нападки прерастват в ксенофобия.
Няколко от участничките многократно приписват на украинката в предаването негативни качества, които обясняват с произхода ѝ. Звучат и обобщения, че молдовките и украинките са „ескорти в Дубай“, а „наглите“ украинки трябва да знаят мястото си и да „бъдат по-ниски от тревата“.
Зад обидните стереотипи прозира една по-дълбока претенция за мнима власт: правото да определяш мястото на другия. На един човек се внушава, че произходът и съдбата на бежанец задължава да бъдеш по-тих, смирен, благодарен за мястото, което е „позволено“ да заемеш. Сякаш равноправието е жест на благоволение, който едни могат да окажат, а други трябва да заслужат. Случайността на месторождението става основание за морална присъда, а географията получава правото да определя характера.
Европа познава добре тази логика от миналото, когато нацизмът я превърна в идеология. В телевизионния рай тя се появява в умален, привидно безобиден вид, като поредна реплика с коктейл в ръка край басейна. При това стереотипът за „ескортите“ не е никак невинен, защото омаловажава реалната експлоатация, на която жени от всички страни от бившия Източен блок (вкл. България) нерядко стават жертва.
От персонаж към карикатура
Hurt people hurt people, гласи една популярна формула: наранените хора нараняват. Не знаем какво стои зад нечии крясъци, нито какви лични истории или ескалации, предизвикани от изолирания живот в имението, остават извън кадър. Но когато сезон след сезон се моделират все по-трайни и еднотипни фигури, трудно можем да говорим за непреднамереност на продуцентите.
Парите например отново заемат централно място в представите за любов и партньорство. Една от участничките се самоопределя като „жена трофей“ и почти във всеки епизод подробно излага финансовите си очаквания. Друга, с театрално преувеличен руски акцент, предлага семинари, учудващо дублиращи вече позната „търговска марка“ за такива обучения.
В това саморазбиране има елемент на еманципация. Жените открито заявяват желанията си, определят условията на партньорството и не се извиняват за материалните си претенции. В крайна сметка свободата предполага и правото на личен избор, който не всекиму се харесва или се вписва в дадени очаквания. Странно е обаче, когато независимостта изисква зависимост от платежоспособността на партньора.
Към тази галерия се прибавя и друг добре разпознаваем телевизионен образ: жената, която крещи и обижда вулгарно. Така между „жената трофей“ и „агресивната, вечно готова за конфликт жена“ (а.к.а. „женска злоба“, както се нарича във форуми и синхрони) се наслага все по-траен образ на жената като карикатура.
Тук се проявява и един от най-парадоксалните ефекти на икономиката на вниманието. Публиката може да осъжда видяното и едновременно с това да допринася за разпространението му. Всеки скандален откъс получава нов живот като повод за спор в социалните мрежи. „Ергенът“ продава карикатури. Социалните мрежи ги превръщат в доказателство, че карикатурата е реалност. Голяма част от заплахите от една участничка към друга са наречени „заслужено наказание“.
Обществото получава тревожен речник за отношенията между хората и интернализираната мизогиния.
Няма основание да приписваме на телевизионно предаване отговорност за насилието в обществото ни. Дългосрочно погледнато обаче, екранът може да притъпи ухото към него. Първата агресия смущава, втората звучи познато, а десетата вече е повод за забава. В един момент зрителите не се питат защо някой унижава друг човек пред милиони зрители, защо някой има тежка криза в екранно време, а изпитват тръпка какво ще се случи в следващия епизод.
Най-лесният отговор на тази критика е, че никой не е принуден да гледа. Публиката има избор. Участниците са пълнолетни и доброволно са се съгласили да бъдат снимани. Всичко това е вярно. И нищо от него не отменя редакционната отговорност. Съгласието за участие в телевизионен формат не прави всяко последващо решение на продукцията етично. Телевизионният оператор има власт върху кастинга, условията на снимане, монтажа и разпространението. Тази власт предполага и отговорност. И тук никой не очаква от риалити предаване да преподава уроци по здравословни отношения. Но
от една национална телевизия можем да очакваме поне да различава човешкото страдание от телевизионната атракция.
Защото това, с което сме свикнали, невинаги е това, което трябва да приемаме. И защото най-опасната граница не е тази, която телевизията прекрачва пред очите ни. А тази, която постепенно преставаме да забелязваме.
Темата за психичното здраве е важна за нас. Ако вие или ваш близък минава през трудности и има нужда от психологическа подкрепа в криза, може да се свържете със спешните служби на номер 112 или да намерите специализирани линии за подкрепа за България в сайта Find A Helpline.
App stability at scale with a layered defense
Post Syndicated from Grab Tech original https://engineering.grab.com/app-stability-at-scale-with-a-layered-defense
Introduction
Artificial intelligence (AI) coding assistants have changed how fast we can ship. They have not changed how mobile users experience a crash. That gap is the pressure every mobile stability program now operates under.
The Grab superapp, which millions of users across Southeast Asia use to book rides, order food, and more, operates at a large scale. On Android alone, it spans millions of lines of code, with many engineers shipping code into every release on a weekly release cycle. Maintaining app stability is not just a technical goal; it is a product commitment to those users. With the rise of AI coding assistance, the volume of change in every release has grown, and so has the number of ways a single change can break something in an already large codebase.
At this scale, crashes leaking into production are an ongoing risk. A high volume of merge requests lands every week across many product teams, many shipping features behind flags that are switched on independently of releases. Any one of those changes can introduce a crash. Most of the time, the stack trace points straight to the responsible change and team. The hard cases are the exceptions: crashes without a usable stack trace, such as native crashes without debug symbols, where finding the cause means cross-referencing release timelines, flag rollouts, and session metadata.
The cost of a crash is also steeper on mobile than on the web. A web fix can go live in minutes; a mobile crash that ships stays on users’ devices. With more than 100 million downloads on Google Play as of October 2026, not every user has auto-update enabled, and until a force update reaches them, some will run a broken version for months. Meanwhile, the crash degrades their experience, drags down the crash-free session rate, and can hurt the app’s ranking on Google Play. If it is severe enough to need a hotfix, the team also has to prepare an out-of-cycle build, pulling time away from planned work.
We keep the Grab superapp stable with a set of layered practices. Data points and tooling examples come from Android. The Grab iOS app follows the same strategy with platform-equivalent tooling (SwiftLint in place of Android Lint), and both apps share one release pipeline for Grab Early Access (GEA), our early access build, as well as staged rollout, production monitoring, and crash triage.
A layered defense for app stability
Our strategy is rooted in a shift-left mindset: the earlier we catch a crash, the cheaper and less disruptive it is to fix. A crash caught by a lint rule costs nothing. A crash caught in GEA takes an engineer fewer hours to fix. A crash that reaches production costs user trust. That is why we invest most heavily in prevention: the goal is to stop crashes before they reach production, not to fix them there.
The system is a series of filters, each anchored to a specific phase of the feature development lifecycle, so the right check runs at the right time, and a crash that slips past one layer has another waiting downstream.

The colors mark the three phases on the stability side: prevention (pre-merge through pre-prod), the release gate (staged rollout and feature flags), and response (post-release).
Prevention: Our primary line of defense
Lint checks: Stopping crashes at the code level
Lint is the cheapest layer we have: static analysis that flags unsafe patterns, application programming interface (API) misuse, and likely crashes before the code ever runs. We use Android Lint on Android and SwiftLint on iOS. Both run in continuous integration (CI) on every merge request, and high-severity findings are merge blockers. Pre-existing issues never block a merge request: on Android, a lint baseline records them, and on iOS, SwiftLint reports only on the lines a merge request changes. Either way, a merge request fails only on the findings it introduces.
Our rules come from three sources:
- Platform rules. Built-in checks cover well-known dangerous patterns, such as incorrect API usage and threading mistakes, and form the foundation for every build.
- Community rules. Open-source rule sets cover third-party libraries and patterns the built-in checks miss. We adopt the ones relevant to our stack.
- Custom rules. Both Android Lint and SwiftLint support custom rules, and we have built our own on both platforms. When a post-mortem or crash investigation traces a production crash to a specific code pattern, we write a rule that blocks that pattern from coming back.
Custom rules matter more as AI-assisted coding grows. An assistant can write code that looks right in general without knowing which patterns have crashed our app before. Custom rules turn those lessons into checks that apply equally to hand-written and AI-generated code.
Lint routinely blocks merge requests carrying Fatal issues: the kind that typically crash the app immediately or stop it from running.
Testing strategy: Multiple layers of confidence
Lint catches unsafe patterns statically, but it cannot run the code. Tests are where we catch crashes and regressions that only appear at runtime. No single test type covers everything, so we apply multiple complementary layers:
| Layer | Focus |
|---|---|
| Unit tests | Business logic correctness at the function and class level |
| User interface (UI) component tests | Rendering and interaction behavior of individual UI components |
| End-to-end (E2E) automation tests | Integrity of critical user journeys |
| Quality assurance (QA) manual testing | Real-device exploratory testing for new features and significant code changes |
Each layer targets a different class of crash risk. Unit tests block logic errors before they merge. UI component tests catch crashes tied to rendering or state mismatches; like unit tests, they run pre-merge on every merge request, so a rendering regression is blocked before it lands. E2E automation covers the flows with the highest business impact and runs on a per-team schedule and on every release train. QA manual testing focuses on new features and significant code changes, plus a full regression pass on every release, catching the edge cases that automation misses on real devices.
Grab Early Access (GEA): A one-week pre-production gate
Even with strong lint rules and test coverage, some crashes only surface under real-world conditions. GEA is an early build app by Grab. GEA builds are actively monitored for crashes, and any new crash surfaced during the GEA window automatically creates a ticket assigned to the responsible team. Issues reported by internal users, including functional defects and feature breakage, are ticketed the same way. Teams are required to resolve all blocking GEA issues before the release proceeds to production. GEA’s user base is large enough to expose real-world edge cases that automated tests miss, but small enough that issues are contained before reaching production users. GEA is a mandatory quality gate on every release cycle.
A crash that only a handful of internal users see in GEA would, at production scale, translate into a substantial spike in the crash rate, extra support load, and potentially a hotfix. Catching these crashes before they ever reach production users makes GEA one of our most important stability gates.
The impact adds up. Across both platforms, GEA catches new crashes every month, and each is fixed before the release reaches production. Each of them could otherwise have reached production users, including the long tail of users who do not auto-update and would have kept hitting them for months.
The release gate: Staged rollout and feature flags
Prevention keeps crashes out of the build. But the moment a release enters production, it meets something neither lint rules nor GEA can fully replicate: the full diversity of the real world, with thousands of device models, operating system (OS) versions, carrier configurations, and usage patterns that no internal test environment can mirror. So we treat the release boundary as its own critical checkpoint, a release gate between a validated build and full user exposure. Two mechanisms operate at this gate: staged rollout monitoring to limit the blast radius of the release itself, and feature flags to decouple feature activation from deployment.
Staged rollout monitoring
We do not ship to all users at once. Every release follows a staged rollout over the course of a week, starting with a small percentage of users and expanding in steps to the full user base. Each increment gives the monitoring system time to accumulate meaningful signal before the next expansion. During this window, we run a dedicated monitor that tracks the crash rate of the new version in isolation, separately from the baseline of all active versions. The separation matters: a regression in the new release can be masked in aggregate metrics if the older, stable versions dominate the user base.
If the new release shows an abnormal crash rate at any point during rollout, an automated system pauses the release before it expands further. The rollout does not resume until the responsible team has reviewed the issue and explicitly approved continuation. The pause gives us a hard stopping point: a regression introduced by the new release is contained to the fraction of users who received it, instead of compounding across the full install base.
In recent months, several Android rollouts were paused for on-call review. Most resumed after investigation: either the signal turned out to be noise, or the crash sat behind a feature flag that could be turned off without a new build. A small number stayed halted at the first stage until a hotfix shipped. We tune the monitor to be sensitive on purpose: a paused rollout takes an engineer a few hours to fix, while a missed regression can cost weeks. In one of the halted cases, only a small number of users hit the new crash before the halt, and the rest of the user base never saw it. Without the automated halt, the rollout would have kept expanding on schedule, taking the crash to the full user base.
Feature flags: Controlled activation with an instant kill switch
Even when a release ships cleanly, the features inside it are gated independently. All significant new features ship behind feature flags, decoupling deployment from activation. Flags let us roll out a feature gradually, monitor crash rates at each increment, and, critically, disable a feature instantly if its crash rate exceeds a defined threshold, without waiting for the next release cycle. For a team shipping weekly, the kill switch is what makes fast iteration safe, and it is also our first lever when something does reach production.
Response: When prevention falls short
No prevention layer is perfect. Crashes can still reach production: a misconfigured remote flag opens an unexpected code path, an OS update from a device manufacturer changes system behavior in ways no test environment can predict, or a bug slips past GEA and the rollout monitor because it only triggers under a specific combination of device state and user action. When that happens, the goal shifts from prevention to containment. For these scenarios, speed of detection, stopping the bleeding, and accuracy of diagnosis become the priority.
Real-time monitoring and on-call response
We maintain real-time crash rate monitoring across all active versions, with two complementary signals that can trigger an on-call alert:
- Hard threshold breach. The crash rate of an active version crosses an absolute limit we define as unacceptable.
- Abnormal trend. The crash rate spikes sharply relative to its own recent baseline, even if it has not yet crossed the absolute threshold.
We watch both because they catch different failure modes. A hard threshold catches slow drift: if the crash rate creeps up a little with each release, every step looks normal against its recent baseline and the trend alert never fires, yet over a year the rate can quietly increase. An abnormal trend catches the opposite case: a sudden regression, early, before it grows large enough to breach the threshold.
When either signal fires, an on-call engineer is immediately notified. The engineer begins by reviewing Firebase Crashlytics reports to identify which crash issues are driving the anomaly, then loops in the team responsible for the affected area. From there, the response follows a three-step decision framework, ordered from cheapest to most expensive:
- Disable the responsible feature flag. If the crash is tied to a feature behind a flag, turning the flag off stops new users from hitting the issue immediately, with no new build required. Turning off a flag is by far the fastest mitigation we have.
- Apply a server-side fix. If no flag covers the affected code path, the team looks for any server-side lever that can contain the impact: updating an API response, changing a config value, throttling a backend dependency. Any change that takes effect without shipping a new app build is preferred over one that does.
- Ship a hotfix. If neither of the above is available, the team evaluates whether the crash warrants an out-of-cycle hotfix release, using defined criteria: business criticality of the affected flow, crash severity, user impact, and time to the next scheduled release. After the hotfix is delivered, a post-mortem is required. The goal is not just to document what went wrong, but to identify concrete action items that close the gap in our prevention layer, such as adding a lint rule to block the same pattern, wrapping a similar feature behind a flag, or improving test coverage for the affected code path. Every hotfix should make the next one less likely.
Automated crash triage
Automated ticket creation in GEA and production is not a collection of separate tools; it is one triage pipeline that follows a release from GEA into production. In production, running in parallel with real-time monitoring, it creates a production issue ticket for crashes that cross a minimum threshold. We assess crashes by type, user impact, and whether they’re actionable. Tickets are created for issues that meaningfully affect users; low-volume, device-specific crashes that we can’t address are monitored but don’t receive tickets. This keeps the team focused on the problems users are most likely to feel.
For crashes that do qualify, the ticket is routed to the owning team with a service-level agreement (SLA) tied to severity: Urgent, High, Medium, or Low. The initial priority is set automatically based on crash rate and user impact, but teams can re-evaluate and adjust the priority based on the business criticality of the affected feature.
Feature flag rollout history: Diagnosing crash spikes
Some of the hardest on-call moments start the same way: the app suddenly begins crashing, alerts fire, and there is no obvious reason why. Nothing shipped that day, and in the worst cases the crash arrives without a usable stack trace to point anywhere. With many product teams working on the same app simultaneously, the culprit is often not new code in the latest release; it is a feature flag quietly rolled out to a wider user segment in the background. Finding that flag by asking around does not scale: without a central view, an on-call engineer can spend hours before the responsible rollout turns up.
So we maintain a feature flag rollout history: a dashboard that correlates flag activation events with crash rate changes over time. Instead of polling every team, the on-call engineer gets an immediate view of whether any flag rollout aligns with the onset of the spike, turning a slow manual search into a quick read of a timeline.
Deep observability: Enriched diagnostics for hard-to-debug crashes
Firebase Crashlytics is our primary crash monitoring tool, but some crashes resist easy diagnosis: crashes with unusable stack traces, native crashes from third-party libraries without debug symbols, or issues that only manifest on specific device configurations. Without a clear stack trace, there is no obvious starting point for investigation.
We handle these cases in two ways.
First, we use Crashlytics’ built-in export to BigQuery, so we own a copy of the crash data. The data is pseudonymized and handled under Grab’s data protection policies. That copy gives us two things Crashlytics alone cannot:
- Query the data when needed: full Structured Query Language (SQL) analysis across device attributes, app versions, and session metadata, surfacing patterns invisible in individual crash reports.
- Build internal dashboards that serve app stability investigations, broken down by crash category, device tier, or release version.
Second, we enrich every crash session with custom metadata attached directly to Crashlytics. Among the most useful attributes we track:
- Last visited screen: the last screen the user was on before the crash occurred (for example, the last Activity and Fragment on Android), helping reconstruct the navigation path that led to the failure.
- Install source: whether the app was installed from Google Play or a third-party store (Android only). Some third-party stores distribute unofficial copies of the app, and more than once we have traced a crash back to a corrupted copy served by one of them. Knowing the install source lets us recognize these failures as environmental, instead of chasing them as code defects.
- Session history: from the session data, we can reconstruct the sequence of screens and actions leading up to the crash, which is often the key to a crash investigation.
We attach many other custom attributes, but these three have proven the most useful in hard investigations. Together with structured logs and breadcrumbs, they give us a trail of events leading up to the crash, often the only meaningful signal when the stack trace alone is not enough.
Crashes we control, not eliminate
Different crashes call for different responses. Some are fixed in our code, while others, such as rare native crashes in operating system (OS) code, out-of-memory errors on devices near their limits, or failures from unofficial and sideloaded installs, are better handled through monitoring and containment.
We keep these categories at an acceptable baseline and monitor them on dedicated dashboards, separate from actionable issues. If any of them starts trending up instead of sitting flat, that spike triggers the same triage process as any other anomaly.
Conclusion
Sustaining stability across a codebase of millions of lines on Android alone, with many engineers shipping a release every week and AI assistance accelerating the rate of code change, is not the work of any single tool or team. It is the cumulative effect of a layered defense: lint rules and tests blocking bad code at the merge gate, QA and GEA catching what slips through, staged rollout limiting the blast radius of what reaches production, and on-call response combined with automated triage closing the loop on what production reveals.
The principle behind every layer is the same: shift left. A crash caught earlier is cheaper, smaller in impact, and less disruptive to fix. As the volume of code shipped per release continues to grow, the layered defense matters more, not less: the cost of a crash that reaches production is unchanged, but the number of opportunities to introduce one is rising. AI is speeding up how fast code is written; the layered defense is what makes that speed safe. Stability is not about having zero open problems; it is about knowing which problems you own and which ones you are watching.
Join us
Grab is a leading superapp in Southeast Asia, operating across the deliveries, mobility, and digital financial services sectors. Serving over 900 cities in eight Southeast Asian countries: Cambodia, Indonesia, Malaysia, Myanmar, the Philippines, Singapore, Thailand, and Vietnam. Grab enables millions of people every day to order food or groceries, send packages, hail a ride or taxi, pay for online purchases or access services such as lending and insurance, all through a single app. We operate supermarkets in Malaysia under Jaya Grocer and Everrise, which enables us to bring the convenience of on-demand grocery delivery to more consumers in the country. As part of our financial services offerings, we also provide digital banking services through GXS Bank in Singapore and GXBank in Malaysia. Grab was founded in 2012 with the mission to drive Southeast Asia forward by creating economic empowerment for everyone. Grab strives to serve a triple bottom line. We aim to simultaneously deliver financial performance for our shareholders and have a positive social impact, which includes economic empowerment for millions of people in the region, while mitigating our environmental footprint.
Powered by technology and driven by heart, our mission is to drive Southeast Asia forward by creating economic empowerment for everyone. If this mission speaks to you, join our team today!
Vulnerability
Post Syndicated from xkcd.com original https://xkcd.com/3314/

8 eMudhra certificates are compromised. Here’s what you need to know
Post Syndicated from Christopher Patton original https://blog.cloudflare.com/emudhra-certificate-compromise/
On October 19, 2026, at approximately 17:00 UTC, Cloudflare became aware that private keys associated with eight eMudhra intermediate certificates were compromised. These certificates were widely trusted by browsers, operating systems, and also within Cloudflare. Because the keys themselves are weak, an attacker can create a forged certificate for any domain and use it to impersonate servers to intercept or modify traffic. This is a serious security incident with implications across the Internet. For reference, here is a link to more information about how SSL certificates work and why they are so critical to the operation of the Internet.
We immediately prioritized patching critical services across Cloudflare to protect our customers ahead of the public disclosure of the vulnerability. Our security review has not identified active exploitation of this issue on Cloudflare services.
We have released updates for the Cloudflare One Clients, also known as WARP or the 1.1.1.1 app, and Cloudflare Tunnel, also known as cloudflared. We have also deployed mitigations across our CDN, Developer, and Zero Trust products. If you are using Cloudflare Zero Trust with Gateway and an up-to-date client (see below), you are automatically protected.
Our response
We prioritized updating services that use public certificates to authenticate remote endpoints, including proxies connecting to origins and applications calling external APIs. In parallel, we updated shared trust stores, base images, and other shared foundations, providing a common mitigation path for services that inherit their certificate trust from those sources. We paired these updates with reloads, restarts, and image deployments needed to activate them. Applications with bundled or custom trust stores received separate assessment and updates. This work addresses certificate-based authentication, not a weakness in TLS’s encryption algorithms.
Teams across Cloudflare are presently working on further remediation. We are making progress, but there's much work still to be done. Some customers will need to take action on software or trust configurations that they operate, especially on their origin servers. The recommended actions are summarized below.
What customers should do
Developer guidance
For developers, look beneath the SDK.
An API client may delegate certificate verification to an HTTP library, a language runtime, the operating system, or a custom trust configuration. Updating the SDK alone may not change the underlying policy.
Once you patch, you may notice certificate errors in your dashboards. It's important to not resolve these errors by disabling verification. That would remove the authentication protection these updates are intended to restore.
This incident affects many software stacks that rely on the WebPKI for authentication. Mozilla’s Dennis Jackson has crowdsourced a list of commonly used packages that have been patched. We advise readers to upgrade as soon as possible. (Note that some of these may be indirect dependencies of your software stack, so look at the dependency tree.) Apply the relevant dependency updates, rebuild affected images, and confirm whether applications require a reload, restart, or redeployment.
Dennis Jackson’s test site provides browser checks, non-browser testing instructions, and package update information. Results apply to the verification path being tested, not every application on the device. Validate through the application’s actual TLS path. A successful browser test does not prove that a background service is protected. Neither does a curl test if the application uses a different verifier.
Timeline
The timeline of events so far is below.
|
Date and Time |
Event |
|
October 19, approximately 17:00 UTC |
Cloudflare becomes aware of the compromise and begins assessment. |
|
October 20, 02:00 UTC |
Cloudflare One Client and WARP app security updates published across platforms (except Cloudflare One Agent on iOS, for which app review is still pending). |
|
October 20 09:15 UTC |
Cloudflare Tunnel (cloudflared) security update published. |
|
October 20 19:20 UTC |
CDN and server-side Zero Trust mitigations fully deployed. |
Looking forward
The impact of this incident is not felt equally. Browser maintainers were able to remediate the issue with a flip of a switch. They of course have just one application to update, instead of hundreds, but they do have a neat trick up their sleeves: most browsers use quick-revocation mechanisms (like Chrome CRLSets). At Cloudflare we also use such a mechanism for some of our products. To bring it to more systems at Cloudflare and industry, we’re excited about projects like upki that understand a trust store can’t be a static list of root certificate authorities, but needs the ability to be quickly updated with information like revocation and certificate transparency keys.
Critical PHP security update coming
Post Syndicated from corbet original https://lwn.net/Articles/1101687/
The PHP security team has let it be
known that there is a high-stakes security update coming at
14:00 UTC on October 21. “All PHP users are encouraged to
“.
prepare now so they can upgrade as soon as the release is available
Anybody running a PHP site probably needs to be prepared for this one.
Limit agent permissions and spend in AWS Transform custom
Post Syndicated from Hamza Alfarrash original https://aws.amazon.com/blogs/devops/limit-agent-permissions-and-spend-in-aws-transform-custom/
Engineering teams that own large Java estates face recurring upgrade deadlines. When they hand one of those upgrades to an AI agent, the agent brings its own permissions and its own bill. Consider a central engineering group with a few hundred Java services, several of which run on a Java Development Kit (JDK) version that reaches end of support in two quarters. Upgrading each service by hand means a dependency audit, a javax to jakarta migration, a test framework migration, and a release. The deadline does not move while the team works through the list.
Agents change the arithmetic. An agent upgrades a repository in place, where it runs the build, edits the source, and commits as it goes, and it finishes in minutes a job that takes a developer weeks. Across a few hundred services you don’t sit at a terminal approving each step. You invoke the agent from a pipeline, repository after repository, and an autonomous process with shell access to your source code now runs throughout your estate.
That speed comes with a footprint you must manage. The agent runs shell commands against the code that it’s changing, it uses the AWS credentials in its environment, and it bills you by the agent minute while it works. Before you point it at a few hundred repositories, you decide what permissions the agent holds and how much it can spend. That decision repeats wherever a runtime deadline meets a service count too large to upgrade by hand.
AWS Transform custom provides the agent, and you enforce that decision with three configuration controls. You write a trust allowlist to set which of the agent’s actions run without asking you. You scope an execution identity to limit what the agent can ask the service to do. You also set a cap on agent minutes, which stops a run at the limit you choose, and you configure an account-level alert on cumulative spend across runs. None of the three requires new infrastructure, because you manage each one as configuration, so you can adopt agentic transformation on a schedule you set.
The agent runs transformations through the AWS Transform CLI, either interactively on your machine or non-interactively in a pipeline, so the controls must hold in both places. In this post, we walk through the three controls against a working repository and give the measured result of each one. We show how a real run produced the trust allowlist, why interactive runs and pipeline runs need different controls, and how to scope an execution identity to approved transformations. The complete source code is available in the sample repository.
Unbounded agent risks
An agentic transformation runs as a process on a machine you own, rather than handing you a patch to review, and that footprint carries three distinct risks. The agent can run tools without limit, the identity it runs under can do more than run transformations, and the spend it accrues has no ceiling unless you set one. Each risk needs its own control, and you meet all three on the way to your first fleet-wide upgrade.
Tool execution
The agent works by calling tools. It reads a file, writes a file, runs the build, inspects git history, and commits, and the shell commands among them run with the privileges of whoever started the run. On your first run against one service, each of those calls stops for your approval, and after enough prompts the flag that trusts every tool looks like the obvious way to get through the day. That flag stops the prompts by removing the check behind them, which is the risk. The agent can then run whatever a transformation asks of it, on a machine that holds your source code and your credentials.
Identity
The AWS credentials in your environment decide what the caller can do to the service, and the managed policy that gets a first run working also covers authoring. If an identity can both run a transformation and rewrite its definition, it can also change what runs next time. On a laptop that identity belongs to a person exercising judgment, but in a pipeline it belongs to a role that the rest of the build inherits, and the pipeline is where your other few hundred runs will happen.
Spend
Billing is per agent minute, and the meter runs while the service plans, reasons, analyzes, and edits. A single run on a small service costs little, so the risk isn’t the run you watch but a fleet-wide upgrade of a few hundred automated runs, on a bill nobody reads until the end of the month.
Solution overview
The following diagram shows where each of the three controls intercepts a transformation run.
- Invocation: A developer runs the AWS Transform CLI interactively, or a pipeline runs it non-interactively. The two paths carry different controls.
- Trust settings: Before the agent runs a shell command or writes a file, the CLI checks the trust settings file in your home directory. A command that matches the allowlist runs. A command that does not match returns to the person at the terminal as an approval prompt.
- Identity: AWS Transform custom authorizes each call the CLI makes against the AWS Identity and Access Management (IAM) identity in your environment. When you attach the execute-only managed policy and scope it to the transformations you approve, the policy bounds the service actions that the caller can request, including requests that originate from the agent.
- Spend: The run carries an agent-minute cap and stops when it reaches it. Underneath that, an AWS Budgets budget filtered to AWS Transform watches monthly spend across runs and notifies a subscriber at a threshold you set.
Inside a transformation run
AWS/java-version-upgrade is one of the AWS managed transformations, prebuilt and maintained by AWS rather than authored in a customer account. Running atx custom def list shows the AWS managed definitions alongside any custom ones you have created. The definition for this one covers a range of build systems and source and target JDK versions, with dependency modernization that includes Jakarta EE migration, database drivers, object-relational mapping (ORM) frameworks, and updates across the Spring libraries.
The target version is an input rather than a property of the transformation. The definition gives three ways to supply it: interactive chat with the agent, an additionalPlanContext configuration parameter, or a configuration file. We specified the target version in the prompt we gave to atx.
The sample repository is a small Spring Boot REST service with a single endpoint, running on Java 8 and Spring Boot 1.5. It stands in for one of the few hundred services in the opening scenario. The transformation takes it to Java 17 and Spring Boot 3.2, so the javax.servlet and javax.annotation imports become their jakarta equivalents and the JUnit 4 test moves to JUnit 5. We kept the business logic trivial from the beginning so anyone can follow along. If the logic were more complicated, it would introduce a monetary barrier for readers who want to try it themselves, and it would take longer to run.
In a run (AWS Transform CLI 3.10.0), the transformation made 43 tool calls across the sample’s 4 files: 13 shell commands, 11 file writes, 11 file reads, 6 editor operations, and 2 version control operations. Every shell command ran with the permissions of the identity that started the run, inside the working tree of the repository being upgraded. The counts in this post come from this definition and this sample in August and September 2026, so expect different counts on other CLI versions, definitions, and repositories.
The documentation describes multi-step transformations as using Git to commit intermediate steps. In that run, the 2 version control operations produced a single checkpoint commit on the result branch.
Prerequisites
The walkthrough requires the following:
- An AWS account and an AWS Region where AWS Transform custom is available, listed in the getting started guide.
- The AWS Transform CLI and
Node.js22 or later, which the CLI requires. Install the CLI withcurl -fsSL https://transform-cli.awsstatic.com/install.sh | bash, then confirm withatx --version. The confirmation runs in this post used version 3.10.0. - Git, with the sample checked out as a valid repository, because the transformation commits its intermediate steps. On CLI 3.10.0, a run also stopped when the working directory wasn’t a repository, which is behavior we measured rather than a documented requirement.
- JDK 8 to build the sample before the upgrade, JDK 17 after it, and Maven 3.6 or later. The commands in this post were verified on macOS. On Linux, set
JAVA_HOMEto a JDK 8 path directly instead of using the macOS-specific/usr/libexec/java_homehelper. - AWS credentials with permission to call AWS Transform custom. Control 2 covers which policy to attach.
Restricted networks additionally need transform-cli.awsstatic.com, transform-custom.<region>.api.aws, and *.s3.amazonaws.com reachable. The repository README carries the full setup detail.
Control 1: Scope which tools run without asking
This control starts on a laptop, because that is where the allowlist gets built.
Our first run of AWS/java-version-upgrade against the sample repository used AWS Transform CLI 3.9.0 with no trust configuration, and it raised 23 approval prompts across four files. The later runs used 3.10.0, and the CLI version history lists no change to trust settings or approval prompts in that release.
Before the allowlist, you have two options. Either you grant blanket tool trust for the session, which comes with the risk of tool calls you don’t want the agent to make. Or you walk through every prompt carefully, reading what it says and deciding whether you want that tool call to run, which adds to the overall time the agent takes to complete the task.
Across a few hundred repositories, either choice makes the documented shortcut the obvious thing to reach for. The --trust-all-tools flag (-t) approves the tool calls the agent requests without asking.
The middle position is a trust settings file at ~/.aws/atx/trust-settings.yaml. The file is split into three categories. trustedTools covers the tool calls that are allowed automatically. trustedShellCommands are the shell commands you allow the agent to run on its own without prompting you. And alwaysPromptCommands are the commands the agent has to ask you about before executing, in interactive mode. A fourth mechanism sits alongside the file: answering t at an approval prompt trusts that tool for the rest of the session, which the prompt text itself names when it reports that a tool “hasn’t been trusted this session.”
We first made a test run with no trust configuration in place, so we could see which tool calls the agent makes for this specific transformation. We logged each tool call and added the shape of each command to the file, to make it straightforward for you to use. Twenty-three prompts collapse into a short list, because the agent asks for variations of the same few operations.
Rerunning with that first list (CLI 3.10.0) dropped the count from 23 prompts to 3, and all three were the same shape: cd <path> && <command> compounds in the validation phase. The matcher is a full-command-string glob, so JAVA_HOME=* mvn * does not match a string that starts with cd. Command shapes vary between runs, and this one issued a bare mvn during execution and cd ... && mvn during validation, so the shipped file carries both forms. With both forms added, a third run on a clean clone (CLI 3.10.0) reached zero prompts.
The following excerpt shows the shape of the file. The repository copy carries the full set, including the cd-prefixed variants:
Copy the file into place and run the transformation interactively:
The mkdir -p matters on a fresh install, because ~/.aws/atx/ does not exist until the CLI has run at least once.
Patterns match against the full command string, which is why JAVA_HOME=* mvn * is listed separately from mvn *. The validation command pins JDK 8 because Spring Boot 1.5 can’t start its context on later versions, which is what puts that prefix in the run at all.
The alwaysPromptCommands entries are matched against each sub-command in a compound expression rather than against the whole string. In an interactive run, session trust and the --trust-all-tools flag don’t approve a match.
Important: alwaysPromptCommands doesn’t force a prompt in 2 cases.
- A matching trusted pattern takes priority. The documentation states that
trustedShellCommandspatterns match the full command string and take priority over the always-prompt list, so a trailing*spans pipes, semicolons, and&&. In our verification run (CLI 3.10.0), the trusted pattern/usr/libexec/java_home *matched a compound that continued; echo "---" ; ls ..., and the chained tail ran without a prompt. By the same rule,mvn *trustsmvn --version; printf canaryeven withprintf *inalwaysPromptCommands. The file in this post usesmvn *to reach zero prompts on the sample, so narrow that pattern to the Maven goals your builds run before you reuse the file. - Non-interactive mode (
-x) does not enforcealwaysPromptCommands, as the documentation states, so the list has no effect on a pipeline run.
Keep the two lists non-overlapping and the trusted patterns as narrow as the runs allow. The following diagram shows the order in which the CLI evaluates a proposed shell command.
With the allowlist in place, a full run of AWS/java-version-upgrade completed with no approval prompts and without blanket trust. The run made 43 tool calls, each one covered by the allowlist or by a built-in trusted tool, with a green build and 2 of 2 tests passing on AWS Transform CLI 3.10.0. This lets us focus on other tasks, and we’re only interrupted when the task finishes or something unexpected comes up. The startup banner on that version also identified six built-in trusted tools: file_read, grep, both transformation-registry tools, document_manager for add operations, and editor for view and find-line operations. Those calls don’t prompt, so a prompt inventory understates the agent’s effective tool surface. Default trust is also scoped by path rather than only by tool. The same file_write tool runs without prompting when it targets the CLI artifacts directory and prompts when it targets the repository.
In a pipeline
The trust settings file governs interactive runs only. On CLI 3.10.0, -x without --trust-all-tools stops before the transformation starts, with the error Must explicitly --trust-all-tools when running in non-interactive mode, which we hit in a test. A pipeline run therefore trusts every tool, and the allowlist has no effect on it. The interactive path does not fit a pipeline either, because without a terminal it stops at the plan approval step and reports Input is not a TTY.
This control therefore belongs on a developer machine. A pipeline needs its boundary somewhere else, and that somewhere else is the next two controls.
Control 2: Separate the identity that runs from the identity that authors
The pipeline from the opening scenario needs an identity, and that identity should run the upgrade and little else.
Three AWS managed policies cover AWS Transform custom, and the split between them is the control. The following table describes each policy at version 4, the current version on September 30, 2026. Check the managed policies page for a later version before you attach one.
| Policy | What it grants | Who gets it |
AWSTransformCustomExecuteTransformations |
Run existing transformations, and read and update campaigns | The pipeline execution role |
AWSTransformCustomManageTransformations |
The preceding, plus authoring: upload and delete transformation packages, manage knowledge items, tag resources | The people or pipelines that author definitions |
AWSTransformCustomFullAccess |
Both of the preceding, reasonable for a first run but wider than a governed setup needs | Nobody, after setup is complete |
The execute-only policy also carries its own iam:CreateServiceLinkedRole statement scoped to the AWS Transform service-linked role, so a first run works without AWSTransformCustomFullAccess even in a fresh account.
Give the pipeline execution role the execute-only policy. Authoring stays with whoever maintains the transformation definitions, so a build step holding that role is not authorized to rewrite the definition that it’s about to run:
Then confirm what the identity holds, rather than what you meant to give it:
The execute-only policy still lets the role run whatever is in the registry. For transformations you publish yourself, you can narrow it further, because transformation packages are AWS resources with Amazon Resource Names (ARNs). The transform-custom:ExecuteTransformation action takes a package resource and supports the aws:ResourceTag condition key. Tag the packages you publish, and scope the role to the tag:
We confirmed the mechanics with the IAM policy simulator: it allows the execute call when the tag is present and returns an implicit deny when the tag is absent. Note the scope of the example, though. The Resource element names packages in your account, and an AWS managed package such as AWS/java-version-upgrade is not a resource in your account, so a role holding only this policy can’t run it. The execute-only managed policy itself grants ExecuteTransformation on Resource "*" for that reason. The practical split is tag-scoping for the definitions you publish, alongside the managed policy’s broader grant for the AWS managed catalog.
The second statement is the limit of this approach. The actions table in the service authorization reference lists no resource type and no condition keys for ConverseStream, so that statement stays at "*". A role scoped to one transformation can still open a conversation with the service.
The broader limit is that IAM bounds the API surface and not the edits. The execute-only policy still authorizes whatever the transformation does to your working tree, because the scope of changes inside a repository is a local filesystem question. That’s what Control 1 is for on a laptop, and what code review of the resulting branch is for in a pipeline.
Control 3: Cap what a run can spend
Now think about the same upgrade from the cost perspective. The fleet-wide upgrade from the opening scenario means a few hundred runs, but you’re constrained by your budget. With the spend control, you can bound the agent minutes used by each run and use the account-level budget to watch cumulative spend across the fleet.
Start with what an agent minute measures. You’re billed per agent minute, but an agent minute is not a wall-clock minute. The two match only while a single agent is running, and AWS Transform can run several agents at once on one task, so each of them accrues its own minutes. Per the AWS Transform pricing page, minutes accrue while the service is actively planning, reasoning, analyzing, or modifying code, and not while it waits on local compilation, tests, or builds.
AWS Cost Explorer recorded 54.0 agent minutes for the discovery run (CLI 3.9.0) and 45.8 agent minutes for the clean-clone confirmation run (CLI 3.10.0). At the published rate of USD $0.035 per agent minute, the confirmation run cost approximately USD $1.60. A 30-agent-minute cap would therefore stop this particular upgrade partway through, which makes it a useful review checkpoint rather than a budget sized for uninterrupted completion. In practice, the number is experimental. It depends on your budget for the task, and it can take multiple iterations at a smaller scale first to get an understanding of the agent minutes your tasks need.
Set the per-run cap with --limit:
We wanted to see what the CLI does when it hits the cap, so we ran the same transformation non-interactively on a scratch clone with --limit 1. On AWS Transform CLI 3.10.0 the run stopped at 1.09 agent minutes, printed Budget limit reached: 1.09 / 1.00 Agent Minutes. Exiting., and returned process exit code 2. The repository was left clean. The exit code is the part we were checking. The web documentation describes the message and the resume path but not an exit code. The CLI --help output on 3.10.0 does state that the run exits with code 2 when the limit is reached, and the run confirmed it. It’s also what turns spend into control flow, because a pipeline can tell a budget stop from a transformation failure. The 0.09-minute overshoot comes from how coarsely the CLI receives usage events, so treat the limit as a close bound rather than an exact fractional-minute cutoff.
The work is preserved. Review the partial result, then resume the same conversation with a higher cap. The trust settings file from Control 1 still governs the resumed interactive session:
A pipeline can handle the bounded stop separately:
Entering /usage during an interactive session reports the accumulated agent minutes without ending the conversation. Minutes persist across an interruption, so when you resume a session after Ctrl+C, the count continues rather than starting over. Per the pricing page, an interrupted transformation can be resumed for up to 24 hours before it’s stopped automatically. We did not test the expiry, so treat that window as documented rather than measured.
The per-run cap says nothing about how many runs start, so back it with an account-level AWS Budgets budget. A budget like the one in this sample sends a notification and does not stop runs, so the next run still starts after the alert. AWS Budgets also updates its data up to 3 times a day, which means a fleet of runs can pass the threshold before the alert arrives. To stop new runs at a threshold, you can configure a budget action that applies an IAM policy or a service control policy (SCP), which this post does not cover.
The sample repository ships a monthly budget of USD $50 filtered to the AWS Transform service, with an alert at 80 percent of actual spend:
Edit the email address in guardrails/notifications.json before running that command, because the file ships a placeholder. To see where the month stands, query AWS Cost Explorer for the same service dimension:
Use the cap to bound each run, and use the budget to find out when the runs together cost more than you planned.
Limits of these controls
Retention is a separate question from permissions. The --do-not-learn flag opts one execution out of lesson extraction for that transformation definition. A different control governs whether your content is used for service improvement, and you configure it as an AI services opt-out policy in AWS Organizations. Neither one changes the fact that the transformation sends code to the service to do the work. Both govern what happens to it afterward.
Retained lessons also reach back into later runs. In the verification run, the agent diffed against a baseline commit carried in from a previous run on the same repository, so a README that we had added by hand between the two runs appeared in the diff, and the validation summary credited the transformation with adding it. Lessons persist repository-specific facts across runs, and on a repository that changes between runs they can misattribute human work to the agent.
The number of commits a run produces is not fixed. The same transformation on the same repository produced two commits on the first run and a single commit on each of the next two, and the commits covered a different set of plan steps each time. Review the result branch with git log and git diff rather than assuming one commit per plan step.
Clean up
The controls in this post are configuration rather than provisioned infrastructure, so there is little to tear down. Delete the budget when you no longer want the alert:
The trust settings file at ~/.aws/atx/trust-settings.yaml and the policy attachments on the execution role are yours to keep or remove. If you also deployed the sample application to AWS to see the upgraded service running, run npx cdk destroy from the infra/ directory. One artifact survives by design. The container image stays in the AWS Cloud Development Kit (AWS CDK) bootstrap repository in Amazon Elastic Container Registry (Amazon ECR), because cdk destroy does not remove bootstrap assets. Storage for it costs about a cent a month, and deleting the image from the cdk-*-container-assets-* repository clears it. Leaving the sample deployed costs roughly USD $13 a month, so tear it down when you’re finished with it.
Conclusion and next steps
You can now put a few hundred upgrades on a schedule, because the execution identity and the agent-minute cap apply to each run wherever it executes. A trust settings allowlist adds a third control on a developer machine. That allowlist took the interactive sample run from 23 approval prompts to zero without blanket tool trust. We built the execution identity from the AWS Transform managed policies in IAM and narrowed it to approved transformations with a resource tag. An AWS Budgets budget and alert on the account backed the agent-minute cap on each run. Because every measurement came from running AWS/java-version-upgrade against the sample repository, you can repeat the runs in your own account before you decide what to change. We ran them in August and September 2026, with the confirmation runs on AWS Transform CLI 3.10.0.
The configuration leaves room to grow. If you publish your own transformation definitions, tag them and scope the execute permission to the tag, which holds a pipeline role to the transformations you have reviewed. And if you run transformations over proprietary repositories, the --do-not-learn flag covers a single execution. An artificial intelligence services opt-out policy in AWS Organizations covers service improvement across the account.
To go further, see the AWS Transform custom user guide for the execution modes and the trust settings reference, the AWS managed policies for AWS Transform for the identity split, and the service authorization reference when you scope a policy to specific transformations. Pricing and the definition of an agent minute are on the AWS Transform pricing page. The complete source code is available in the sample repository.
For more on what these transformations do, see AWS Transform custom: AI-driven Java modernization to reduce tech debt, Automating AWS SDK for Java v1 to v2 upgrades with AWS Transform, and Migrating your Java applications to AWS Graviton using AWS Transform custom.
About the authors
[$] SUSE’s efforts to disable setuid system-wide
Post Syndicated from jzb original https://lwn.net/Articles/1100257/
Setuid (and setgid) binaries have long been a source of headaches, and security
vulnerabilities, on Linux systems. They are largely seen as something to be
avoided; SUSE’s security team, for example, forbids
the inclusion of setuid or setgid binaries in packages unless they have been
reviewed and explicitly allowed. Thorsten Kukuk wants to go a step further and
disallow them entirely. At the 2026 All Systems Go! conference, he spoke
about his work to disable setuid system-wide, as well as some of the hurdles
that remain.
Building an AEO scoring pipeline with AWS Lambda durable functions
Post Syndicated from Nick Beall original https://aws.amazon.com/blogs/compute/building-an-aeo-scoring-pipeline-with-aws-lambda-durable-functions/
When an AI agent crawls your documentation looking for answers, it doesn’t browse like a human. It scores structure, extracts entities, checks factual consistency, and moves on, often in under a second. If your content doesn’t surface clearly in those evaluations, it won’t appear in AI-generated answers regardless of its current search ranking. This problem is called Agent Engine Optimization (AEO), and solving it requires running multiple evaluation steps that are expensive, stateful, and failure-prone.
In this post, you build a five-step AEO scoring pipeline using AWS Lambda durable functions. Each step (fetch, score, analyze, publish, record) runs as a checkpointed operation that suspends without incurring additional costs between stages, retries without re-spending on prior work, and reads like ordinary Python. You score content against five AEO signals, see a real audit example, and walk away with a deployable AWS Serverless Application Model (AWS SAM) template.
A note on fetching: The pipeline uses a plain HTTP GET, mimicking how non-rendering AI crawlers (GPTBot, ClaudeBot, PerplexityBot) see pages today. Sites that rely on client-side JavaScript may score lower because most AI agents do not execute JavaScript.
Solution overview
The pipeline runs as a single Lambda durable function that chains five checkpointed steps. Scoring is fully deterministic (pure Python, no large language model (LLM)), so the same page consistently produces the same score. Amazon Bedrock generates prose analysis explaining the results. For production deployments that surface generated content to end users, consider adding Amazon Bedrock Guardrails for responsible AI controls. Because the function suspends between steps without incurring additional costs, a failure at step 3 resumes from step 3. The deterministic scores from step 2 are already checkpointed.
The following architecture diagram shows the five pipeline stages:
- Fetch – Retrieve the target page through an HTTP GET and extract structured signals (headings, token count,
robots.txtrules,llms.txt,AGENTS.md). - Score – Apply the deterministic rubric: threshold-based checks produce a reproducible 0–100 score with no LLM involvement.
- Analyze – Send the scores and raw signals to Amazon Bedrock, which generates prose findings and fix recommendations (temperature 0 for consistency).
- Publish – Render the audit report as HTML and JSON, write to Amazon Simple Storage Service (Amazon S3).
- Record – Persist the score and metadata to Amazon DynamoDB for trend tracking.
This gives you retry safety, cost predictability, and simpler debugging. The pipeline runs fully automated by default, with an optional callback gate for workflows requiring human approval.
Why Lambda durable functions
An AEO audit is five operations that depend on each other, any of which can fail mid-flight. Without checkpointing, a retry means re-running every step from the beginning, including Bedrock calls that already returned valid results.
Lambda durable functions solve this with checkpointed steps. Each step’s output is persisted before the next begins. When a Bedrock call gets throttled at step 3, only step 3 retries. The pipeline doesn’t re-run steps 1 and 2 or re-spend on their inference tokens.
Between steps, the function suspends with no environment held open, so you pay nothing while waiting. The pipeline reads as a single Python file, top to bottom. Each step’s checkpoint is independently inspectable, so debugging a failed run means looking at one step’s result rather than replaying the full execution log.
Prerequisites
- An AWS account with Amazon Bedrock model access enabled.
- AWS SAM CLI v1.100+ installed and configured.
- Python 3.12+.
- AWS Identity and Access Management (IAM) permissions to deploy AWS CloudFormation stacks (Lambda, DynamoDB, Amazon S3, and Amazon Bedrock invoke)
A SAM template in the GitHub repository provisions the DynamoDB table, S3 bucket, Lambda durable function, and required IAM roles. You deploy the full stack with sam build && sam deploy --guided.
Estimated time: 20–30 minutes. Each audit run uses a single Bedrock inference call plus brief Lambda durable function and DynamoDB usage. See the AWS Pricing Calculator for estimates based on your Region and usage volume.
The five AEO signals
Scoring evaluates content against five signals drawn from Addy Osmani’s Agent Engine Optimization framework. Each signal maps to a capability an AI agent needs when deciding whether to use your content. Scoring is deterministic: every point maps to a measurable threshold (file exists, token count under ceiling, heading hierarchy valid). No LLM is involved in producing the number.
1. Discoverability (0–25)
This signal checks whether the URL returns server-rendered HTML, whether an llms.txt file exists at the domain root, and whether AI crawlers receive a successful response. A page returning HTTP 200 with parseable content passes. A page returning 403 or 429 to AI user agents fails.
2. Parsability (0–25)
This signal scores heading hierarchy (H1 through H6), presence of code blocks and tables, and whether the page has semantic landmarks. Because agents parse structurally rather than linearly, it’s essential for sites to be well organized and logical. Osmani suggests serving Markdown and HTML, leading each section with the outcome, and using tables for parameter references, among other tips that make your site easier to parse.
3. Token efficiency (0–25)
It measures total token count against a 30,000-token ceiling and a 15,000-token quick-start target. Pages bloated with navigation elements or repeated boilerplate score lower.
4. Capability signaling (0–15)
This signal checks for AGENTS.md or skill.md files describing available actions, required inputs, authentication, and rate limits. Without these, agents discover capabilities through trial and error.
5. Access control (0–10)
It checks robots.txt for AI-specific rules (GPTBot, ClaudeBot, PerplexityBot). Pages with explicit Allow or Disallow rules for AI user agents score higher than pages with no AI-specific rules, where access is open by default. Either choice is fine. The signal rewards making the decision on purpose.
Deterministic scores feed into the analyze step, where Bedrock generates prose explanations and actionable fix recommendations.
Example: auditing a real page
To see the pipeline in action, here are the results from a technical documentation page: a conceptual overview for a cloud computing service.
Target: A technical documentation page (conceptual overview, 958 words)
Overall score: 58/100
| Signal | Score | Key finding |
| Discoverability | 17/25 | Server-rendered, llms.txt exists (but bloated at 295 KB / ~74K tokens compared to the recommended 5K token limit). No AGENTS.md. |
| Parsability | 14/25 | Invalid heading hierarchy (H1 to H6 to H2). No fenced code blocks or tables despite being technical documentation. 63.9% HTML noise ratio. |
| Token efficiency | 25/25 | 1,245 tokens. Well under both the 15K quickstart target and 30K ceiling. |
| Capability signaling | 0/15 | No skill.md. Agents cannot discover what actions this documentation enables. |
| Access control | 2/10 | No AI-specific rules in robots.txt. Access is accidental rather than intentional. |
Top three fixes:
- Create a
skill.mddeclaring what agents can do with this service (available actions, required inputs, constraints). - Fix the heading hierarchy to follow valid nesting (H1, H2, H3) and add fenced code blocks with language tags.
- Add an
AGENTS.mdat the domain root and explicit AI crawler rules torobots.txt.
The scoring is deterministic, and every point maps to a measurable condition. Amazon Bedrock then runs LLM inference on the results to generate the prose findings.
Under the hood: Steps and callbacks
Every step in the preceding audit, from fetch through record, runs as a checkpointed step. The callback is optional and sits after the analyze step, if you want a human to review the report before it’s published.
Lambda durable functions expose two core primitives: steps and callbacks. This pipeline runs fully automated by default (five steps, no human gate), but you can opt into a callback-based approval gate when the use case calls for it.
Steps
A step is a unit of work. The runtime checkpoints its return value before the next step begins. You declare one with the @step decorator:
If this step succeeds, its return value is persisted. On retry, completed steps are skipped and their cached results passed forward. Two rules:
- Keep return values small. Return structured results, not raw API responses.
- One side effect per step. A step that calls Bedrock and also writes to DynamoDB is harder to reason about on retry. Make one external call per step.
Callbacks
By default, the pipeline runs all five steps without stopping. To add a human review gate, turn on the callback. The function suspends without incurring additional costs until an external signal arrives. In practice, you wire this to a Slack bot or approval dashboard rather than a CLI command. Resumption happens through the SendDurableExecutionCallbackSuccess AWS API call with the callback ID. Because this is an authenticated API call, only principals with the appropriate IAM permissions can signal completion.
The function suspends at callback.result() without incurring additional costs. The external system calls SendDurableExecutionCallbackSuccess with the callback ID and the approval payload. Timeouts raise TimeoutError for fallback routing.
When to add a callback
| Run fully automated when… | Add a callback when… |
| Scheduled audits or continuous integration and continuous delivery (CI/CD) regression monitoring | High-stakes pages needing human sign-off |
| Reports feed directly into dashboards or alerts | External workflow integration (Slack, Jira, webhook) |
| Fixes are suggestions, not auto-applied actions | Downstream actions are gated (auto-filing tickets) |
By default, the pipeline skips the callback entirely. To turn it on, set APPROVAL_GATE=true in the function’s environment variables.
Clean up
To avoid ongoing charges, delete the stack when you’re done experimenting:
This removes the Lambda durable function, DynamoDB table, S3 bucket (if empty), and the associated IAM roles. If your S3 bucket contains audit reports you want to keep, download them first or remove the DeletionPolicy: Delete setting from the template before deploying.
Conclusion
You now have a five-step AEO scoring pipeline in a single Lambda function that checkpoints between steps without incurring additional costs. Some steps involve LLM inference you don’t want to pay for twice. Durable checkpoints help make sure you do not.
To get started:
- Clone the repository: github.com/aws-samples/sample-aeo-scoring-pipeline
- Deploy with
sam build && sam deploy --guided - Run your first audit:
aws lambda invoke --function-name AeoScoringPipeline --payload '{"url": "https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html"}'
Next steps: schedule audits using Amazon EventBridge, add Slack alerts when scores drop, or extend the rubric with domain-specific signals.
For more on Lambda durable functions, see the AWS Lambda durable functions Developer Guide. For the AEO framework, see Addy Osmani’s original post on agent-optimized content.


