As many of you are, I’m a parent. And like you, I think about the world I’m building for my children. That’s part of why today’s launch matters for many of us. I’m excited to announce the launch of the AWS Sustainability console, a standalone service that consolidates all AWS sustainability reporting and resources in one place.
With the The Climate Pledge, Amazon set a goal in 2019 to reach net-zero carbon across our operations by 2040. That commitment shapes how AWS builds its data centers and services. In addition, AWS is also committed to helping you measure and reduce the environmental footprint of your own workloads. The AWS Sustainability console is the latest step in that direction.
Until now, accessing your carbon footprint data required billing-level permissions. That created a practical problem: sustainability professionals and reporting teams often don’t have (and shouldn’t need) access to cost and billing data. Getting the right people access to the right data meant navigating permission structures that weren’t designed with sustainability workflows in mind. The AWS Sustainability console has its own permissions model, independent of the Billing console. Sustainability professionals can now get direct access to emissions data without requiring billing permissions to be granted alongside it.
As sustainability reporting requirements have grown more complex, teams need more flexibility accessing and working with their emissions data. The console now includes a Reports page where you can download preset monthly and annual carbon emissions reports covering both market-based method (MBM) and location-based method (LBM) data. You can also build a custom comma-separated values (CSV) report by selecting which fields to include, the time granularity, and other filters.
If your organization’s fiscal year doesn’t align with the calendar year, you can now configure the console to match your reporting period. When that is set, all data views and exports reflect your fiscal year and quarters, which removes a common friction point for finance and sustainability teams working in parallel.
You can also use the new API or the AWS SDKs to integrate emissions data into your own reporting pipelines, dashboards, or compliance workflows. This is useful for teams that need to pull data for a specific month across a large number of accounts without setting up a data export or for organizations that need to establish custom account groupings that don’t align with their existing AWS Organizations structure.
You can read about the latest features released and methodology updates directly on the Release notes page on the Learn more tab.
Lets see it in action To show you the Sustainability console, I opened the AWS Management Console and searched for “sustainability” in the search bar at the top of the screen.
The Carbon emissions section gives an estimate on your carbon emissions, expressed in metric tons of carbon dioxide equivalent (MTCO2e). It shows the emissions by scope, expressed in the MBM and the LBM. On the right side of the screen, you can adjust the date range or filter by service, Regions, and more.
For those unfamiliar: Scope 1 includes direct emissions from owned or controlled sources (for example, data center fuel use); Scope 2 covers indirect emissions from the production of purchased energy (with MBM accounting for energy attribute certificates and LBM using average local grid emissions); and Scope 3 includes other indirect emissions across the value chain, such as server manufacturing and data center construction. You can read more about this in our methodology document, which was independently verified by Apex, a third-party consultant.
The combination of the visual console and the new API gives you two additional ways to work with your data, in addition to the Data Exports still available. You can now explore and identify hotspots on the console and automate the reporting you want to share with stakeholders.
The Sustainability console is designed to grow. We plan to continue to release new features as we grow the console’s capabilities alongside our customers.
Get started today The AWS Sustainability console is available today at no additional cost. You can access it from the AWS Management Console. Historical data is available going back to January 2022, so you can start exploring your emissions trends right away.
Get started on the console today. If you want to learn more about the AWS commitment to sustainability, visit the AWS Sustainability page.
Learn how you can use AWS services like AWS Backup and AWS Elastic Disaster Recovery (AWS DRS), along with AWS Resilience Competency Partner solutions like Arpio to implement powerful and comprehensive Disaster Recovery solutions.
Resilience is the ability of your application to keep running even when “bad stuff” happens. A critical part of your resilience strategy is Disaster Recovery (DR). DR is what protects you against less frequent, but bigger faults like natural disasters, technical faults, and bad actors. To maintain critical business continuity, disaster recovery requires recovering your workload to a new site, such as a different AWS Region or AWS account.
AWS provides powerful tools for all aspects of resilience. However, achieving a comprehensive Disaster Recovery solution for your cloud workloads using native AWS services requires planning and engineering effort. This is because, as the Shared Responsibility Model for Resiliency states, resilience is a shared responsibility between AWS and the customer. This blog post will help you understand your responsibilities and show you how to reduce the work required to access the powerful DR capabilities of AWS.
In this blog post, we take a building blocks approach. Starting with the tools like AWS Backup to protect your data, we then add protection for Amazon Elastic Compute Cloud (Amazon EC2) compute using AWS Elastic Disaster Recovery (AWS DRS). Finally, we show how to use the full capabilities of AWS to restore your entire workload—data, infrastructure, networking, and configuration, using Arpio disaster recovery automation.
Your recovery site
For DR, your recovery site is usually going to be a different AWS Region (cross-Region) or a different AWS account (cross-account) than where your workload runs.
Cross-Region backup and recovery are essential for disaster recovery. This helps to keep your workloads protected if an event causes your source Region to be unable to run your workload. AWS Regions are strong fault isolation boundaries, so the event in your source is highly unlikely to affect your recovery Region.
Cross-account backup is a critical security measure to enable recovery from malware and ransomware. By storing copies of your data in a separate clean room recovery account with distinct credentials, you create an isolated environment that can’t be accessed, even if the source account is compromised.
Protecting your data
We start with your data—your data is the foundation of your workload.
Figure 1. AWS Backup and replication for Amazon RDS
AWS Backup takes this further, tying together many of these disparate backup technologies, giving a single plane of glass to configure data backup plans across resources. AWS Backup also added backup capabilities for AWS resources that previously didn’t have them such as Amazon Elastic File System (Amazon EFS) and Amazon FSx. It also provides the ability to back up your data to a different AWS Region or AWS account. It even enabled cross-Region backup for services like Amazon DynamoDB, which previously didn’t have that capability.
AWS Backup is a powerful tool for protecting your data. With your data protected, you will then need additional automation to get to a fully recovered workload. If you want to build this yourself, AWS offers the tools to do this. In this prior blog post on Backup and Restore, we go more into detail about adding automation using Amazon EventBridge and AWS Lambda functions for automated recovery. For more information, see figures 6 and 7.
With its ability to create vaults for secure storage, define policies for governance, and set schedules for automation, AWS Backup centralizes and streamlines the backup process. Instead of managing backups service by service, you can enforce consistent protection across resources, reduce manual effort, and streamline recovery when it matters most.
Protecting your Amazon EC2 compute
As important as data is, only restoring your data isn’t a complete solution to recovering from disaster. You must also restore your compute resources.
For static Amazon EC2 instances, you can create snapshots of your instances as Amazon Machine Images (AMIs), or use AWS Backup to manage this for you. By static instances, we mean those you create directly and maintain, as opposed to those created by Amazon EC2 Auto Scaling. Such a strategy can deliver a Recovery Points Objective (RPO) and Recovery Time Objective (RTO) of minutes to hours. The size (and growth in size) of your EC2 instances determines the time to back them up. Their size and launch time determines the time to restore them.
If you need real-time RPO (near-zero data loss) and RTO (recovery) in minutes or less, then AWS DRS is the solution here. AWS DRS provides a nearly continuous block-level replication, recovery orchestration, and automated server conversion capabilities. With these, you to achieve a crash-consistent recovery point objective of seconds, and a recovery time objective typically ranging between 5–20 minutes. You can also use AWS DRS to configure your recovery Amazon Virtual Private Cloud (Amazon VPC). So, with the right settings, you can get your EC2 networking to look like your primary environment.
Protecting everything in your entire workload
Restoring data and static EC2 instances is only part of the disaster recovery solution that you need. Modern workloads often rely on a broader range of compute services, including EC2 Auto Scaling, AWS Lambda, Amazon ECS, and Amazon Elastic Kubernetes Service (Amazon EKS). For ECS and EKS, you can run on EC2 instances or go serverless with AWS Fargate. You will need a solution that can restore either of these.
The challenge with these services is making sure that they are recreated with the right configuration and metadata. For example, EC2 instance types and volume sizes, EC2 user data, or AWS Lambda function code, and not everything here is stateless. Both ECS and EKS can rely on persistent Amazon EBS volumes or Amazon Elastic File System (Amazon EFS). In those cases, recovery requires restoring the data and reattaching volumes restored from backup to the correct ECS tasks or EKS pods.
You can build automation to do all of this, or you can rely on an AWS Resilience Software Competency Partner solution to take care of this for you. Arpio is a software as a service (SaaS) product focused on discovering and backing up everything it takes to run your workload on AWS, and recovering it cross-Region and cross-account as a fully functional workload.
Figure 2 illustrates how AWS tools (left) establish a powerful foundation for robust workload recovery. Beyond these foundational building blocks, full recovery requires additional resources (right), including AWS compute options as discussed. Furthermore, complex networking (potentially spanning VPCs and accounts), infrastructure, and IAM principals are critical. Arpio uses and extends AWS Backup, AWS DRS, and other AWS service capabilities to back up and restore a functional AWS workload, including all its necessary components. This unburdens you from the undifferentiated heavy lifting of building your own automation. You still have responsibilities in the shared responsibility model, but Arpio takes on most of the work of getting you backed up and recovered.
Figure 2. AWS tools on the left provide a powerful foundation for full recovery on the right
Even with data, compute, networking, infrastructure, and IAM principals restored, there is another requirement to achieve full recovery: translation of your configuration. For example, an application that accesses the Amazon RDS database requires configuration information about the DB endpoint and credentials. When restoring your RDS instance into your recovery environment, it will have a new endpoint. Arpio addresses this using a two-fold strategy. First Arpio will find all references to the early database endpoint name and translate them to the new database endpoint name. Next, Arpio will also create an Amazon Route 53 private hosted zone in the recovered VPC, mapping the early endpoint to the new one using a CNAME record. This way, applications still using the early name still connect to the newly recovered database. Arpio also securely backs up the credentials in your recovery account, for every database backup taken, ready to be recovered for the point in time that you recover your database from. Figure 3 shows how your recovered application can seamlessly access your restored database.
Figure 3. Arpio automation ensures your applications can access your restored database in the recovery environment
Figure 4 shows a sample AWS workload protected by Arpio. In the standby state, you can see how Arpio is coordinating multiple AWS services. When a disaster or ransomware event occurs, you can launch a recovery. This will create a fully recovered workload as seen in the recovery stage on the right.
Figure 4. Sample AWS workload protected by Arpio
Arpio does all of this in your accounts, on your behalf. To enable this, Arpio applies AWS Well-Architected Tool (AWS WA Tool) best practices for security, using only IAM roles with least-privilege permissions. For example, the IAM role used to access your source AWS account is incapable of changing or mutating your source workload and is explicitly denied from reading or exfiltrating any data.
With its ability to back up over 140 AWS resources and restore them as fully functioning AWS workloads in a cross-Region cross-account recovery environment, Arpio builds on top of the powerful AWS tooling to streamline your complete workload recovery.
Conclusion
Disaster recovery (DR) is essential for a robust resilience strategy. By using the powerful tools offered by AWS and complementing them with AWS Resilience Competency Partner solutions like Arpio, organizations can significantly streamline access to comprehensive and powerful disaster recovery capabilities for their AWS workloads.
AWS Security Agent on-demand penetration testing is now generally available, enabling you to run comprehensive security tests across all your applications, not only your most critical ones. This milestone transforms penetration testing from a periodic bottleneck into an on-demand capability that scales with your development velocity across AWS, Azure, GCP, other cloud-providers, and on-premises. With multicloud support, AWS Security Agent allows you to consolidate penetration testing across your entire infrastructure.
AWS Security Agent delivers autonomous penetration testing that operates 24/7 at a fraction of the cost than manual penetration tests. Most organizations limit manual penetration testing to their most critical applications and conduct these tests periodically due to time and cost limitations. This approach can leave the majority of their application portfolio exposed to vulnerabilities in the periods between tests. Security Agent allows you to increase the penetration testing speed, frequency, and coverage across all applications, not just your top critical applications. The Security Agent approach compresses the penetration testing timeline from weeks to days, dramatically reducing your exposure window while maintaining development velocity.
In preview, HENNGE K.K. shared, “AWS Security Agent delivered valuable insights that enhance the robustness of HENNGE’s products and services—insights we hadn’t discovered through manual testing. The contextually aware agentic AI approach provides different insights than traditional methods, while surfacing valuable application improvements beyond pure security findings. This allows us to rapidly accelerate our security lifecycle, reducing the typical testing duration by more than 90%.”
How on-demand penetration testing works
AWS Security Agent represents a new class of frontier agents – autonomous systems that work independently to achieve goals, scale massively to tackle concurrent tasks, and run persistently without constant human oversight. It deploys specialized AI agents to help discover, validate, and report security vulnerabilities through sophisticated multi-step attack scenarios. Unlike traditional scanners that generate findings without validation, AWS Security Agent operates penetration tester, helping to identify potential vulnerabilities, then attempting to exploit them with targeted payloads and attack chains to confirm they are legitimate security risks.
Consider the example of deploying a new payment processing feature. With traditional penetration testing, you would either delay the release until the next scheduled assessment, which could be weeks or months away, or you would deploy with uncertainty. With AWS Security Agent, you initiate a penetration test in minutes and receive validated findings within hours, as shown in the following figure, which you can use to help identify and remediate critical vulnerabilities before they reach production and deploy more confidently.
Figure 1: Initiate a pen test in minutes and receive validated findings within hours.
This validation approach helps minimize false positives and provides visibility into the agent’s reasoning. The agent shows how it plans attacks, what payloads it uses, the tools it builds to execute exploits, and how it verifies successful exploitation, providing transparency. Each finding includes Common Vulnerability Scoring System (CVSS) risk scores, application-specific severity ratings, and detailed reproduction steps, as shown in the following figure, so your team can focus on confirmed vulnerabilities rather than investigating scanner noise.
Figure 2: Each finding includes Common Vulnerability Scoring System (CVSS) risk scores, application-specific severity ratings, and detailed reproduction steps.
How AWS Security Agent delivers proactive, context-aware application security
AWS Security Agent combines static application security testing (SAST), dynamic application security testing (DAST), and penetration testing into a single context-aware agent. The agent ingests design documents, architecture diagrams, infrastructure-as-code, source code, user stories, and threat models to understand how you designed, built, and deployed your application. It then identifies how individual vulnerabilities connect into higher-severity attack chains. Richer context produces higher-quality findings and more actionable remediation recommendations.
Consider three findings detected by AWS Security Agent
These might have been discovered by other tools, but if they were detected, they might not have been properly prioritized in isolation because those tools lack contextual awareness of how the application was designed, built, and used, and how each finding is being used as part of an attack chain. These findings exist in custom code written by the customer, so there might not be a Common Vulnerabilities and Exposures (CVE) vulnerability to detect in all cases, making these zero-day vulnerability discoveries.
Finding1 – Stored cross-site scripting (XSS) (CVSS 6.1, Medium): A threat actor could inject a script into a comment field that captures an admin’s session cookie inside standard HTTPS traffic. SAST and DAST might flag this as an isolated, medium-severity input validation issue competing with hundreds of other findings in a backlog. Without application context, these tools struggle to recognize it as the entry point to a critical chain.
Finding 2 – Session hijack through admin access (unscored):A threat actor could use a hijacked admin session to reach restricted endpoints. This step goes undetected by every tool category, SAST analyzes code not runtime sessions, DAST crawls as a standard user, Endpoint Detection and Response (EDR) and Extended Detection and Response (XDR) see a valid HTTPS session hidden among other valid traffic. No finding is generated and no alerts are fired.
Finding 3 – Database credential exfiltration through admin config endpoint (CVSS 9.8, Critical — never discovered):The admin panel exposes an /admin/config endpoint returning environment variables, including the production database connection string with credentials in plaintext. A threat actor could use a hijacked admin session to call this endpoint, extract credentials, connect directly to the production database containing customer personally identifiable information (PII), and exfiltrate the full customer dataset. SAST doesn’t flag this because the code functions as designed. DAST never reaches the admin panel. EDR and XDR see a legitimate authenticated API call.
AWS Security Agent connects the dots
By ingesting the source code and documentation, AWS Security Agent identifies that the /admin/config endpoint exposes database credentials, something SAST, DAST, or a Software Composition Analysis (SCA) scanner would struggle to identify. SAST and DAST might flag Finding 1 as isolated and medium severity without recognizing it as the entry point to a critical chain. Finding 2 goes undetected, because SAST analyzes code not sessions, DAST crawls as a standard user, EDR and XDR see valid HTTPS traffic hidden among other valid traffic. Finding 3 goes unflagged because SAST doesn’t flag endpoints functioning as designed, DAST never reaches the admin panel, and EDR and XDR see legitimate API calls. The program requirements document (PRD) provided the key context that the endpoint was designed for legitimate troubleshooting but assumed the authentication gateway would prevent unauthorized access. AWS Security Agent chains all three findings, tests each step, and proves the full attack works.
The chain is the vulnerability
A deprioritized CVSS 6.1 XSS unlocks a critical CVSS 9.8 database credential exfiltration through steps that are beyond the capabilities of most automated SAST or DAST tools. Finding 1 sits in a backlog for weeks, contributing to alert fatigue for developers and security teams. Finding 2 generates no finding. Finding3 functions as designed. Developers fix critical and high findings first, but a CVSS 6.1 among hundreds of others waits, leaving customers exposed. AWS Security Agent, informed with application context, elevates the entire sequence from three isolated findings to a critical, validated vulnerability. This means deeper insights and recommended remediations, fewer false positives, and more cost-effective penetration testing. Security teams can now confidently scale continuous penetration testing across a wider application portfolio than is being tested today, or isn’t being tested as frequently while it’s being developed. AWS Security Agent delivers these insights and recommended remediations within hours instead of weeks, helping customers ship more secured applications faster.
Scout24 confirmed the value of these capabilities directly: “AWS Security Agent outperformed traditional DAST by combining agentic testing with source-code context to deliver code-aware application security testing. It identified a critical publicly exploitable issue that other approaches had not surfaced. Its transparent reasoning gave us confidence in the attack paths explored and the coverage achieved.” – Abdul Al-Kibbe, Tech Lead, Security, Scout24 SE
Bamboo Health validated the depth of context-aware discovery in their own usage: “AWS Security Agent surfaced findings that no other tool has uncovered by truly understanding the application, its code, and connecting that context to what it discovered during testing. Legacy scanners simply could not match what Security Agent revealed. It gave us visibility into issues we typically would not see, even from human pentesting teams. For the first time, it felt like I had an AI tool on my side as a defender.” – Travis Allen, Manager of Security Operations at Bamboo Health
Set up your first penetration test
Setting up a penetration test is straightforward and includes the following steps.
Create agent spaces as logical boundaries Start by creating an agent space for each application or project. An agent space serves as a logical boundary where you can connect documents and code repositories for your application. The agent uses this application context from your documentation and code to create targeted test cases specific to your implementation. For example, create an Ecommerce Platform agent space and connect your GitHub repository, API specifications, and architecture documentation. By analyzing these materials to understand how your application handles payment processing, sessions, and user stories, the agent creates targeted test cases for payment manipulation vulnerabilities and session hijacking risks specific to your implementation.
Complete domain ownership validation Before testing begins, complete domain ownership validation by adding a DNS TXT record or uploading a verification file to your domain. This required step helps ensure you have authorization to test the target application, protecting both you and AWS. Complete this one-time setup for all domains during initial configuration to prevent delays when running penetration tests.
Add application context for improved accuracy and deeper findings While optional, providing source code and documentation considerably improves testing accuracy. Include the following:
Source code: Enables white-box testing to identify implementation-specific vulnerabilities. You can directly connect your source code repositories with GitHub integration
API specifications (OpenAPI or Swagger): Documents all endpoints, parameters, and authentication requirements so the agent tests comprehensively rather than discovering endpoints through trial and error
Architecture documentation: Helps the agent understand service interactions and potential attack chains
Product requirements documents:Helps the agent understand purpose, features, functionality, and user stories when using the application
Existing threat models: Guides the agent to focus on your highest-risk areas and known concerns
Test across any environment AWS Security Agent operates across AWS, Azure, GCP, other cloud-providers, and on-premises. Configure public endpoints directly by providing the URL, or connect private endpoints through a VPC for secure testing of internal applications without internet exposure. By using this multicloud support, you can consolidate security testing across your entire infrastructure using AWS Security Agent.
Testing authenticated applications
Most vulnerabilities exist in authenticated areas of applications, and you can’t find them without signing in. Configure multiple credentials for different user roles to enable comprehensive testing:
Standard user credentials for customer-facing functionality
Privileged user credentials for administrative functions
Service account credentials for API-to-API authentication
Multi-factor authentication (MFA), including MFA and two-factor authentication (2FA) and
By testing with multiple credential sets, AWS Security Agent identifies privilege escalation vulnerabilities, for example, discovering that a standard user can access admin functions by manipulating API parameters.
Provide sign-in guidance for complex authentication
AWS Security Agent uses large language model (LLM)-based sign-in capabilities to navigate authentication flows including OAuth, SAML, Okta, and MFA. Providing clear sign-in guidance significantly improves success rates, for example:
Navigate to app.example.com/auth/login
Enter username in the Email or Username field
Enter password in the Password field
Choose Sign In
Specific instructions, sequential steps, and success verification criteria help the agent navigate your authentication flow reliably.
From findings to fixes: The complete security lifecycle
Review the findings and take actions to remediate with AWS Security Agent.
Validated, actionable findings AWS Security Agent validates potential vulnerabilities by attempting exploitation to confirm the security risk exists. This validation approach minimizes false positives and reduces the time your team spends manually verifying findings, so you can focus on legitimate vulnerabilities that require fixes. The agent achieved a 92.5% success rate on CVE Bench v2.0, demonstrating its capability to discover and validate real-world vulnerabilities.
Each finding includes CVSS risk scores, application-specific severity ratings, detailed reproduction steps, and impact analysis that explains the business risk. In an ecommerce application, the agent might discover a price manipulation vulnerability and show that attackers can modify product prices during checkout, allowing customers to obtain items for free and directly impacting revenue.
The agent also identifies how vulnerabilities chain together, showing how lower-severity findings can become gateways to critical exploits.
You can export reports as PDF files for executive reporting, compliance documentation, developer handoffs, and audit trails.
Remediation with code fix suggestion completes the process Traditional penetration testing ends with a report, then weeks or months pass while developers research, implement, and deploy fixes. AWS Security Agent completes the security lifecycle:
Run penetration test and identify confirmed vulnerabilities
Review findings and prioritize critical issues
Trigger remediation to generate pull requests with code fixes
Developer review and merge the ready-to-implement fixes in hours instead of days
Retest to confirm vulnerabilities are resolved
Deploy with confidence knowing security issues are addressed
Get started with on-demand penetration testing
AWS Security Agent on-demand penetration testing is now available in the following AWS Regions:
US East (N. Virginia)
US West (Oregon)
Europe (Ireland)
Europe (Frankfurt)
Asia Pacific (Sydney)
Asia Pacific (Tokyo)
Pricing
Pricing is straightforward and transparent: $50 per task-hour, metered per second. A task-hour represents the time AWS Security Agent actively works on testing your application. Based on current metrics, an average application test takes approximately 24 task-hours, resulting in a typical cost of $1,200 per comprehensive penetration test and remediation. See the AWS Security Agent pricing page for more details on pricing and free trial.
Sample bill:
Small web application (8 task-hours): $400
Medium ecommerce platform (24 task-hours): $1,200
Large enterprise application (48 task-hours): $2,400
Note: The preceding sample bills and estimated costs are for illustrative purposes only and are not guaranteed. Actual costs can vary based on multiple factors including application complexity, number of endpoints, authentication mechanisms, code base size, and the depth of testing required. Your actual penetration test duration and cost will depend on your specific application characteristics.
By using AWS Security Agent, you can perform penetration testing more quickly, frequently, and on more of your applications at a reduced cost. For example, some customers found that AWS Security Agent provided up to 70–90% savings compared to traditional manual penetration testing approaches.
Ready to transform your security testing? Create your first agent space and run your first penetration test in minutes:
Connect your code repository and add documentation
Configure and run your first penetration test
Conclusion
By using on-demand penetration testing in AWS Security Agent, you can test all your applications continuously, not just your most critical ones periodically. Start with one application, experience validated findings and automatic remediation in action, then scale comprehensive security testing across your entire portfolio.
I may have just automated myself into a completely different job…
This is a familiar pattern among software engineers, who often, through inspiration, frustration, or sometimes even laziness, build systems to remove toil and focus on more creative work. We then end up owning and maintaining those systems, unlocking that automated goodness for the rest of those around us.
As an AI researcher, I recently took this beyond what was previously possible and have automated away my intellectual toil. And now I find myself maintaining this tool to enable all my peers on the Copilot Applied Science team to do the same.
During this process, I learned a lot about how to effectively create and collaborate using GitHub Copilot. Applying these learnings has unlocked an incredibly fast development loop for myself as well as enabled my team mates to build solutions to fit their needs.
Before I get into explaining how I made this possible, let me set the stage for what spawned this project so you better understand the scope of what you can do with GitHub Copilot.
The impetus
A large part of my job involves analyzing coding agent performance as measured against standardized evaluation benchmarks, like TerminalBench2 or SWEBench-Pro. This often involves poring through tons of what are called trajectories, which are essentially lists of the thought processes and actions agents take while performing tasks.
Each task in an evaluation dataset produces its own trajectory, showing how the agent attempted to solve that task. These trajectories are often .json files with hundreds of lines of code. Multiply that over dozens of tasks in a benchmark set and again over the many benchmark runs needing analysis on any given day, and we’re talking hundreds of thousands of lines of code to analyze.
It’s an impossible task to do alone, so I would typically turn to AI to help. When analyzing new benchmark runs, I found that I kept repeating the same loop: I used GitHub Copilot to surface patterns in the trajectories then investigated them myself—reducing the number of lines of code I had to read from hundreds of thousands to a few hundred.
However, the engineer in me saw this repetitive task and said, “I want to automate that.” Agents provide us with the means to automate this kind of intellectual work, and thus eval-agents was born.
The plan
Engineering and science teams work better together. That was my guiding principle as I set about solving this new challenge.
Thus, I approached the design and implementation strategy of this project with a couple of goals in mind:
Make these agents easy to share and use
Make it easy to author new agents
Make coding agents the primary vehicle for contributions
Bullets one and two are in GitHub’s lifeblood and are values and skills I’ve gained throughout my career, especially during my stint as an OSS maintainer on the GitHub CLI.
However, goal three shaped the project the most. I noticed that when I set GitHub Copilot up to help me build the tool effectively, it also made the project easier to use and collaborate on. That experience taught me a few key lessons, which ultimately helped push the first and second goals forward in ways I didn’t expect.
Making coding agents your primary contributor
I’ll start by describing my agentic coding setup:
Coding agent: Copilot CLI
Model used: Claude Opus 4.6
IDE: VSCode
It’s also noteworthy that I leveraged the Copilot SDK to accelerate agent creation, which is powered under the hood by the Copilot CLI. This gave me access to existing tools and MCP servers, a way to register new tools and skills, and a whole bunch of other agentic goodness out of the box that I didn’t have to reinvent myself.
With that out of the way, I could streamline the whole development process very quickly by following a few core principles:
Prompting strategies: agents work best when you’re conversational, verbose, and when you leverage planning modes before agent modes.
Architectural strategies: refactor often, update docs often, clean up often.
Iteration strategies: “trust but verify” is now “blame process, not agents.”
Uncovering and following these strategies led to an incredible phenomenon: adding new agents and features was fast and easy. We had five folks jump into the project for the first time, and we created a total of 11 new agents, four new skills, and the concept of eval-agent workflows (think scientist streams of reasoning) in less than three days. That amounted to a change of +28,858/-2,884 lines of code across 345 files.
Holy crap!
Below, I’ll go into detail about these three principles and how they enabled this amazing feat of collaboration and innovation.
Prompting strategies
We know that AI coding agents are really good at solving well-scoped problems but need handholding for the more complex problems you’d only entrust to your more senior engineers.
So, if you want your agent to act like an engineer, treat it like one. Guide its thinking, over-explain your assumptions, and leverage its research speed to plan before jumping into changes. I found it far more effective to put some stream-of-consciousness musings about a problem I was chewing on into a prompt and working with Copilot in planning mode than to give it a terse problem statement or solution.
Here’s an example of a prompt I wrote to add more robust regression tests to the tool:
> /plan I've recently observed Copilot happily updating tests to fit its new paradigms even though those tests shouldn't be updated. How can I create a reserved test space that Copilot can't touch or must reserve to protect against regressions?
This resulted in a back and forth that ultimately led to a series of guardrails akin to contract testing that can only be updated by humans. I had an idea of what I wanted, and through conversation, Copilot helped me get to the right solution.
It turns out that the things that make human engineers the most effective at doing their jobs are the same things that make these agents effective at doing theirs.
Architectural strategies
Engineers, rejoice! Remember all those refactors you wanted to do to make the codebase more readable, the tests you never had time to write, and the docs you wish had existed when you onboarded? They’re now the most important thing you can be working on when building an agent-first repository.
Gone are the days where deprioritizing this work over new feature work was necessary, because delivering features with Copilot becomes trivial when you have a well-maintained, agent-first project.
I’ve spent most of my time on this project refactoring names and file structures, documenting new features or patterns, and adding test cases for problems that I’ve uncovered as I go. I’ve even spent a few cycles cleaning up the dead code that the agents (like your junior engineers) may have missed while implementing all these new features and changes.
This work makes it easy for Copilot to navigate the codebase and understand the patterns, just like it would for any other engineer.
I can even ask, “Knowing what I know now, how would I design this differently?” And I can then justify actually going back and rearchitecting the whole project (with the help of Copilot, of course).
It’s a dream come true!
And this leads me to my last bit of guidance.
Iteration strategies
As agents and models have improved, I have moved from a “trust but verify” mindset to one that is more trusting than doubtful. This mirrors how the industry treats human teams: “blame process, not people.” It’s how the most effective teams operate, because people make mistakes, so we build systems around that reality.
This idea of blameless culture provides psychological safety for teams to iterate and innovate, knowing that they won’t be blamed if they make a mistake. The core principle is that we implement processes and guardrails to protect against mistakes, and if a mistake does happen, we learn from it and introduce new processes and guardrails so that our teams won’t make the same mistake again.
Applying this same philosophy to agent-driven development has been fundamental to unlocking this incredibly rapid iteration pipeline. That means we add processes and guardrails to help prevent the agent from making mistakes, but when it does make a mistake, we add additional guardrails and processes—like more robust tests and better prompts—so the agent can’t make the same mistake again. Taking this one step further means that practicing good CI/CD principles is a must.
Practices like strict typing ensure the agent conforms to interfaces. Robust linters impose implementation rules on the agent that keep it following good patterns and practices. And integration, end-to-end, and contract tests—which can be expensive to build manually—become much cheaper to implement with agent assistance, while giving you confidence that new changes don’t break existing features.
When Copilot has these tools available in its development loop, it can check its own work. You’re setting it up for success, much in the same way you’d set up a junior engineer for success in your project.
Putting it all together
Here’s what all this means for your development loop when you’ve got your codebase set up for agent-driven development:
Plan a new feature with Copilot using /plan.
Iterate on the plan.
Ensure that testing is included in the plan.
Ensure that docs updates are included in the plan and done before code is implemented. These can serve as additional guidelines that live beside your plan.
Let Copilot implement the feature on /autopilot.
Prompt Copilot to initiate a review loop with the Copilot Code Review agent. For me, it’s often something like: request Copilot Code Review, wait for the review to finish, address any relevant comments, and then re-request review. Continue this loop until there are no more relevant comments.
Human review. This is where I enforce the patterns I discussed in the previous sections.
Additionally, outside of your feature loop, be sure you’re prompting Copilot early and often with the following:
/plan Review the code for any missing tests, any tests that may be broken, and dead code
/plan Review the code for any duplication or opportunities for abstraction
/plan Review the documentation and code to identify any documentation gaps. Be sure to update the copilot-instructions.md to reflect any relevant changes
I have these run automatically once a week, but I often find myself running them throughout the week as new features and fixes go in to maintain my agent-driven development environment.
Take this with you
What started as a frustration with an impossibly repetitive analysis task turned into something far more interesting: a new way of thinking about how we build software, how we collaborate, and how we grow as engineers.
Building agents with a coding agent-first mindset has fundamentally changed how I work. It’s not just about the automation wins—though watching four scientists ship 11 agents, four skills, and a brand-new concept in under three days is nothing short of remarkable. It’s about what this style of development forces you to prioritize: clean architecture, thorough documentation, meaningful tests, and thoughtful design—the things we always knew mattered but never had time for.
The analogy to a junior engineer keeps proving itself out. You onboard them well, give them clear context, build guardrails so their mistakes don’t become disasters, and then trust them to grow. If something goes wrong, you blame the process. Not the agent. If there’s one thing I want you to take away from this, it’s that the skills that make you a great engineer and a great teammate are the same skills that make you great at building with Copilot. The technology is new. The principles aren’t.
So go clean up that codebase, write that documentation you’ve been putting off, and start treating your Copilot like the newest member of your team. You might just automate yourself into the most interesting work of your career.
Amazon Managed Workflows for Apache Airflow (Amazon MWAA) provides robust orchestration capabilities for data workflows, but managing DAG permissions at scale presents significant operational challenges. As organizations grow their workflow environments and teams, manually assigning and maintaining user permissions becomes a bottleneck that can impact both security and productivity.
Traditional approaches require administrators to manually configure role-based access control (RBAC) for each DAG, leading to:
Inconsistent permission assignments across teams
Delayed access provisioning for new team members
Increased risk of human error in permission management
Significant operational overhead that doesn’t scale
There is another way of doing it by defining custom RBAC roles as mentioned in this Amazon MWAA User Guide. However, it doesn’t use Airflow tags to do so.
In this post, we show you how to use Apache Airflow tags to systematically manage DAG permissions, reducing operational burden while maintaining robust security controls that complement infrastructure-level security measures.
Prerequisites
To implement this solution, you need:
AWS resources:
An Amazon MWAA environment (version 2.7.2 or later, not supported in Airflow 3.0)
IAM roles configured for Amazon MWAA access with appropriate trust relationships
Amazon Simple Storage Service (Amazon S3) bucket for Amazon MWAA DAG storage with proper permissions
Permissions:
IAM permissions to create and modify Amazon MWAA web login tokens
Amazon MWAA execution role with permissions to access the Apache Airflow metadata database
Administrative access to configure Apache Airflow roles and permissions
Solution overview
The automated permission management system consists of four key components that work together to provide scalable, secure access control.The following diagram shows the workflow of how the solution works.
IAM integration layer – AWS IAM roles map directly to Apache Airflow roles. Then, users authenticate through AWS IAM and are automatically assigned corresponding Airflow roles. This supports both individual user roles and group-based access patterns. Note:
IAM Based access control to Amazon MWAA works for Apache Airflow default roles. For custom roles, the Admin user can assign the custom role using the Apache Airflow UI as mentioned in the Knowledge Center post and in the Amazon MWAA User Guide.
If using other authenticators, the tag-based DAG permissions continue to work as stated in the AWS Big Data Blog post.
Tag-based configuration – Apache Airflow tags defined in DAGs are used to declare access requirements. It supports read-only, edit, and delete permissions.
Automated synchronization engine – Scheduled DAG scans all active DAGs for permission tags based on CRON schedule. It then processes tags and updates Apache Airflow RBAC permissions accordingly. Then, it provides a configuration based to control the clean-up of existing permissions.
Role-based access control enforcement – Apache Airflow RBAC enforces the configured permissions by storing on Apache Airflow role and permissions metadata tables. Users see only the DAGs that they have access to. They have granular control over read compared to edit permissions.
Data flow
Amazon MWAA User assumes an IAM role to access the Amazon MWAA UI.
DAG developer adds relevant tags to the DAG definition.
manage_dag_permissions DAG deployed to the Amazon MWAA environment runs on a CRON schedule, for example, daily.
The DAG updates the respective role permissions to the DAG by updating the Apache Airflow metadata on the Apache Airflow DB.
Users gain or lose access based on their assigned roles.
Our solution builds upon the existing IAM integration of Amazon MWAA, while extending functionality through custom automation:
Authentication and role mapping – Users authenticate through AWS IAM roles that map directly to corresponding Airflow roles.
Automated user creation – Upon first login, users are automatically created in the Apache Airflow metadata database with appropriate role assignments.
Tag-based permission control – Each Apache Airflow role contains specific DAG permissions based on tags defined in the DAGs.
Automated synchronization – A scheduled script maintains permissions as DAGs are added or modified.
Step 1: Configure IAM to Airflow role mapping
First, establish the mapping between your IAM principals and Apache Airflow roles. To grant permission using the AWS Management Console, complete the following steps:
Sign in to your AWS account and open the IAM console.
In the left navigation pane, choose Users, then choose your Amazon MWAA IAM user from the users table.
On the user details page, under Summary, choose the Permissions tab, then choose Permissions policies to expand the card and choose Add permissions.
In the Grant permissions section, choose Attach existing policies directly, then choose Create policy to create and attach your own custom permissions policy.
On the Create policy page, choose JSON, then copy and paste the following JSON permissions policy in the policy editor. This policy grants web server access to the user with the default Public Apache Airflow role.
Step 2: Create the automated permission management DAG
Now, create a DAG that will automatically manage permissions based on tags.
from airflow import DAG, settings
from airflow.operators.python import PythonOperator
from sqlalchemy import text
import pendulum
import logging
dag_id = "manage_dag_permissions"
class Constants:
"""
Constants class to hold constant values used throughout the code.
"""
AB_VIEW_MENU = "ab_view_menu"
AB_PERMISSION = "ab_permission"
AB_ROLE = "ab_role"
AB_PERMISSION_VIEW = "ab_permission_view"
AB_PERMISSION_VIEW_ROLE = "ab_permission_view_role"
DAG_TAG = "dag_tag"
CAN_READ = "can_read"
CAN_EDIT = "can_edit"
CAN_DELETE = "can_delete"
def _execute_query(sql_text, params=None, fetch=True):
"""
Execute a parameterized SQL query against the Airflow metadata DB.
All queries use SQLAlchemy text() with bind parameters to prevent SQL injection.
Parameters:
sql_text: SQL string with :named bind parameters
params: dict of parameter values
fetch: If True, return list of first-column values; if False, commit and return None
Returns:
List of values (first column) if fetch=True, else None
Raises:
Re-raises any exception after rollback and logging
"""
session = settings.Session()
try:
stmt = text(sql_text)
if fetch:
result = session.execute(stmt, params or {}).fetchall()
return [row[0] for row in result]
else:
session.execute(stmt, params or {})
session.commit()
return None
except Exception as e:
session.rollback()
logging.error(f"DB query error (fetch={fetch}): {type(e).__name__}: {e}")
raise
finally:
session.close()
def fetch_airflow_role_id(role_name):
"""
Fetch role id of a given role name using parameterized query.
"""
result = _execute_query(
"SELECT id FROM ab_role WHERE name = :role_name",
{"role_name": role_name},
)
if not result:
raise ValueError(f"Airflow role not found: {role_name}")
logging.info("Fetched role ID successfully")
return result[0]
def fetch_airflow_permission_id(permission_name):
"""
Fetch permission id of a given permission using parameterized query.
"""
result = _execute_query(
"SELECT id FROM ab_permission WHERE name = :perm_name",
{"perm_name": permission_name},
)
if not result:
raise ValueError(f"Airflow permission not found: {permission_name}")
logging.info("Fetched permission ID successfully")
return result[0]
def fetch_airflow_menu_object_ids(dag_names):
"""
Fetch view_menu IDs for a list of DAG resource names.
Uses parameterized IN-clause via individual bind params.
Parameters:
dag_names: list of DAG resource names (e.g. ['DAG:my_dag1', 'DAG:my_dag2'])
Returns:
list of view_menu IDs
"""
if not dag_names:
return []
# Build parameterized IN clause: :p0, :p1, :p2, ...
param_names = [f":p{i}" for i in range(len(dag_names))]
params = {f"p{i}": name for i, name in enumerate(dag_names)}
in_clause = ", ".join(param_names)
result = _execute_query(
f"SELECT id FROM ab_view_menu WHERE name IN ({in_clause})",
params,
)
logging.info(f"Fetched {len(result)} view menu IDs")
return result
def fetch_perms_obj_association_ids(perm_id, view_menu_ids):
"""
Fetch permission_view IDs for a permission and list of view_menu IDs.
Uses parameterized query.
"""
if not view_menu_ids:
return []
param_names = [f":vm{i}" for i in range(len(view_menu_ids))]
params = {f"vm{i}": vm_id for i, vm_id in enumerate(view_menu_ids)}
params["perm_id"] = perm_id
in_clause = ", ".join(param_names)
result = _execute_query(
f"SELECT id FROM ab_permission_view WHERE permission_id = :perm_id AND view_menu_id IN ({in_clause})",
params,
)
logging.info(f"Fetched {len(result)} permission-view association IDs")
return result
def fetch_dag_ids_by_tag(tag_name):
"""
Fetch DAG IDs with a given tag name using parameterized query.
"""
result = _execute_query(
"SELECT DISTINCT dag_id FROM dag_tag WHERE name = :tag_name",
{"tag_name": tag_name},
)
logging.info(f"Fetched {len(result)} DAG IDs for tag")
return result
def associate_permission_to_object(perm_id, view_menu_ids):
"""
Associate permission to view_menu objects (DAGs) using parameterized INSERT.
"""
session = settings.Session()
try:
for vm_id in view_menu_ids:
session.execute(
text(
"INSERT INTO ab_permission_view (permission_id, view_menu_id) "
"VALUES (:perm_id, :vm_id) "
"ON CONFLICT (permission_id, view_menu_id) DO NOTHING"
),
{"perm_id": perm_id, "vm_id": vm_id},
)
session.commit()
logging.info(f"Associated permission to {len(view_menu_ids)} view menus")
except Exception as e:
session.rollback()
logging.error(f"Error associating permission to objects: {type(e).__name__}: {e}")
raise
finally:
session.close()
def associate_permission_to_role(permission_view_ids, role_id):
"""
Associate permission_view entries to a role using parameterized INSERT.
"""
session = settings.Session()
try:
for pv_id in permission_view_ids:
session.execute(
text(
"INSERT INTO ab_permission_view_role (permission_view_id, role_id) "
"VALUES (:pv_id, :role_id) "
"ON CONFLICT (permission_view_id, role_id) DO NOTHING"
),
{"pv_id": pv_id, "role_id": role_id},
)
session.commit()
logging.info(f"Associated {len(permission_view_ids)} permissions to role")
except Exception as e:
session.rollback()
logging.error(f"Error associating permissions to role: {type(e).__name__}: {e}")
raise
finally:
session.close()
def validate_if_permission_granted(permission_view_ids, role_id):
"""
Validate if given permissions are associated to given role using parameterized query.
"""
if not permission_view_ids:
return []
param_names = [f":pv{i}" for i in range(len(permission_view_ids))]
params = {f"pv{i}": pv_id for i, pv_id in enumerate(permission_view_ids)}
params["role_id"] = role_id
in_clause = ", ".join(param_names)
result = _execute_query(
f"SELECT id FROM ab_permission_view_role "
f"WHERE permission_view_id IN ({in_clause}) AND role_id = :role_id",
params,
)
logging.info(f"Validated {len(result)} permission grants")
return result
def clean_up_existing_dag_permissions_for_role(role_id):
"""
Clean up existing DAG permissions for a given role using parameterized query.
Note: this creates a brief window where the role has no DAG permissions.
"""
_execute_query(
"DELETE FROM ab_permission_view_role WHERE id IN ("
" SELECT pvr.id"
" FROM ab_permission_view_role pvr"
" INNER JOIN ab_permission_view pv ON pvr.permission_view_id = pv.id"
" INNER JOIN ab_view_menu vm ON pv.view_menu_id = vm.id"
" WHERE pvr.role_id = :role_id AND vm.name LIKE :dag_prefix"
")",
{"role_id": role_id, "dag_prefix": "DAG:%"},
fetch=False,
)
logging.info("Cleaned up existing DAG permissions for role")
def sync_permission(config_data):
"""
Sync permissions based on the config.
Parameters:
config_data: dict with keys:
- airflow_role_name: name of the custom Airflow role
- managed_dags: list of DAG IDs to grant full management permissions on
(can_read, can_edit, can_delete)
- do_cleanup: if True, remove all existing DAG:* permissions first
"""
# Get the role ID for role name
role_id = fetch_airflow_role_id(config_data["airflow_role_name"])
# Clean up existing DAG level permissions if requested
if config_data.get("do_cleanup", False):
clean_up_existing_dag_permissions_for_role(role_id)
managed_dags = config_data.get("managed_dags", [])
if not managed_dags:
logging.info("No managed DAGs found, skipping permission sync")
return
# Determine which permissions to grant (default: can_read only)
permissions = config_data.get("permissions", [Constants.CAN_READ])
# Build DAG resource names (e.g. ["DAG:my_dag1", "DAG:my_dag2"])
dag_resource_names = [f"DAG:{dag.strip()}" for dag in managed_dags]
# Get IDs for DAG view_menu objects
vm_ids = fetch_airflow_menu_object_ids(dag_resource_names)
if not vm_ids:
logging.info("No view_menu entries found for managed DAGs")
return
# Grant the configured permissions on each managed DAG
all_perm_view_ids = []
for perm_name in permissions:
perm_id = fetch_airflow_permission_id(perm_name)
associate_permission_to_object(perm_id, vm_ids)
all_perm_view_ids += fetch_perms_obj_association_ids(perm_id, vm_ids)
# Associate permission_view entries with the role and validate
if all_perm_view_ids and role_id:
associate_permission_to_role(all_perm_view_ids, role_id)
validate_if_permission_granted(all_perm_view_ids, role_id)
def sync_permissions_with_tags(role_mappings):
"""
For each role mapping, fetch DAG IDs by tag and sync permissions.
"""
for role_map in role_mappings:
username = list(role_map.keys())[0]
airflow_role = role_map[username]["airflow_role"]
edit_tag_name = role_map[username]["airflow_edit_tag"]
config_data = {
"airflow_role_name": airflow_role,
"managed_dags": fetch_dag_ids_by_tag(edit_tag_name),
"permissions": role_map[username].get("permissions", [Constants.CAN_READ]),
"do_cleanup": role_map[username].get("do_cleanup", True),
}
logging.info(f"Syncing permissions for airflow role")
sync_permission(config_data)
logging.info("Completed permission sync for role")
"""
Add new roles and permissions here.
Format:
{
"<role_key>": {
"airflow_role": <Custom Airflow role name to grant permissions to>,
"airflow_edit_tag": <Airflow Tag Name - DAGs with this tag will be managed>,
"permissions": <List of permissions to grant on each tagged DAG.
Options: "can_read", "can_edit", "can_delete"
Default: ["can_read"] if omitted>,
"do_cleanup": <Set to True (recommended) to clean up existing DAG permissions>
}
},
IMPORTANT - ROLE SETUP:
When creating a new custom role (e.g. "analytics_reporting", "marketing_analyst")
in the Airflow UI (Security > List Roles), you MUST copy the Viewer role's
permissions into the new role. The Viewer permissions provide base UI access
(browse DAGs, view logs, menu access, etc.). --or-- Assign the viewer role as well.
Without them, users assigned to
the custom role will not be able to log in to the Airflow UI.
This DAG manages DAG-level permissions on DAG:xxx resources.
Which permissions are granted is controlled by the "permissions" list
in each config entry (options: can_read, can_edit, can_delete).
It does NOT manage base UI permissions — those must be set up manually
when creating the role.
Steps to create a new custom role:
1. Go to Security > List Roles > + (Add)
2. Name it to match the "airflow_role" value in the config below
3. Copy all permissions from the "Viewer" role into the new role
4. Save — this DAG will then automatically add DAG-specific permissions
(as configured in the "permissions" list) for each tagged DAG
"""
role_mappings = [
{
"analytics_reporting": {
"airflow_role": "analytics_reporting",
"airflow_edit_tag": "analytics_reporting_edit",
"permissions": ["can_read", "can_edit", "can_delete"],
"do_cleanup": True,
}
},
{
"marketing_analyst": {
"airflow_role": "marketing_analyst",
"airflow_edit_tag": "marketing_analyst_edit",
"permissions": ["can_read", "can_edit", "can_delete"],
"do_cleanup": True,
},
},
]
with DAG(
dag_id=dag_id,
schedule="*/15 * * * *",
catchup=False,
start_date=pendulum.datetime(2026, 1, 1, tz="UTC"),
) as dag:
sync_dag_permissions_task = PythonOperator(
task_id="sync_dag_permissions",
python_callable=sync_permissions_with_tags,
op_kwargs={"role_mappings": role_mappings},
)
Step 3: Tag your DAGs for access control
Add appropriate tags to your DAGs to specify which roles should have access. Tags are used to define which roles have access to tagged DAGs.
# Example DAG for analytics_reporting
with DAG(
"analytics_reporting_dag",
description="Daily analytics reporting pipeline",
schedule_interval="@daily",
start_date=pendulum.datetime(2023, 1, 1, tz="UTC"),
catchup=False,
tags=["reporting", "analytics", "analytics_reporting_edit"]
) as dag:
# DAG tasks here
pass
# Example DAG for marketing_analyst
with DAG(
"marketing_analyst_dag",
description="Daily marketing lead analysis pipeline",
schedule_interval="@daily",
start_date=pendulum.datetime(2023, 1, 1, tz="UTC"),
catchup=False,
tags=["marketing", "analytics", "marketing_analyst_edit"]
) as dag:
# DAG tasks here
pass
In this example:
The analytics_reporting custom role will have read, edit, and delete access to the DAG analytics_reporting_dag (and other DAGs tagged with analytics_reporting_edit)
The marketing_analyst custom role will have read, edit, and delete access to the DAG marketing_analyst_dag (and other DAGs tagged with marketing_analyst_edit)
The exact permissions granted (can_read, can_edit, can_delete) are configurable per role in the role_mappings config inside the permission management DAG:
Note: Before this DAG can manage permissions for a custom role, the role must be created manually in the Apache Airflow UI (Security > List Roles) with the Viewer role’s permissions copied in. See Step 2 for details.
Step 4: Deploy and test
Upload both the permission management DAG and your tagged DAGs to your Amazon MWAA environment’s S3 bucket.
Wait for Amazon MWAA to detect and process the new DAGs.
Verify that the permission management DAG runs successfully.
Test access with different user roles to confirm proper permission enforcement.
In this section, we cover some common issues and how to troubleshoot them.
Permission sync failures
Symptom: Permission sync DAG fails with database errors.
Cause: Insufficient permissions on MWAA execution role.
Solution: Ensure that the execution role has airflow:CreateWebLoginToken permission and database access.
Tags not being processed
Symptom: DAG tags are present but permissions aren’t updated.
Solution: Check that DAG is active and parsed successfully – Review permission sync DAG logs for processing errors.
Users cannot access expected DAGs
Symptom: Users with correct IAM roles cannot see DAGs
Solution: Confirm that IAM to Apache Airflow role mapping is correct. Verify that the permission sync DAG has run successfully. Check Amazon CloudWatch Logs for permission assignment errors.
Performance issues
Symptom: Permission sync takes too long or times out.
Solution: Reduce sync frequency for large environments. Consider batching permission updates. Monitor DAG execution time and optimize accordingly.
Debugging steps
Check Amazon MWAA environment health and connectivity
Review permission sync DAG execution logs
Verify IAM role configurations and trust relationships
Test with a single DAG to isolate issues
Monitor CloudWatch Logs for detailed error messages
Benefits and considerations
Automated permission management offers you significant operational advantages while enhancing your security. You will benefit from reduced administrative overhead as manual permission assignments are removed, so you can scale seamlessly without additional burden. Your security improves through consistent application of least-privilege principles and reduced human error. You will enhance your developer experience with automatic access provisioning that shortens onboarding time, while your system supports environments with over 500 DAGs without performance degradation.
When you implement these systems, you must adhere to key security practices. You should apply the principle of least privilege, validate tags to make sure that you’re only processing authorized tags, and establish comprehensive audit mechanisms including CloudTrail logging. Your access control measures should restrict permission management functions to administrators while you utilize appropriate role separation for different user personas.
You will need to consider several technical limitations during your implementation. IAM-based access control to Amazon MWAA works only with Apache Airflow default roles, not custom ones, though your tag-based permissions function with alternative authenticators. Permission changes propagate based on DAG schedules, potentially causing delays. You should establish approval processes for your production changes, maintain version control for permissions, and document your rollback procedures to ensure your system’s resilience and security.
Update the IAM role policy or delete the IAM role if not needed.
Conclusion
In this post, you learned how to automate DAG permission management in Amazon MWAA using Apache Airflow’s tagging system. You saw how to implement tag-based access control that scales efficiently, reduces manual errors, and maintains least-privilege security principles across hundreds of DAGs. You also explored the key security practices and technical considerations that you need to keep in mind during implementation.
Try out this solution in your Amazon MWAA environment to streamline your permission management. Start by implementing the tagging system in a development environment, then gradually roll it out to production as your team becomes comfortable with the approach.
Discussion of
a memory-management patch set intended to clean up a helper function for
handling huge pages spiraled into something else entirely after it was posted on March 19.
Memory-management maintainer Andrew Morton
proposed making changes to the subsystem’s review process, to require
patch authors to respond to feedback from Sashiko,
the
recently released LLM-based kernel patch review system. Other
sub-maintainers, particularly Lorenzo Stoakes, objected. The
resulting discussion about how and when to adopt Sashiko is potentially relevant
to many other parts of the kernel.
In early March, Dylan M. Taylor submitted a pull request to add a field
to store a user’s birth date in systemd’s JSON user records. This was done to allow
applications to store the date to facilitate compliance with age-attestation and
-verification laws. It was to be expected that some members of the community would
object; the actual response, however, has been shockingly hostile. Some of this has
been fueled by a misinformation campaign that has targeted the systemd project and
Taylor specifically, resulting in Taylor being doxxed and receiving death
threats. Such behavior is not just problematic; it is also deeply misguided given the
actual nature of the changes.
There is a
blog post on sockpuppet.org arguing that we are not prepared for the
upcoming flood of high-quality, LLM-generated vulnerability reports and
exploits.
Now consider the poor open source developers who, for the last 18
months, have complained about a torrent of slop vulnerability
reports. I’d had mixed sympathies, but the complaints were at least
empirically correct. That could change real fast. The new models
find real stuff. Forget the slop; will projects be able to keep up
with a steady feed of verified, reproducible, reliably-exploitable
sev:hi vulnerabilities? That’s what’s coming down the pipe.
Everything is up in the air. The industry is sold on memory-safe
software, but the shift is slow going. We’ve bought time with
sandboxing and attack surface restriction. How well will these
countermeasures hold up? A 4 layer system of sandboxes, kernels,
hypervisors, and IPC schemes are, to an agent, an iterated version
of the same problem. Agents will generate full-chain exploits, and
they will do so soon.
Meanwhile, no defense looks flimsier now than closed source
code. Reversing was already mostly a speed-bump even for
entry-level teams, who lift binaries into IR or decompile them all
the way back to source. Agents can do this too, but they can also
reason directly from assembly. If you want a problem better suited
to LLMs than bug hunting, program translation is a good place to
start.
We’re proud to introduce Programmable Flow Protection: a system designed to let Magic Transit customers implement their own custom DDoS mitigation logic and deploy it across Cloudflare’s global network. This enables precise, stateful mitigation for custom and proprietary protocols built on UDP. It is engineered to provide the highest possible level of customization and flexibility to mitigate DDoS attacks of any scale.
Programmable Flow Protection is currently in beta and available to all Magic Transit Enterprise customers for an additional cost.
Programmable Flow Protection is customizable
Our existing DDoS mitigation systems have been designed to understand and protect popular, well-known protocols from DDoS attacks. For example, our Advanced TCP Protection system uses specific known characteristics about the TCP protocol to issue challenges and establish a client’s legitimacy. Similarly, our Advanced DNS Protection builds a per-customer profile of DNS queries to mitigate DNS attacks. Our generic DDoS mitigation platform also understands common patterns across a variety of other well known protocols, including NTP, RDP, SIP, and many others.
However, custom or proprietary UDP protocols have always been a challenge for Cloudflare’s DDoS mitigation systems because our systems do not have the relevant protocol knowledge to make intelligent decisions to pass or drop traffic.
Programmable Flow Protection addresses this gap. Now, customers can write their own eBPF program that defines what “good” and “bad” packets are and how to deal with them. Cloudflare then runs the program across our entire global network. The program can choose to either drop or challenge “bad” packets, preventing them from reaching the customer’s origin.
The problem of UDP-based attacks
UDP is a connectionless transport layer protocol. Unlike TCP, UDP has no handshake or stateful connections. It does not promise that packets will arrive in order or exactly once. UDP instead prioritizes speed and simplicity, and is therefore well-suited for online gaming, VoIP, video streaming, and any other use case where the application requires real-time communication between clients and servers.
Our DDoS mitigation systems have always been able to detect and mitigate attacks against well-known protocols built on top of UDP. For example, the standard DNS protocol is built on UDP, and each DNS packet has a well-known structure. If we see a DNS packet, we know how to interpret it. That makes it easier for us to detect and drop DNS-based attacks.
Unfortunately, if we don’t understand the protocol inside a UDP packet’s payload, our DDoS mitigation systems have limited options available at mitigation time. If an attacker sends a large flood of UDP traffic that does not match any known patterns or protocols, Cloudflare can either entirely block or apply a rate limit to the destination IP and port combination. This is a crude “last line of defense” that is only intended to keep the rest of the customer’s network online, and it can be painful in a couple ways.
First, a block or a generic rate limit does not distinguish good traffic from bad, which means these mitigations will likely cause legitimate clients to experience lag or connection loss — doing the attacker’s job for them! Second, a generic rate limit can be too strict or too lax depending on the customer. For example, a customer who expects to receive 1Gbps of legitimate traffic probably needs more aggressive rate limiting compared to a customer who expects to receive 25Gbps of legitimate traffic.
An illustration of UDP packet contents. A user can define a valid payload and reject traffic that doesn’t match the defined pattern.
The Programmable Flow Protection platform was built to address this problem by allowing our customers to dictate what “good” versus “bad” traffic actually looks like. Many of our customers use custom or proprietary UDP protocols that we do not understand — and now we don’t have to.
How Programmable Flow Protection works
In previous blog posts, we’ve described how “flowtrackd”, our stateful network layer DDoS mitigation system, protects Magic Transit users from complex TCP and DNS attacks. We’ve also described how we use Linux technologies like XDP and eBPF to efficiently mitigate common types of large scale DDoS attacks.
Programmable Flow Protection combines these technologies in a novel way. With Programmable Flow Protection, a customer can write their own eBPF program that decides whether to pass, drop, or challenge individual packets based on arbitrary logic. A customer can upload the program to Cloudflare, and Cloudflare will execute it on every packet destined to their network. Programs are executed in userspace, not kernel space, which allows Cloudflare the flexibility to support a variety of customers and use cases on the platform without compromising security. Programmable Flow Protection programs run after all of Cloudflare’s existing DDoS mitigations, so users still benefit from our standard security protections.
There are many similarities between an XDP eBPF program loaded into the Linux kernel and an eBPF program running on the Programmable Flow Protection platform. Both types of programs are compiled down to BPF bytecode. They are both run through a “verifier” to ensure memory safety and verify program termination. They are also executed in a fast, lightweight VM to provide isolation and stability.
However, eBPF programs loaded into the Linux kernel make use of many Linux-specific “helper functions” to integrate with the network stack, maintain state between program executions, and emit packets to network devices. Programmable Flow Protection offers the same functionality whenever a customer chooses, but with a different API tailored specifically to implement DDoS mitigations. For example, we’ve built helper functions to store state about clients between program executions, perform cryptographic validation, and emit challenge packets to clients. With these helper functions, a developer can use the power of the Cloudflare platform to protect their own network.
Combining customer knowledge with Cloudflare’s network
Let’s step through an example to illustrate how a customer’s protocol-specific knowledge can be combined with Cloudflare’s network to create powerful mitigations.
Say a customer hosts an online gaming server on UDP port 207. The game engine uses a proprietary application header that is specific to the game. Cloudflare has no knowledge of the structure or contents of the application header. The customer gets hit by DDoS attacks that overwhelm the game server and players report lag in gameplay. The attack traffic comes from highly randomized source IPs and ports, and the payload data appears to be random as well.
To mitigate the attack, the customer can use their knowledge of the application header and deploy a Programmable Flow Protection program to check a packet’s validity. In this example, the application header contains a token that is unique to the gaming protocol. The customer can therefore write a program to extract the last byte of the token. The program passes all packets with the correct value present and drops all other traffic:
#include <linux/ip.h>
#include <linux/udp.h>
#include <arpa/inet.h>
#include "cf_ebpf_defs.h"
#include "cf_ebpf_helper.h"
// Custom application header
struct apphdr {
uint8_t version;
uint16_t length; // Length of the variable-length token
uint8_t token[0]; // Variable-length token
} __attribute__((packed));
uint64_t
cf_ebpf_main(void *state)
{
struct cf_ebpf_generic_ctx *ctx = state;
struct cf_ebpf_parsed_headers headers;
struct cf_ebpf_packet_data *p;
// Parse the packet headers with provided helper function
if (parse_packet_data(ctx, &p, &headers) != 0) {
return CF_EBPF_DROP;
}
// Drop packets not destined to port 207
struct udphdr *udp_hdr = (struct udphdr *)headers.udp;
if (ntohs(udp_hdr->dest) != 207) {
return CF_EBPF_DROP;
}
// Get application header from UDP payload
struct apphdr *app = (struct apphdr *)(udp_hdr + 1);
if ((uint8_t *)(app + 1) > headers.data_end) {
return CF_EBPF_DROP;
}
// Perform memory checks to satisfy the verifier
// and access the token safely
if ((uint8_t *)(app->token + token_len) > headers.data_end) {
return CF_EBPF_DROP;
}
// Check the last byte of the token against expected value
uint8_t *last_byte = app->token + token_len - 1;
if (*last_byte != 0xCF) {
return CF_EBPF_DROP;
}
return CF_EBPF_PASS;
}
An eBPF program to filter packets according to a value in the application header.
This program leverages application-specific information to create a more targeted mitigation than Cloudflare is capable of crafting on its own. Customers can now combine their proprietary knowledge with the capacity of Cloudflare’s global network to absorb and mitigate massive attacks better than ever before.
Going beyond firewalls: stateful tracking and challenges
Many pattern checks, like the one performed in the example above, can be accomplished with traditional firewalls. However, programs provide useful primitives that are not available in firewalls, including variables, conditional execution, loops, and procedure calls. But what really sets Programmable Flow Protection apart from other solutions is its ability to statefully track flows and challenge clients to prove they are real. A common type of attack that showcases these abilities is a replay attack.
In a replay attack, an attacker repeatedly sends packets that were valid at some point, and therefore conform to expected patterns of the traffic, but are no longer valid in the application’s current context. For example, the attacker could record some of their valid gameplay traffic and use a script to duplicate and transmit the same traffic at a very high rate.
With Programmable Flow Protection, a user can deploy a program that challenges suspicious clients and drops scripted traffic. We can extend our original example as follows:
#include <linux/ip.h>
#include <linux/udp.h>
#include <arpa/inet.h>
#include "cf_ebpf_defs.h"
#include "cf_ebpf_helper.h"
uint64_t
cf_ebpf_main(void *state)
{
// ...
// Get the status of this source IP (statefully tracked)
uint8_t status;
if (cf_ebpf_get_source_ip_status(&status) != 0) {
return CF_EBPF_DROP;
}
switch (status) {
case NONE:
// Issue a custom challenge to this source IP
issue_challenge();
cf_ebpf_set_source_ip_status(CHALLENGED);
return CF_EBPF_DROP;
case CHALLENGED:
// Check if this packet passes the challenge
// with custom logic
if (verify_challenge()) {
cf_ebpf_set_source_ip_status(VERIFIED);
return CF_EBPF_PASS;
} else {
cf_ebpf_set_source_ip_status(BLOCKED);
return CF_EBPF_DROP;
}
case VERIFIED:
// This source IP has passed the challenge
return CF_EBPF_PASS;
case BLOCKED:
// This source IP has been blocked
return CF_EBPF_DROP;
default:
return CF_EBPF_PASS;
}
return CF_EBPF_PASS;
}
An eBPF program to challenge UDP connections and statefully manage connections. This example has been simplified for illustration purposes.
The program statefully tracks the source IP addresses it has seen and emits a packet with a cryptographic challenge back to unknown clients. A legitimate client running a valid gaming client is able to correctly solve the challenge and respond with proof, but the attacker’s script is not. Traffic from the attacker is marked as “blocked” and subsequent packets are dropped.
With these new abilities, customers can statefully track flows and make sure only real, verified clients can send traffic to their origin servers. Although we have focused the example on gaming, the potential use cases for this technology extend to any UDP-based protocol.
Get started today
We’re excited to offer the Programmable Flow Protection feature to Magic Transit Enterprise customers. Talk to your account manager to learn more about how you can enable Programmable Flow Protection to help keep your infrastructure safe.
We’re still in active development of the platform, and we’re excited to see what our users build next. If you are not yet a Cloudflare customer, let us know if you’d like to protect your network with Cloudflare. Join our Programmable Flow Protection Discord channel to chat with us about this feature.
Initial Access Brokers (IABs) are a key component of the cybercrime ecosystem, offering hassle-free building blocks for ransomware, data theft, and extortion. Rapid7’s analysis of H2 2025 activity across five major forums grants fresh insight into a power balance shift toward initial access sales from newer marketplaces, such as RAMP and DarkForums. Higher asking prices and more focus on high-value sectors and large organizations, such as Government, Retail, and IT, reveal a mature and profit-focused IAB market.
This blog highlights key access trends and pricing, pinpoints the most targeted industries and regions, and gives actionable recommendations for identifying and isolating potential breaches via popular IAB offerings.
Key findings
Our detailed analysis of six months of data from Exploit, XSS, BreachForums, DarkForums, and RAMP reveals the following key findings:
Access prices and target organization size increased dramatically: The average alleged victim revenue and offering base price have increased significantly compared to the previous year, indicating that IABs are targeting larger, higher-value enterprises and charging premium prices for quality access.
Primary access vectors haven’t changed: RDP, VPN, and RDWeb remain the top access vectors being offered for sale, which means that remote access infrastructure is still the primary attack surface for initial access sales.
High-privilege access is increasingly prioritized: Most common privilege levels being offered by IABs are Domain User (42.9%), Domain Admin (32.1%), and Local Admin (12.5%), with a visible decline in lower-privilege offerings, such as Local User privileges. It seems the market is shifting from volume to high-impact access that enables faster and more efficient malicious operations, such as ransomware and extortion attacks.
Certain underground marketplaces have become favored over others: DarkForums (221 threads) and RAMP (208 threads) were the most active forums for initial access sales in H2 2025, accounting together for 81% of the observed threads. At the same time, older, historically dominant forums such as XSS and Exploit saw significant declines in IAB activity.
IABs target specific industries: IAB activity is primarily concentrated on sectors offering the highest potential for financial gain or intelligence acquisition: Government, Retail, and Information Technology (IT).
Focus on government access: The Government sector is the most frequently targeted industry vertical, at 14.2% (Retail and Information Technology follow with 13.1% and 10.8%, respectively). ‘Admin panel’ access is the most commonly observed type offered for this sector, with DarkForums serving as the principal platform for its sale.
IAB and cybercrime forum landscape in 2026
Just as in 2025, cybercriminal forums continue to serve as the primary marketplaces for the promotion and sale of pirated network access. Platforms such as Exploit, BreachForums, XSS, DarkForums, and RAMP have remained central pillars of the cybercriminal underground through 2025 and into 2026, despite sustained law-enforcement pressure, infrastructure seizures, and repeated cycles of disruption and rebirth. In response to their continued relevance, Rapid7 threat intelligence researchers expanded their monitoring to include all five forums, tracking activity from January through December 2025. The primary objective was to benchmark Initial Access Broker (IAB) activity and adjacent services, including an in-depth analysis of tactics, techniques, and procedures (TTPs), initial access vectors, credential and session pricing, victim geographies, and evolving monetization strategies.
Why cybercrime forums matter in 2026
We selected these five forums for their continued relevance, the concentration of experienced actors, and their distinct functional roles within the cybercriminal ecosystem. Collectively, they represent the full lifecycle of modern cybercrime from initial compromise and access brokerage to data monetization, extortion, and ransomware enablement. Despite repeated takedowns and administrator arrests, the past two years have demonstrated that forum resilience, brand persistence, and rapid reconstitution remain defining characteristics of the underground economy. Monitoring activity across these platforms, particularly from reputable, high-volume IABs and repeat sellers, provides critical insight into shifting attacker priorities, preferred access vectors, and pricing dynamics.
Exploit, XSS, DarkForums, BreachForums, and RAMP: Combined data analysis
Last year, in The Rapid7 2025 Access Brokers Report, we analyzed the data of three main cybercrime forums, Exploit, XSS, and BreachForums. This year, we have expanded this list to include two additional (and very popular) forums, DarkForums and RAMP.
In fact, the newly analyzed forums were the most active in the past six months in terms of initial access and privileges offered for sale. DarkForums with 221 sale threads, followed by RAMP with 208, then Exploit with 53, Breached with 30, and XSS with 18. This might indicate a certain change in shifts in terms of popularity between the newer forums and the older ones.
⠀
The average alleged revenue of the organizations whose access is being sold in these forums was $3.242 billion, and the average base price for the offerings was $113,275. However, it is important to keep in mind that victim revenue numbers are broker-provided based on their own online research, and as such, they may not necessarily be accurate.
Both numbers manifest a substantial rise compared to last year (average revenue – $2.232 billion, average base price – $2,726), with the average base price of the offerings increasing by approximately 4055% compared to last year. Notably, these numbers are especially affected by DarkForums, with tremendously high values in both counts. They show that IABs have become more resourceful, finding weak spots in larger organizations, and also much greedier in terms of the price of their offerings.
Initial access vectors and privilege types
Analysis of the access types offered for sale revealed 29 distinct types of access. The most frequently advertised access types were RDP (21.2%, 91 offers), VPN (12.8%, 55 offers), and RDWeb (11.2%, 48 offers).
⠀
The most common privilege types were Domain User with 144 instances (42.9%), followed by Domain Admin with 108 (32.1%) and Local Admin with 42 (12.5%).
In many observed cases, VPN and RDWeb access are sold with the Domain User privilege, while RDP is sold with either Domain User or Domain Admin.
If we compare the numbers of the top 5 access types offered for sale to last year’s data, we can see that RDP access has become more prevalent than VPN, although both access types remain the leading two categories. In addition, it seems that RDweb is much more popular among the sellers.
⠀
As for the privilege types, we can see that the clear dominance of the Domain User privilege offered for sale has declined, though it remains the most common privilege type sold by IABs. In addition, the newer dataset lacks any mentions of the Local User privilege. The data indicates a decline in the previously dominant Domain User access offering. Despite this decrease, Domain User access remains the most frequently sold privilege level among Initial Access Brokers (IABs). Notably, the updated dataset contains no instances of Local User privilege sales.
This shift likely reflects evolving IAB monetization strategies and changing buyer demand. While Domain User access remains valuable for its broad network reach, its reduced dominance may signal heightened market competition, stronger defensive controls, or strategic diversification into alternative access types. The complete absence of Local User privileges suggests diminishing operational relevance and limited resale value, as threat actors increasingly prioritize access that facilitates lateral movement, privilege escalation, and rapid operational impact.
⠀
Additionally, in RAMP, we observed an exploit targeting a vulnerability in the Oracle E-Business Suite (CVE-2025-61882) being offered for sale.
⠀
⠀
CVE-2025-61882 is a critical vulnerability in Oracle E-Business Suite (versions 12.2.3–12.2.14). This flaw allows unauthenticated attackers to execute arbitrary code via HTTP, resulting in complete system compromise.
The vulnerability has been exploited as a zero-day by the Cl0p criminal organization to exfiltrate financial and human resources data for subsequent extortion attempts, as documented in the Rapid7 blog.
Demographic information
A comprehensive analysis of the underground market for illicit network access points reveals that most available listings concern networks in the United States, totaling 155 unique listings.
This substantial figure constitutes a significant 30.9% of the total global data on illicit network access available for purchase. The dominance of the U.S. in this domain suggests a confluence of factors, including the sheer size and connectivity of its network infrastructure, the high value associated with compromised U.S. enterprise and government networks, and the relative wealth of potential buyers seeking access to these environments. The visibility of U.S.-based access points on darknet marketplaces underscores a considerable vulnerability and highlights the attractiveness of U.S. targets to cybercriminal syndicates seeking initial access for subsequent malicious activities such as data exfiltration, ransomware deployment, or espionage.
⠀
The top 10 targeted countries list is very similar to the one from last year, which also placed the United States at the top, with a large margin from the following countries (the United Kingdom, India, and Brazil).
In addition, an analysis of the offerings indicates a pronounced concentration on particular sectors. The government sector is the most frequently targeted category, accounting for 14.2% of the observed offerings, likely due to the substantial value of sensitive data held. The retail industry closely follows at 13.1%, attracting IABs due to the presence of payment card information (PCI) and personally identifiable information (PII). The Information Technology (IT) sector is the third most frequent target, at 10.8%, valued for its potential as a supply chain vector to compromise a wide range of clients.
This strategic focus on Government, Retail, and IT underscores the IAB community’s prioritization of targets that promise the greatest financial return, intelligence acquisition, or potential for systemic disruption.
⠀
Unlike the top 10 countries list, the top 10 targeted sectors list is very different from last year’s, which was dominated by the Financial Services and IT sectors, with few network access offerings from organizations in the Government and Retail sectors. This is likely due to the inclusion of DarkForums in this year’s analysis, which usually contain many sellers offering access to government networks.
Individual analysis of Exploit, XSS, DarkForums, BreachForums, and RAMP
The following is a detailed, individual analysis of the five forums, covering their history, operations, and key trends from the latter half of 2025. This includes an examination of common illicit listings, typical base price ranges, and frequently targeted regions.
Exploit
Exploit has continued to function as one of the most technically rigorous Russian-language cybercrime forums. Historically focused on exploits, malware development, and high-end IAB offerings, Exploit has maintained a comparatively stable operational posture over the past two years. While selectively restricting access and tightening vetting following multiple international law enforcement takedowns of peer forums, Exploit has benefited from its long-standing reputation system and senior moderator structure. Between 2024 and 2026, it increasingly served as a venue for enterprise network access, VPN, and EDR-bypassed footholds, and post-exploitation tooling, rather than commodity credential sales.
Unlike last year’s offerings that focused on RDP access, the H2 2025 data shows that Exploit’s IABs are more focused on RDweb. The shift from RDP access to RDWeb access in H2 2025 is likely due to improved defenses against direct exposure to the RDP protocol. Faced with reduced capabilities to secure or remove RDP access points exposed to the internet, attackers are adapting by targeting RDWeb portals, which are often vulnerable and sometimes less well-protected. RDWeb offers reliable access to enterprise environments, making it an attractive alternative for initial access brokers. The United States remains the most targeted country, accounting for approximately 40% of cases in which the organization’s location is specified.
⠀
Interestingly, while the average alleged revenue of the targeted organizations dropped from approximately $314 million to only $58 million, the base price of the offerings has gone 6 times higher than last year.
BreachForums (AKA Breached)
BreachForums has experienced the most visible volatility. Following multiple seizures and arrests in 2023–2024, the forum underwent several reboots under new administrators, each attempting to inherit the brand equity of the original platform. By 2025, BreachForums had largely reestablished itself as a data-leak-centric marketplace, with less emphasis on technical exploitation and a greater focus on breached databases, stealer logs, and extortion-related disclosure tactics. Trust erosion from repeated compromises, however, pushed higher-tier IABs and ransomware affiliates toward more closed or Russian-language platforms, reducing BreachForums’ role in elite access brokerage by 2026.
The precarious status of the Breached forum, as it is now called, is reflected by the number of IAB threads found this year (around 52% less than in 2024). This is likely due to the disappearance of very dominant players in the IAB community, such as IntelBroker (real name: Kai West), who was apprehended by law enforcement and charged in the U.S. with his crimes. Accordingly, the variety of access types was much more limited, dominated by remote code execution (RCE) and Shell access. However, unlike last year, which included only Domain Admin, this year we noticed additional privilege types offered: Domain User and Local Admin.
⠀
Just like in the other examined forums, the United States is the most targeted country (17.4%) in Breached, but by a substantially smaller percentage compared to last year.
As for the pricing, we see an opposite trend compared to Exploit – while the average alleged revenue of the targeted organizations has slightly increased in 2025, the base price of the offerings in Breached was cut in half.
XSS (formerly DaMaGeLaB)
XSS has retained its status as a premier Russian-language forum for initial access sales, ransomware partnerships, and credentialed access to corporate environments. Following intermittent downtime and administrator turnover in 2024, XSS emerged in 2025 with reinforced operational security practices and stricter membership controls. Over the past two years, XSS has increasingly served as a coordination hub for post-access collaboration, including handoffs between IABs, ransomware operators, and data theft specialists. Pricing trends observed on XSS indicate a shift toward higher-value, lower-volume access, particularly in Western enterprise environments.
Compared to last year’s assessment, this forum showed the most significant shift. It went from being the most dominant forum for IAB threads to the lowest among the five forums we examined. In H2 of 2025, we only located around 20 threads (compared to almost 200 in 2024). This small number of threads makes XSS stats so statistically negligible as to be unanalyzable. This decline is likely due to many IABs shifting to newer, “shinier” cybercrime forums, such as DarkForums and RAMP.
DarkForums
DarkForums rose to prominence as an English-language alternative following repeated disruptions to BreachForums. Between 2024 and 2026, DarkForums positioned itself as a hybrid marketplace, blending breach data sales, low- to mid-tier IAB offerings, and fraud services. While it lacks the technical depth of Exploit or XSS, DarkForums has become a key on-ramp for emerging actors, especially those operating stealer malware or reselling access obtained using phishing and MFA fatigue attacks. Its relatively open registration model has resulted in higher signal-to-noise ratios, but it remains valuable for tracking early-stage monetization trends.
DarkForums is one of the two new forums that were included in this year’s analysis, and the most dominant in terms of IAB threads. It had a somewhat unique access type, leading the board, Fortinet, followed by SSH, RDP, and Root access. The Fortinet access points were predominantly sold by a very active DarkForums user, BigBro. Interestingly, we also found another user, Big-Bro, active on RAMP, who is likely the same user, although selling different types of access points.
⠀
Similar to the other forums, the most targeted country on DarkForums was the United States (25.8%); however, unlike the others, many of the network access offerings were from organizations in the Government and Retail sectors.
As for the pricing, DarkForums had the highest average of alleged targeted organization revenue and offering base price by a very large margin compared to the rest.
RAMP (Russian Anonymous Marketplace)
RAMP has continued to operate as a high-trust, invite-only ecosystem following its resurgence after earlier disruptions by law enforcement. By 2025–2026, RAMP solidified its role as a convergence point for ransomware affiliates, IABs, and cash-out services, rather than a general discussion forum. RAMP listings observed during this period emphasized full domain access, long-term persistence, and revenue-sharing models, reflecting a mature, partnership-driven cybercrime economy. Its closed nature limits visibility, but the activity that does surface suggests alignment with the most operationally sophisticated threat actors.
RAMP was another newly examined forum and the second-highest in terms of IAB threads. The most dominant type of access being sold by RAMP’s IABs was RDP, followed by VPN and Citrix by a large margin. The most common privilege types for sale were Domain User (56.4%) and Domain Admin (33.9%). Notably, most of the threads that were analyzed for this forum (78.8%) belonged to only two users, Big-Bro (mentioned earlier) and an allegedly Albanian user, lacrim.
⠀
In RAMP, the United States continued to lead the list of targeted countries (36.5%). The average alleged targeted organization revenue was approximately $440 million, and the average base price was almost $6400.
Threat actors active across multiple forums
This research revealed that a subset of threat actors maintains an active presence across multiple forums, with the greatest overlap observed between Breached and DarkForums. This overlap is understandable, since DarkForums was intentionally designed as a “spiritual successor” and a like-for-like replacement for Breached following the latter’s frequent law-enforcement disruptions. Consequently, the two platforms share a nearly identical visual and structural layout, both utilizing the MyBB forum software to create a familiar environment for users.
Recommendations
For organizations, security strategies cannot remain static. Policy frameworks and compliance controls alone are insufficient. Continuous monitoring of real-world access behavior is essential. Anomalous logins, unexpected privilege escalations, access outside normal business hours, or activity from unfamiliar locations should be treated as early indicators of compromise.
Proactive threat intelligence further enables defenders to anticipate which access methods are most likely to be targeted. An effective defense requires making stolen access difficult to exploit. Enforcing least-privilege principles, tightly controlling administrative rights, hardening remote access services with MFA, and accelerating intrusion detection all materially limit an attacker’s ability to escalate and persist. While breaches may still occur, rapid identification and containment can prevent them from becoming full-scale incidents. Organizations that evolve their defenses in step with access brokers can erode the attackers’ advantage, increasing the cost and reducing the effectiveness of cybercrime.
Conclusion
The comparison between 2024 and 2025 highlights how initial access brokers continue to adapt to increasingly robust defensive measures. As organizations strengthen their security postures, attackers refine the types of access they steal and monetize to maintain effectiveness. In 2025, high-privilege credentials, such as domain or local administrator accounts, will command greater value because they enable rapid lateral movement and immediate operational impact, leaving defenders little time to detect and respond. Lower-privilege access is steadily losing value, signaling a clear shift from volume-driven access sales to a focus on quality and impact. Access vectors are evolving in parallel. As VPN infrastructure becomes more hardened and closely monitored, attackers are pivoting to RDP, RDWeb, and SSH services that are operationally critical, widely exposed, and often subject to less rigorous scrutiny. This shift reflects a pragmatic path-of-least-resistance strategy rather than any decline in attacker sophistication.
Some innovations change the trajectory of a company, others change the trajectory of an entire industry. Today, I’m absolutely chuffed that one of our original Storage Pods, ul010 to be exact, is heading to the Computer History Museum. Not as a curiosity, but as a piece of living history that changed not just how Backblaze stored data, but how the entire cloud industry thought about server design.
Some history
On September 1, 2009, we published a blog post called Petabytes on a Budget: How to Build Cheap Cloud Storage. The post went into detail about how we, as a bootstrapped company, could provide an unlimited backup service at a reasonable rate without compromising on performance or burning through cash. Essentially, open-sourcing our server design and making it available to the masses was a bit of a gamble given that a better-funded company could copy our design, deploy it at scale, and put us out of business.
Our “secret sauce” has always been our software stack and design decisions, so we felt strongly that while they could mimic some of our economics, being able to build a service as performant as ours would be out of reach.
At the beginning
Founder Brian Wilson had this to say about some of Backblaze’s history:
The founders of Backblaze were primarily software engineers, and after wiring up some prototypes on Tim’s office desk, we worked with the company Protocase all by email and telephone to have the first actual sheet metal Pod enclosure manufactured. The “custom” part of the Pods is the sheet metal enclosure, for cost reasons all of the components inside the enclosure are standard drives, motherboard, power supplies that you can purchase for consumers.
An early Storage Pod prototype (never in production)
So the sheet metal Pod has screw holes where the computer motherboard sits down and gets attached to the metal enclosure. They have to be precisely in the correct location or the screws wouldn’t line up. I (Brian) thought there was no way we (a bunch of software engineers) could get that all perfectly lined up on the very first prototype. But when we got the very first sheet metal enclosure shipped to our corporate office, every screw hole to mount the drives, backplanes, power supply, and motherboard were in perfect with alignment. However…
We forgot that computers have power buttons! All the complex stuff was correct, but there was no location on the case to have a power button. So Tim jammed a screwdriver in some air vents on the first prototype sheet metal Pod and opened up a hole wide enough for the power button. Below is Tim opening a hole for the Pod’s power button:
And with that one modification, the very first sheet metal Pod was deployed in the datacenter and started storing customer data for the next several years, performing flawlessly.
While we’d spend the next decade moving away from the title word “cheap”, the blog post and how we thought about our storage problem struck a chord with enthusiasts, businesses, and the storage industry at large. Our Storage Pod wasn’t just a chassis full of drives, it was proof that infrastructure innovation doesn’t have to come from billion-dollar labs. Sometimes it comes from engineers willing to be cleverly unconventional.
Innovation across the industry followed. Partially inspired by our architecture and philosophies around solving storage density and interconnectivity issues, the Open Compute Project (2011), and Netflix’s Open Connect (2012) came to life and continue their innovative charters to this day. Protocase, which bent the sheet metal for our original Storage Pod, spun up an entire company, 45 Drives, to meet the “build this for us” demand they were experiencing. As we moved from version 1 to version 6 of our Storage Pods and beyond, we looked on fondly as capital-efficient, high-density 4u servers became commonplace, and commoditized. Today, you can customize your own dense servers from a variety of providers, from 45Drives to Sanmina to Dell.
Why donate the Pod?
One of my favorite places in the Bay Area is the Computer History Museum in Mountain View. Walking through the exhibits, and seeing an old Babbage machine, telecom equipment, and the evolution of electronic gaming was inspiring to me when I first moved to the bay 15 years ago. At Backblaze, we’ve also kept a museum of sorts, originally created by Andy Klein. Our museum consisted of Storage Pods from version 1 all the way to version 6, along with the original RAID array we tested our systems on, and it has been displayed at our office for years.
Backblaze went fully remote in mid-January, and as our museum became destined for storage, I tried to think of other interesting things to do with it, and the Computer History Museum sprang to mind. I reached out and they graciously agreed to consider the original Storage Pod. (I appreciated the kind way in which they declined taking on our entire museum—they have space constraints as well!)
The handoff was a bit of an adventure
I went to our office before it closed up for good to take some pictures and bring the Storage Pod to their ingestion site.
I drove to the Shustek Research Archives, which serves as an archive, preservation, and ingestion site for all the historic items bound for the Computer History Museum and its archives. It’s also where the curators do a final yay/nay on whether the items truly are a part of computer history. It was a little bittersweet to drop off the Storage Pod, but knowing it would be going to a nice home felt great.
When Backblaze began in 2007, their goal was to provide unlimited cloud backup storage for $5 a month. Their first product relied on hardware—Storage Pod 1.0—which represented a watershed, defying the era’s proprietary technical norms by using off-the-shelf components and open-source software. By famously sharing their design blueprints with the world, Backblaze also ignited a revolution in ‘open hardware,’ proving that high-density enterprise storage could be built for a fraction of the cost of traditional approaches. We are honored to preserve this original unit.
— Dag Spicer, Senior Curator, Computer History Museum
After the handoff, all I could do was wait and see whether the curators felt that our Storage Pod was worthy to be a part of their collection. Less than three weeks later, I got the news that the Pod was accepted and will join the historical relics of the CHM.
A post-Pod world
While our Storage Pod helped democratize storage at a time where the industry was in need, today B2 Cloud Storage with B2 Overdrive and B2 Neo help companies, industries, and builders democratize their tech stacks. And that kind of flexibility will help accelerate them into and past the AI-era.
Our donated Storage Pod once held backups—data comprising the many aspects of our customer’s lives, stories, and work. And, it’s also a symbol of our stories—the late nights, bold bets, and belief in the innovation that sparked the Backblaze founders in the first place. My sincere hope is that through its retirement at the Computer History Museum, it will inspire the next generation of innovators, and if that’s you…hey, nice to meet you!
Charles Bennett and Gilles Brassard have won the 2026 Turing Award for inventing quantum cryptography.
I am incredibly pleased to see them get this recognition. I have always thought the technology to be fantastic, even though I think it’s largely unnecessary. I wrote up my thoughts back in 2008, in an <a href+https://www.schneier.com/essays/archives/2008/10/quantum_cryptography.html”>essay titled “Quantum Cryptography: As Awesome As It Is Pointless.”
Back then, I wrote:
While I like the science of quantum cryptography—my undergraduate degree was in physics—I don’t see any commercial value in it. I don’t believe it solves any security problem that needs solving. I don’t believe that it’s worth paying for, and I can’t imagine anyone but a few technophiles buying and deploying it. Systems that use it don’t magically become unbreakable, because the quantum part doesn’t address the weak points of the system.
Security is a chain; it’s as strong as the weakest link. Mathematical cryptography, as bad as it sometimes is, is the strongest link in most security chains. Our symmetric and public-key algorithms are pretty good, even though they’re not based on much rigorous mathematical theory. The real problems are elsewhere: computer security, network security, user interface and so on.
Cryptography is the one area of security that we can get right. We already have good encryption algorithms, good authentication algorithms and good key-agreement protocols. Maybe quantum cryptography can make that link stronger, but why would anyone bother? There are far more serious security problems to worry about, and it makes much more sense to spend effort securing those.
As I’ve often said, it’s like defending yourself against an approaching attacker by putting a huge stake in the ground. It’s useless to argue about whether the stake should be 50 feet tall or 100 feet tall, because either way, the attacker is going to go around it. Even quantum cryptography doesn’t “solve” all of cryptography: The keys are exchanged with photons, but a conventional mathematical algorithm takes over for the actual encryption.
What about quantum computation? I’m not worried; the math is ahead of the physics. Reports of progress in that area are overblown. And if there’s a security crisis because of a quantum computation breakthrough, it’s because our systems aren’t crypto-agile.
Америка и Израел в открита война срещу Иран. Развитие, което доскоро беше немислимо или най-малкото разглеждано като изключително нежелана ескалация. До редакционното приключване на тази статия военнополитическите цели на атакуващите страни не са постигнати. Режимът в Техеран е жив, иранската армия не само функционира, а успешно нанася удари срещу западни бази в Близкия изток и срещу енергийни цели в държавите съюзници на американците в региона.
Водейки успешна (засега) асиметрична война срещу многократно по-силни противници, Иран успява да пренесе фронта върху световната икономика и чрез ефективното въвличане на трети страни в конфликта да предотврати бързата победа, за която мечтаеха Тръмп и Нетаняху.
Като държава в непосредствена геополитическа близост до конфликта България е твърде уязвима на проблемите, които войната вече породи, и които, изглежда, ще се задълбочават. Те са в три основни направления. Първо, военната заплаха, тоест риск от разширяване на конфликта до Балканите. Второ, негативните икономически ефекти – галопиращи цени на горивата и задаваща се световна рецесия. На трето място е проблемът с миграционния натиск.
Колко „далече“ е войната всъщност?
Ескалацията на военните действия между САЩ, Израел, Иран и арабските държави от региона постепенно превръща югоизточния фланг на НАТО, включително Балканите, в зона с повишен риск за сигурността. Близостта на България до зоната на военните действия и ролята на страната като логистичен коридор за операции на НАТО я поставят в потенциално уязвима позиция.
Първите сигнали за нарастващ риск бяха иранските атаки срещу югоизточната ни съседка Турция – членка на НАТО, и срещу британска военна база в Кипър – страна членка на ЕС. След поредица от прехванати балистични ракети през март турските власти алармираха за покачване на напрежението по южните си граници и обявиха, че НАТО ще засили отбранителното си присъствие в страната.
В центъра на мерките е авиобазата „Инджирлик“, където ще бъде разположена допълнителна система за противоракетна отбрана „Пейтриът“, предоставена от базата в Рамщайн, Германия. Според Анкара това е трети случай на ирански ракетни атаки за кратък период. Техеран обаче категорично отрича участие и твърди, че ударите са външна провокация от страна на Израел, което допълнително усложнява геополитическата картина. На този фон Турция подчертава, че си запазва правото да реагира при пряка заплаха, но засега се въздържа от активиране на член 5 от договора на НАТО.
Минаващият през Балканите въздушен коридор между американските бази в Европа и целите в Близкия изток, както и морският коридор между Черно и Средиземно море стават основни за отбранителната архитектура на НАТО в условията на два активни военни конфликта до границите му. В анализи на европейски изследователски центрове се отбелязва, че инфраструктурата на Алианса в Югоизточна Европа – от бази в Гърция до съоръжения в Румъния – вече е поставена в състояние на повишена готовност поради заплахите от ответни удари срещу западни военни обекти.
Ескалацията около Иран беше като студен душ за българската отбрана и хвърли още светлина върху сериозните слабости във въоръжените ни сили, които дълго са били неглижирани от държавата. България изглежда неподготвена за съвременните измерения на войната – дронове, ракетни заплахи и високи технологии, а армията ни продължава да разчита на морално остаряла техника и на непълноценни системи за противовъздушна защита.
Забавената модернизация и липсата на ясна стратегическа визия допълнително задълбочават тези проблеми. Апелите за съюзническа помощ звучат по-скоро като признание за дефицити, отколкото като проява на координирана сигурност. Без спешна модернизация на въоръжените сили България ще става все по-зависима от близките си съюзници и на практика ще е лишена от възможността да води самостоятелна отбранителна политика на базата на националния си интерес.
Израелско-американската война срещу Иран променя цените на петрола, както и икономическите очаквания по целия свят. Според анализатори възможността петролът да достигне до космическите 200 долара за барел вече не изглежда невероятна при продължително блокиране на Ормузкия проток, през който минава до една пета от световните петролни потоци. За сравнение, сегашният рекорд при цената на суровия петрол е 146 долара за барел, достигнат в пика на финансовата криза от 2008 г. Цените на природния газ също скочиха рязко след атаките срещу ключови енергийни обекти в Персийския залив, включително срещу големи газови съоръжения в Катар. Това доведе до увеличение на фючърсите в Европа с около 30–35%, а доставките на втечнен природен газ ще бъдат силно затруднени за дълъг период.
Повишаването на цените на петрола и газа не е временен ефект: повредената инфраструктура в Близкия изток може да остане извън строя с години, а продължителният конфликт засилва риска от дългосрочен енергиен и икономически шок. Комбинирането на скоковете при газа и петрола създава силен инфлационен натиск върху цената на електрическата енергия, върху производството и цялостната икономика на Европа. Нарастващите енергийни разходи допринасят за силния инфлационен натиск, който вече се усеща в потребителските цени, а веригите на доставки в глобалната икономика са под напрежение без прецедент в XXI век.
По‑високите транспортни разходи и нестабилните суровинни пазари повишават цените на торове, стомана и други основни материали в земеделието и производството, което ще прави икономическото възстановяване по‑трудно дори ако се сбъднат най-оптимистичните сценарии и войната приключи скоро. Българската икономика остава силно уязвима на тези глобални шокове, особено на развиващата се в момента световна инфлация и рязкото поскъпване на горивата. Високата зависимост от внос на енергия и нефтопродукти означава, че ценовите пикове на международните пазари бързо се пренасят върху домакинствата и бизнеса в България.
Данните на НСИ показват, че инфлацията у нас за 2025 г. е 5%. Външни конфликти и геополитическа нестабилност могат допълнително да ускорят натиска върху цените. Вторичните ефекти върху услуги, транспорт и хранителни продукти ще затруднят бюджета на домакинствата и растежа на икономиката.
Нова миграционна криза?
Според Върховния комисариат на ООН за бежанците около 3,2 млн. души от Иран вече са се разселили в страната от началото на нападенията на Израел и САЩ. Въпреки че засега няма вълна от бежанци, съседите на Иран са в нервно очакване на миграционен натиск заради очакванията войната да продължи.
Европейският съюз започва да гледа на конфликта не само като на геополитически риск, но и като на потенциален тест за новите си миграционни правила. Опасенията са, че при по-сериозна ескалация системата за убежище може бързо да се окаже под натиск, особено ако се повторят сценарии, подобни на сирийската криза. Въпреки че към момента броят на иранските молби за убежище в ЕС остава сравнително нисък, анализаторите подчертават, че това може да се промени рязко.
Причината е в мащаба на Иран. При население от около 90 млн. души дори частична дестабилизация би могла да доведе до огромни миграционни потоци. Картината се усложнява допълнително от вътрешните проблеми на страната – икономическа криза, политическо напрежение и дългосрочни фактори, като климатични промени и недостиг на вода, които вече водят до вътрешна миграция. Хипотетично разселване на около 10% от населението извън Иран би се превърнало в една от най-големите бежански вълни в съвременната история. Засега подобен сценарий до голяма степен зависи от ролята на Турция като транзитен коридор към Европа.
България има болезнени спомени от последните две бежански вълни, предизвикани от войните в Сирия и Украйна. И в двата случая популистки политически сили съзнателно засилваха общественото напрежение, превръщайки темата за миграцията в инструмент за набиране на политически рейтинг. Слабостите в държавното управление на кризите и радикализацията в обществото проличаха особено ясно на няколко пъти, включително около бунта в бежанския център в Харманли през 2016 г. и при нападението срещу украински граждани във Варна през 2025 г.
Опасенията са, че нов миграционен натиск вследствие на войната в Иран би могъл да претовари и без това крехката система за прием на бежанци у нас. Българският и европейският опит показват, че подобни кризи бързо се превръщат в политическо оръжие, използвано от радикални елементи. В условията на нарастващо напрежение е вероятно отново да се активизират онези политически актьори, които вече имат доказана склонност да експлоатират страха в обществото, да радикализират политическия език и да използват насилието като средство за политическо влияние.
Догонване на реалността
Сериозната неподготвеност на българската политика спрямо очертаните рискове личи най-ясно от отсъствието на темата за войната в Иран в предизборната кампания за предстоящите парламентарни избори. Липсва не само стратегическо мислене за ефектите от конфликта, но дори и базова позиция за ролята на България в бързо променящия се световен ред, белязан от ескалиращи конфликти и нарастваща несигурност.
За да има шанс страната да се справи с тези кризи, ще бъде необходимо ясно формулиране на национални приоритети, укрепване на институционалния капацитет и по-активно участие в рамките на съюзите, към които България принадлежи. Въпреки настоящата липса на визия натискът на събитията може да се окаже катализатор за по-зрял политически дебат и по-дългосрочно мислене. Такъв процес може би започва с плахи стъпки, след като служебният премиера Гюров открито се противопостави на включването на България в „Борда за мир“ на Доналд Тръмп и беше част от правителствената делегация, посетила Киев в края на март.
The collective thoughts of the interwebz
Manage Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.