Normal view

Microsoft shuts down illegal code-signing operation used by ransomware crims to mask their malware

19 May 2026 at 23:56
Microsoft seized websites and took down hundreds of virtual machines running a cybercrime service that allegedly sold code-signing certificates to ransomware gangs, thus making their malware look like legitimate software – and allowing criminals to infect thousands of machines in the US, including at least 12 owned and operated by the Windows giant. The malware signing-as-a-service operation called Fox Tempest has been around since May 2025, and abuses Microsoft’s Artifact Signing code-signing service. This service allows developers to digitally sign their software applications, signaling to the Windows operating system and end-user that the software is authentic, and hasn’t been tampered with. Since May 2025, the Fox Tempest crew – referred to as John Doe 1 and 2 in court documents unsealed on Tuesday – used fake identities and impersonated real organizations, allowing them to create more than 580 fraudulent Microsoft accounts. They then used these accounts to abuse Microsoft’s Artifact Signing service and obtain real code-signing credentials, then sold the code-signing certificates to other criminals for thousands of dollars. According to Microsoft, Fox Tempest’s customers included a ransomware group Redmond tracks as Vanilla Tempest (aka Vice Spider, Vice Society, Rhysida), which allegedly used the certificates to digitally sign malware and make it appear legitimate to Windows and users. This also allowed the ransomware slingers “to more easily deploy the malware onto the computers of unsuspecting victims without their consent,” according to the court documents [PDF]. Malware included Windows backdoor Oyster, infostealers Lumma and Vidar, and Rhysida ransomware. Vanilla Tempest “unlawfully accessed victims’ computers and devices, exfiltrated and stole the personal and confidential information of victims, deployed ransomware designed to encrypt victims’ files and systems, and extorted victims by demanding payment in exchange for restoring access to, or suppressing, their data,” the civil complaint continues, adding that the criminal activity remains ongoing. In a subsequent blog post, Microsoft Digital Crimes Unit attorney Steven Masada said the tech company's investigation “further linked Fox Tempest to various additional ransomware affiliates and families, including INC, Qilin, Akira, and others.” Between February and March, the Digital Crimes Unit (DCU), working with “a cooperating source,” anonymously bought and tested the code signing service from John Doe 2, aka SamCodeSign. “These test purchases allowed DCU investigators to observe first-hand how Fox Tempest Defendants operate the service, the information a purchaser is provided, and the instructions given by SamCodeSign to connect to the service and sign the test software created by Microsoft,” the court documents say. “Additionally, the test purchases allowed DCU to identify cryptocurrency wallets used by Fox Tempest Defendants.” During the first test purchase, the source filled out a Google Form asking them to select how quickly they needed the certificates. Standard costs $5,000, while priority runs $7,500 and expedited carries a hefty $9,500 price tag. SamCodeSign then sent a direct message to the source and requested the $7,500 payment to be sent to a bitcoin wallet, according to screenshots (translated from Russian) in the court documents. After the source paid up, SamCodeSign sent instructions on how to access the virtual machine and complete the code signing process. “Microsoft has identified thousands of customer machines, including more than a dozen machines owned and operated by Microsoft, in the United States that have been impacted by malware signed with certificates originating from the tenants created by Fox Tempest Defendants,” the complaint says. ®

CIRT insights: How to help prevent unauthorized account removals from AWS Organizations

19 May 2026 at 23:34

The AWS Customer Incident Response Team works with customers to help them recover from active security incidents. As part of this work, the team often uncovers new or trending tactics used by various threat actors that take advantage of specific customer configurations and designs.

Understanding these tactics can help inform your architecture decisions, improve your response plans, and detect these situations if they occur in your environment.

This post examines a new approach we’re seeing threat actors use after they gain control of a customer account, which is to remove it from the customer’s AWS Organizations implementation and the policies and protections that structure provides.

The described tactic doesn’t take advantage of vulnerabilities within AWS services, instead it uses an unexpected opportunity created by a specific configuration or design to make unauthorized use of resources within an AWS account.

What’s happening?

This approach starts with the threat actor using credentials that have the organizations:LeaveOrganizationpermission grant. This permission provides access to the LeaveOrganizations API call, which, when called from a member account, attempts to remove that account from the organization.

It’s important to remember that while this approach might use a compromised root credential, threat actors can also use other methods to elevate their access until they have the required permission or the ability to assume a role that has this permission, or they have the ability to grant their current credential this permission. This is why a least privilege approach to authorization is critical to protect your environment. To learn more, see AWS Identity and Access Management (IAM) documentation and the AWS Organizations guidance on organizational unit (OU) design and service control policy (SCP) implementation.

The impact on your environment

After the account is removed from the organization, the restrictions inherited as a part of that organization—such as SCPs that were preventing destructive actions, limiting which AWS Regions could be used, or blocking specific API calls—no longer apply. The account is also no longer part of consolidated billing, so the organization’s billing alerts and cost anomaly detection will no longer cover activity in that account. AWS CloudTrail organization trails stop capturing events from the departed account, and Amazon GuardDuty findings managed through a delegated administrator will stop flowing to the central security account.

The result is frequently that the organization loses visibility into the account while it still contains resources for the organization. Related threat technique catalog entries:

Detecting this technique

When an account attempts to leave an organization, at least two API calls are logged in CloudTrail: organizations:AcceptHandshake and organizations:LeaveOrganization. If you have centralized logging configured, these might be among the last events you see from the compromised account. After it leaves the organization, it might default to logging events within the account to its own CloudTrail logs. The following CloudTrail events are associated with accounts joining or leaving an organization. These should be investigated unless they’re part of an approved operational workflow that’s used by your teams to manage AWS Organizations.

CloudTrail event What it indicates
organizations:LeaveOrganization A member account is leaving the organization
organizations:AcceptHandshake The account is accepting an invitation to join a different organization
organizations:InviteAccountToOrganization An organization is inviting the account
organizations:RemoveAccountFromOrganization The management account is removing a member account (different from a member leaving on its own)

Recommended steps to prevent this technique

Implement an SCP that denies the organizations:LeaveOrganization action. AWS Organizations provides detailed guidance on implementing this control, including the specific SCP policy JSON and advice on how to design your OU structure to accommodate legitimate account migrations while keeping the protection in place for production and development accounts.

SCPs act as guardrails that limit what any IAM policy can permit within member accounts. We strongly encourage every customer using AWS Organizations to verify whether this SCP is in place today and take steps to implement it if it is not. This SCP is quick to deploy and has minimal operational impact, providing a process to carefully manage and consider separating a member account from an organization.

Because this action can originate from any compromised IAM principal with the organizations:LeaveOrganization—not just root—the principle of least privilege for IAM permissions is an important complementary control. Limiting which users and roles can add, remove, or change policies, assume other roles, or modify their own permissions reduces the paths available for unauthorized permission changes. Regularly reviewing IAM policies for overly broad permissions—particularly iam:AttachRolePolicy, iam:AttachUserPolicy, iam:PutRolePolicy, and sts:AssumeRole with wide trust policies—will help reduce the scope of what a compromised principal can do.

Root account security remains important, because root compromise is a common entry point for this pattern. Enabling multi-factor authentication (MFA) on every root user, deleting any root access keys, and adopting centralized root access management to remove root credentials from member accounts entirely, will help reduce the risk.

Looking ahead

This technique highlights a broader theme that we see across engagements: threat actors are increasingly aware of how AWS governance controls work, and they’re taking deliberate steps to separate accounts from the controls that an organization provides. Disabling AWS CloudTrail, deleting Amazon GuardDuty detectors, and removing accounts from organizations are all variations of the same strategy: removing your accounts from the guardrails and visibility that would otherwise constrain their activity and help the customer respond.

The controls to prevent this are available today and straightforward to implement. We encourage teams to start with the AWS Organizations service team’s guidance and implement the DenyLeaveOrganizationSCP—it’s the single highest-impact, lowest-effort control for this technique. Beyond that, reviewing SCP coverage across your OU structure, verifying that both root credentials and IAM permissions are properly secured across all member accounts, and ensuring that your detection and response processes account for this technique will contribute to a stronger posture. The Threat Technique Catalog for AWS includes detection guidance for the underlying techniques.

Additional related resources

If you have feedback about this post, submit comments in the Comments section below.

Shannon Brazil

Shannon is a security engineer on the AWS Customer Incident Response Team (CIRT), specializing in digital forensics and cloud security investigations. Known in the community as 4n6lady, she is passionate about security education and mentoring the next generation of defenders.

Derek Ramirez

Derek Ramirez

Derek is a Security Engineer on the AWS Customer Incident Response Team (CIRT), where he gets to combine two things he’s passionate about: cybersecurity and building AI tools that help tackle challenging incident response questions. You can find him running through downtown Austin, working on his short-game in golf, or cheering loudly for the Dallas Cowboys.

Richard Billington

Richard Billington

Richard is a Sr. Security Engineer in the Asia-Pacific region of the AWS Customer Incident Response Team (a team that supports AWS Customers during active security events).

America's top cyber-defense agency left a GitHub repo open with passwords, keys, tokens – and incredibly obvious filenames

19 May 2026 at 19:49
The US Cybersecurity and Infrastructure Security Agency (CISA) left open a GitHub repository named “Private-CISA” containing plain-text passwords, private keys, tokens, and secrets – with obvious file names like “external-secret-repo-creds.yaml” and “AWS-Workspace-Firefox-Passwords.csv” – for six months. GitGuardian researcher Guillaume Valadon, fresh off a recent talk on Kubernetes secret leaks, found the public repository on May 14, and told The Register that he “quickly understood that the leak was bad and that time was running out. A national agency having 844 MB of production infrastructure material in a public GitHub repository for six months is as serious as a secrets leak gets.” Valadon, who previously spent nine years at France’s CISA equivalent, ANSSI, told us the leak included tokens for CISA's internal JFrog Artifactory, Azure registry keys, AWS credentials, Kubernetes manifests, ArgoCD application files, Terraform infrastructure code, GitHub personal access tokens, and Entra ID SAML certificates. GitGuardian reported the leaky repository to CISA on May 14, and the agency took it down a day later. A CISA spokesperson told The Register that it was aware of the report and is investigating. "Currently, there is no indication that any sensitive data was compromised as a result of this incident.” It’s not a good look for the nation’s infosec agency, which hasn’t had a permanent boss since Trump took office, is facing hundreds of millions of dollars in budgets cuts on top of deep cuts to staff and funding last year, and has suffered its share of embarrassing security snafus in the interim. In a Tuesday blog, Valadon said he initially thought the repo “was a hoax, given how suspicious the directory names (Backup-April-2026/, All Backups/, LZ-Artifactory/, Kubernetes-Important-Yaml-Files/, ENTRA ID - SAML Certificates/ ...), file names (external-secret-repo-creds.yaml, CAWS GitHub Token.txt, Important AWS Tokens.txt, AWS-Workspace-Firefox-Passwords.csv, Kube-Config.txt ...), and their contents (private keys, personal and professional GitHub tokens, AWS secrets, ...) seemed too good to be true,” Valadon wrote. It wasn’t a hoax – “The Cybersecurity and Infrastructure Security Agency is aware of the reported exposure and is continuing to investigate the situation,” but it was a “catalogue of unsafe practices,” he added, containing passwords stored in plain text, backups committed to Git, and an “explicit” how-to guide for disabling GitHub's secret scanning. After initially reporting the leak through the CERT/CC portal, and only receiving an auto-acknowledgement as of the morning of May 15 – a Friday – Valadon alerted security journalist Brian Krebs about the publicly exposed secrets, which seemed to speed up CISA’s processes. By 6 pm EST that night, the feds took down the repository. Valadon told The Reg he gives CISA credit for quickly deleting the repository. “Most of our responsible disclosures take much longer, and many are never fixed,” he said. “Managing to take the repository offline in a day is impressive work.” He doesn’t know if any other parties with less altruistic intentions found the secrets first, although the fact that the repository was never forked (based on public GitHub events) would seem to indicate that it wasn’t widely circulated on the dark web. “The only ones that can answer definitively is GitHub,” Valadon said. GitHub did not immediately respond to The Register’s inquiry. GitGuardian isn’t aware of any of the exposed credentials being abused by unauthorized individuals “Each category of secret in the repository unlocks a specific attack path,” Valadon said. “Stacked together, they cover the full range: from destructive attacks and ransomware extortion to quiet, long-term persistence inside CISA's build and deployment pipeline. That last scenario worried me the most, and it's why I escalated through every channel we had until the repository was taken offline.” Plus, the committer used both a CISA-issued contractor email and a personal Yahoo email across the same commits, and created the repository using a personal GitHub account. “That mixed-identity pattern is one of the hardest surfaces for security teams to cover, and it's where the worst leaks happen,” Valadon said.®

Governing infrastructure as code using pattern-based policy as code

19 May 2026 at 18:15

Organizations often struggle to enforce security and compliance requirements consistently across their cloud infrastructure. In one environment, a workload might be deployed in an AWS Region that was never approved for that class of data. In another, a security group might allow broader access than intended. Required tags might be missing. Encryption might be assumed but not configured. These gaps create risk, increase review effort, and make audits harder than they need to be.

Many organizations already have standards that describe what good infrastructure looks like. The more difficult problem is making sure those expectations are checked the same way across repositories, environments, and teams before infrastructure is deployed. Manual review helps, but it doesn’t scale when delivery moves faster and more teams provision infrastructure directly.

Policy as code helps address this problem. It turns control intent into preventive checks that run in delivery workflow.

A pattern-based policy model makes those checks more straightforward to review, maintain, and explain. Teams can organize policy checks around recurring control patterns such as required metadata, allowed configuration, exposure restriction, protection enforcement, and privilege constraint, as shown in Figure 1. This structure simplifies policy coverage across security, governance, risk, and compliance (GRC), and engineering teams.

This post shows you how to use Open Policy Agent (OPA) in continuous integration and continuous delivery (CI/CD) pipelines to validate Amazon Web Services (AWS) infrastructure changes before deployment. You will learn how to structure policy checks around recurring control patterns, fit those checks into a gated delivery workflow, and retain validation artifacts that support both release decisions and later audit review.

The Compliance Engineering and Automation team from AWS Security Assurance Services (AWS SAS) frequently helps customers implement policy as code as part of broader control design and compliance automation efforts. This post focuses on the pre-deployment layer. Runtime monitoring and post-deployment controls still matter, but they are outside the scope of this article.

Figure 1: Pattern-based policy as code in a gated delivery workflow

Figure 1: Pattern-based policy as code in a gated delivery workflow

Organize policies around recurring patterns

Teams sometimes build rules one service at a time, which can make policy as code libraries difficult to review and extend as the library grows. Similar control requirements can be expressed differently across repositories, and teams lose a common way to discuss what the policies are enforcing.

A pattern-based approach organizes policies around recurring control intent rather than service-specific checks, as shown in Figure 2. This makes coverage more straightforward to review, explain, and evolve as infrastructure changes.

A practical set of patterns includes:

  • Required metadata – for tags and other fields used for ownership, support, cost allocation, and automation.
  • Allowed configuration – for approved Regions, accepted deployment boundaries, and other approved settings.
  • Exposure restriction – for configurations that make infrastructure more reachable than intended, such as public ingress or internet-facing resources in the wrong environment.
  • Protection enforcement – for baseline safeguards such as encryption, logging, or deletion protection.
  • Privilege constraint – for AWS Identity and Access Management (IAM) definitions and access patterns that need tighter validation.
Figure 2: Recurring control patterns used to organize policy as code checks

Figure 2: Recurring control patterns used to organize policy as code checks

Where OPA fits in a layered governance model

This post focuses on the preventive layer. You still need runtime controls, drift monitoring, remediation workflows, and compliance reporting. On AWS, AWS Organizations, AWS Control Tower, AWS Config, and AWS Security Hub remain important after resources exist.

OPA fits earlier in the process and validates that infrastructure changes align with expectations. OPA evaluates structured input (HashiCorp Terraform plan JSON) against policy logic. It doesn’t replace AWS governance services that provide organizational guardrails, continuous monitoring, and resource level enforcement after resources exist.

As shown in Figure 3:

  • OPA – Checks proposed changes before deployment
  • AWS Organizations and Control Tower – Establish organizational guardrails
  • AWS Config and Security Hub – Provide visibility and monitoring after resources exist
  • Service-level protections – Enforce settings at the resource boundary

Figure 3: OPA validates changes pre-deployment; AWS services enforce guardrails, monitoring, and controls post-deployment

Figure 3: OPA validates changes pre-deployment; AWS services enforce guardrails, monitoring, and controls post-deployment

How to implement policy validation in your CI/CD pipeline

Use the following steps to integrate OPA policy evaluation into your delivery workflow:

Submit a change through a pull request or merge request.

  1. Run early validation checks such as formatting, syntax validation, and dependency checks.
  2. Generate a Terraform plan and convert it to JSON format.
  3. Evaluate the plan (JSON format) against the shared OPA policy library.
  4. Publish the validation report as an artifact.
  5. Run additional automated quality checks as needed.
  6. Use the validation artifact during approval decisions for higher-risk environments.
  7. Deploy approved changes.
  8. Continue post-deployment monitoring through AWS-native governance services.

Quality gates provide automated pass or fail results based on defined criteria. Approval gates control whether a change moves into a protected environment. This separation matters—manual approval isn’t the first place where anyone notices missing tags, a disallowed AWS Region, or public ingress. Automated checks identify those issues earlier. OPA belongs in the automated gate layer. Its output also feeds the approval process.

Structure your policy library by control domain and intent

A pattern-based library structure, as shown in the following sample, keeps the policy model closer to how teams talk about controls.

  opa-policies/
  ├── patterns/
  │ ├── baseline/ # Foundational security
  │ ├── tagging/ # Required tags
  │ ├── networking/ # Network controls
  │ ├── logging/ # Logging enablement
  │ ├── encryption/ # Encryption at rest and transit
  │ └── iam/ # IAM best practices
  ├── shared/
  │ ├── helpers.rego
  │ └── messages.rego
  ├── tests/
  ├── fixtures/
  └── docs/

A compliance engineer might describe a requirement as mandatory metadata. A cloud engineer might describe the same requirement as a tagging standard. The pattern structure helps both teams talk about the same thing.

Example 1: Enforce secure transport for Amazon S3

This example demonstrates the protection enforcement pattern for Amazon Simple Storage Service (Amazon S3). The goal is to verify that S3 bucket access is protected in transit by requiring a bucket policy that denies requests when aws:SecureTransport is set to false.

The policy checks two things: whether an S3 bucket policy includes a deny statement that blocks non-encrypted requests, and whether an S3 bucket has any corresponding bucket policy at all. The rule evaluates both create and update actions in the Terraform plan JSON.

This example uses an explicit deny rather than an allow statement for secure transport. An explicit deny overrides allow statements that might exist elsewhere in the policy set, making it the stronger enforcement pattern.

package compliance.amazon_s3.ssl

import future.keywords.in
import future.keywords.contains
import future.keywords.if

# Deny: S3 bucket policy missing SecureTransport deny statement
deny contains msg if {
    resource := input.resource_changes[_]
    resource.type == "aws_s3_bucket_policy"
    is_create_or_update(resource.change.actions)

    policy_value := resource.change.after.policy
    policy := json.unmarshal(policy_value)

    not has_secure_transport_deny(policy)

    msg := sprintf(
        "[S3-OPA-1] Resource '%s' does not enforce SSL/TLS. Bucket policy must include a Deny statement with Condition Bool aws:SecureTransport set to \"false\".",
        [resource.address]
    )
}

# Deny: S3 bucket created without any corresponding bucket policy
deny contains msg if {
    resource := input.resource_changes[_]
    resource.type == "aws_s3_bucket"
    is_create_or_update(resource.change.actions)

    bucket_name := resource.change.after.bucket
    not has_bucket_policy(bucket_name)

    msg := sprintf(
        "[S3-OPA-1] Resource '%s' (bucket '%s') has no bucket policy. A bucket policy with a Deny statement for aws:SecureTransport \"false\" is required.",
        [resource.address, bucket_name]
    )
}

is_create_or_update(actions) if { actions[_] == "create" }
is_create_or_update(actions) if { actions[_] == "update" }

has_bucket_policy(bucket_name) if {
    bp := input.resource_changes[_]
    bp.type == "aws_s3_bucket_policy"
    is_create_or_update(bp.change.actions)
    bp.change.after.bucket == bucket_name
}

has_secure_transport_deny(policy) if {
    stmt := policy.Statement[_]
    stmt.Effect == "Deny"
    stmt.Condition.Bool["aws:SecureTransport"] == "false"
    stmt.Principal == "*"
    action := stmt.Action
    action == "s3:*"
}

When you adapt this example, decide whether you want to require one exact policy shape or support several equivalent forms of enforcement. A strict rule is more straightforward to reason about, but it might create false positives if teams already use alternate policy structures that achieve the same outcome.

Example 2: Restrict public ingress on sensitive ports

This example implements the exposure restriction pattern. The goal is to identify Amazon Virtual Private Cloud (Amazon VPC) security group configurations that allow public ingress on sensitive ports before those rules are deployed.

The policy evaluates both inline aws_security_group ingress rules and standalone aws_security_group_rule resources, because customer repositories often use both modeling styles.

This example checks directly for public ingress on sensitive ports rather than trying to infer whether later controls might reduce actual exposure. Security group rules are a direct expression of intended network reachability, making them the right place to enforce this pattern early.

package compliance.amazon_vpc.ingress

import future.keywords.in
import future.keywords.contains
import future.keywords.if

# Sensitive ports that must not be open to the internet
sensitive_ports := {22, 3389, 5432}

# Deny: aws_security_group with inline ingress open to 0.0.0.0/0 on sensitive ports
deny contains msg if {
    resource := input.resource_changes[_]
    resource.type == "aws_security_group"
    is_create_or_update(resource.change.actions)

    ingress := resource.change.after.ingress[_]
    ingress.cidr_blocks[_] == "0.0.0.0/0"

    port := sensitive_ports[_]
    ingress.from_port <= port
    ingress.to_port >= port

    msg := sprintf(
        "[VPC-OPA-1] Resource '%s' allows ingress from 0.0.0.0/0 on port %d. Restrict access to specific CIDR ranges.",
        [resource.address, port]
    )
}

# Deny: aws_security_group_rule with type "ingress" open to 0.0.0.0/0 on sensitive ports
deny contains msg if {
    resource := input.resource_changes[_]
    resource.type == "aws_security_group_rule"
    is_create_or_update(resource.change.actions)

    resource.change.after.type == "ingress"
    resource.change.after.cidr_blocks[_] == "0.0.0.0/0"

    port := sensitive_ports[_]
    resource.change.after.from_port <= port
    resource.change.after.to_port >= port

    msg := sprintf(
        "[VPC-OPA-1] Resource '%s' allows ingress from 0.0.0.0/0 on port %d. Restrict access to specific CIDR ranges.",
        [resource.address, port]
    )
}

is_create_or_update(actions) if { actions[_] == "create" }
is_create_or_update(actions) if { actions[_] == "update" }

When you adapt this example, review which ports to treat as sensitive, whether both IPv4 and IPv6 exposure need checking, and how to handle approved exceptions.

Example 3: Enforce least privilege trust policy for IAM roles

This example implements the privilege constraint pattern for IAM role trust policies. The goal is to identify trust relationships that allow overly broad principals to assume a role. The policy inspects the assume_role_policy document for aws_iam_role resources and looks for wildcard principals in three valid representations: Principal is "*", Principal.AWS is "*", and Principal.AWS is an array containing "*". A wildcard principal allows a broader set of callers than most environments intend to permit. By treating wildcard principals as the prohibited pattern, the rule enforces a safer default and returns a clear result that reviewers can understand quickly.

package compliance.amazon_iam.trust

import future.keywords.in
import future.keywords.contains
import future.keywords.if

# Deny: IAM role with wildcard principal in trust policy
deny contains msg if {
    resource := input.resource_changes[_]
    resource.type == "aws_iam_role"
    is_create_or_update(resource.change.actions)

    policy_value := resource.change.after.assume_role_policy
    policy := json.unmarshal(policy_value)

    stmt := policy.Statement[_]
    stmt.Effect == "Allow"
    has_wildcard_principal(stmt)

    msg := sprintf(
        "[IAM-OPA-2] Resource '%s' has a wildcard principal in its trust policy. Specify explicit account ARNs, service principals, or federated providers instead of \"*\".",
        [resource.address]
    )
}

# Principal is directly "*"
has_wildcard_principal(stmt) if {
    stmt.Principal == "*"
}

# Principal.AWS is "*"
has_wildcard_principal(stmt) if {
    stmt.Principal.AWS == "*"
}

# Principal.AWS is an array containing "*"
has_wildcard_principal(stmt) if {
    stmt.Principal.AWS[_] == "*"
}

is_create_or_update(actions) if { actions[_] == "create" }
is_create_or_update(actions) if { actions[_] == "update" }

When you adapt this example, decide what least privilege means for your IAM trust model. The key design choice is whether your policy checks for a single prohibited pattern or validates trust relationships against an approved set of trusted principals and conditions.

AWS Labs provides IAM Policy Autopilot, an open-source Model Context Protocol (MCP) server and command-line tool that helps generate baseline identity-based IAM policies from application code. That is adjacent to the pattern shown here —IAM Policy Autopilot helps with policy generation, while this example focuses on validating whether IAM role trust policies are scoped appropriately in infrastructure changes.

CI/CD implementation examples

The following examples show the same operating model in two common CI/CD systems. The syntax changes, but the sequence stays the same: validate, plan, evaluate policy, retain the artifact, and use the result during promotion and approval. These examples assume OPA is installed in your CI/CD environment, the opa-policies directory contains your policy library, and Terraform is configured with appropriate credentials.

GitLab CI

stages:
  - validate
  - plan
  - policy_check

variables:
  TF_IN_AUTOMATION: "true"

terraform_validate:
  stage: validate
  script:
    - terraform fmt -check
    - terraform init
    - terraform validate

terraform_plan:
  stage: plan
  script:
    - terraform plan -out=tfplan
    - terraform show -json tfplan > tfplan.json
  artifacts:
    paths:
      - tfplan.json

opa_policy_check:
  stage: policy_check
  script:
    - opa eval --format pretty --data opa-policies --input tfplan.json "data.terraform.deny"
    - opa eval --format json --data opa-policies --input tfplan.json "data.terraform.deny" > policy-report.json
  artifacts:
    paths:
      - policy-report.json

GitHub Actions

name: Terraform Policy Check
on:
  pull_request:

jobs:
  policy-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3

      - name: Terraform Format Check
        run: terraform fmt -check
      - name: Terraform Init
        run: terraform init
      - name: Terraform Validate
        run: terraform validate
      - name: Terraform Plan
        run: terraform plan -out=tfplan
      - name: Convert Plan to JSON
        run: terraform show -json tfplan > tfplan.json
      - name: Run OPA Policy Check
        run: |
          opa eval --format pretty --data opa-policies --input tfplan.json "data.terraform.deny"
          opa eval --format json --data opa-policies --input tfplan.json "data.terraform.deny" > policy-report.json
      - name: Upload Validation Artifact
        uses: actions/upload-artifact@v4
        with:
          name: policy-report
          path: policy-report.json

Retain validation artifacts for review and audit support

In mature delivery workflows, policy results don’t disappear into pipeline logs but are retained as validation artifacts. Those artifacts help reviewers decide whether a change is ready for approval, supports exception handling by showing which controls failed and why, and can stay with the change record for later audit discussions. At a minimum, the artifact identifies the change or pipeline run, the evaluated scope, the policy package or version, the checks that ran, and the pass or fail results.

Test the policy model like software

The first few rules are usually straightforward.The real work starts when the library grows and multiple teams depend on it. Testing includes:

  • Positive and negative test cases – Each policy has cases that show valid input and cases that show expected failures.
  • Regression coverage – Shared helpers need regression coverage.
  • Realistic fixtures – Terraform plan fixtures look like real changes rather than tiny made-up samples.
  • Impact analysis – When a rule changes, teams can tell quickly what else might be affected.

If developers stop trusting the results, they stop treating policy as a useful mechanism.

A phased approach to rolling out policy checks

You don’t need broad coverage on day one. A phased rollout works better than an all at once enforcement approach.

Phase 1: Assess and pilot

  • Start in advisory mode so teams can see results without being blocked.
  • Identify two or three high-confidence patterns such as required metadata, approved Regions, or public exposure restrictions.
  • Run OPA against existing pipelines and review the output for accuracy.

Phase 2: Begin enforcement

  • Enforce the small set of high-confidence patterns after the output is stable and the failures are useful.
  • Integrate validation artifacts into your approval workflow.
  • Establish ownership and exception handling processes for shared packages.

Phase 3: Operationalize and expand

  • Formalize versioning for shared policy packages.
  • Expand pattern coverage based on team feedback and organizational priorities.
  • Connect pre-deployment validation with post-deployment monitoring through AWS Config, AWS Security Hub, and AWS Organizations.

Conclusion

Policy as code helps narrow the distance between what an organization says it expects and what its delivery system checks. By implementing these OPA patterns in your CI/CD pipelines, you can build a preventive layer that evaluates infrastructure changes before deployment. With a pattern-based library, validation artifacts, and clear ownership, policy as code becomes a repeatable way to help translate control intent into day-to-day delivery, while AWS governance services continue to provide visibility and monitoring after resources exist.

To learn more about policy as code and AWS governance capabilities, see:

If you have feedback about this post, submit comments in the Comments section below.

Guptaji Teegela

Guptaji Teegela

Guptaji is a Cloud Infrastructure Architect with AWS Security Assurance Services, where he focuses on compliance automation and policy-as-code for regulated workloads. He brings over 15 years of hands-on experience across site reliability engineering, platform engineering, and cloud architecture, with deep expertise in both AWS and Azure environments. Backed by a broad portfolio of industry certifications spanning cloud and security domains, Guptaji is driven by a passion for helping customers design and deliver reliable, secure, and highly automated cloud platforms.

Paul Keastead

Paul Keastead

Paul is a Senior Security Engineer with AWS Global Professional Services Security, specializing in compliance automation, policy as code, and security engineering for regulated workloads. A CISSP-ISSEP, Lead CMMC Certified Assessor, and former FedRAMP Assessor, he builds automated validation pipelines that translate control requirements into preventive, testable checks in delivery workflows. He brings over a decade of experience in national security and public sector technology compliance.

Clear your calendar, Drupal user: You have a critically urgent patch to install

19 May 2026 at 17:56
Updated: If you use Drupal, get ready to patch without delay. The org behind the popular open source content management system is warning of a highly critical vulnerability in Drupal core that is serious enough for it to tell users ahead of Wednesday’s patch release to set aside time to install the fix immediately. The Drupal Security Team’s Monday PSA announcing the imminent patch for Drupal core doesn’t include any specifics, with the PSA noting that Drupal isn’t willing to share additional information until the announcement is made alongside the patch release. That, says Drupal, will happen at some point between 1700 and 2100 UTC on Wednesday, May 20. To reiterate, this vulnerability is found in Drupal core, the bare-bones version of Drupal designed for developers, and not Drupal CMS, the preconfigured version for those who want Drupal but don’t have coding skills. Drupal noted that sites using Drupal Steward, its paid web application firewall service, are protected against known attack vectors, though it still recommends Steward customers update their core instances in case additional exploit methods emerge. “The Drupal Security Team urges you to reserve time for core updates at that time because exploits might be developed within hours or days,” the advisory warns. Drupal also recommends users update to the latest supported release prior to Wednesday’s patch “so that you can address any other upgrade issues before the security window." While it won’t get specific on the nature of the vulnerability, Drupal did share its severity score based on NIST’s standard scoring methodology, and it’s not good: The bug scored 20 out of a max of 25 on that scale, as defined by Drupal’s own documentation. More specifically, it’s trivially easy to leverage, doesn’t require any privilege level to exploit, could make all non-public data on an affected site accessible to the attacker, and could allow an attacker to modify or delete whatever they wanted. The only two things preventing it from scoring a perfect 25/25 are the fact that a known exploit doesn’t exist yet and that it doesn’t affect all configurations, only those using “uncommon module configurations.” Drupal noted that security releases will be published on Wednesday for all currently supported core branches (11.3.x, 11.2.x, 10.6.x, and 10.5.x), as well as unsupported Drupal 11.1.x and 10.4.x branches for sites that have not yet upgraded from older 10.x and 11.x releases. Drupal users on 8.9 and 9.5 are also getting patches “given the potential severity of this issue,” though the advisory warns 8.9 and 9.5 users will need to install those updates manually, which “might introduce other bugs or regressions,” leading Drupal to recommend a full upgrade to a supported core branch. “Drupal 8 and 9 include numerous other, previously disclosed, security vulnerabilities that will not be addressed by either Drupal Steward or the best-effort patch files,” the advisory said. Drupal 7 users are safe. Given the fact that not all Drupal core environments will be affected, the advisory recommends all Drupal core users set aside time on Wednesday to determine whether they’re part of the vulnerable class, and take action immediately if so. ® Updated to add on May 20: The Drupal Security Team has been in contact to warn that, while Core is the primarily vulnerable product, Core's inclusion in Drupal CMS means those environments might be vulnerable too, so anyone running Drupal will need to be sure their site is secure. As for the patch itself, Drupal told us it can be installed in "minutes or maybe seconds depending on the site," which likely won't need to be taken offline in order to install the patch.In other words, you really ought to be sure this gets installed before you're caught being a straggler.

Disrupting Fox Tempest: A cybercrime service that turned “verified” software into a pathway for ransomware 

19 May 2026 at 17:03

Every day, we decide what software to trust in seconds guided by simple labels such as “verified,” “secure,” and “safe to install.” The problem is that those signs can be manipulated.

Today, Microsoft unsealed a legal case in the US District Court for the Southern District of New York targeting a cybercrime service known as Fox Tempest, which, since May 2025, has enabled cybercriminals to disguise malware as legitimate software. The malware-signing-as-a-service (MSaaS) worked by fraudulently accessing and abusing code signing tools, such as Microsoft’s Artifact Signing, a system designed to verify that software is legitimate and hasn’t been tampered with. Cybercriminals used the service to deliver malware and enable ransomware and other attacks, infecting thousands of machines and compromising networks worldwide.

For the first time, Microsoft is taking public action against a powerful, but often unseen, enabler within the cybercrime ecosystem, targeting how cybercriminals prepare and employ techniques to optimize their rate of success. To disrupt the service, we seized Fox Tempest’s website signspace[.]cloud, took offline hundreds of the virtual machines running the operation, and blocked access to a site hosting the underlying code. This action builds upon persistent internal efforts to revoke fraudulently obtained code‑signing certificates and enhance our defenses and employ new security features to detect and thwart such malicious activity. It’s already having an impact: cybercriminals are complaining about challenges accessing the current service.

Our impact extends beyond one actor. The lawsuit targets Fox Tempest’s infrastructure and also names Vanilla Tempest as a co-conspirator, a prominent ransomware group that used the service to deploy malware like Oyster, Lumma Stealer, and Vidar, and ransomware, including  Rhysida, in multiple recent cyberattacks. Vanilla Tempest has targeted schools, hospitals, and other critical organizations worldwide, while Rhysida, a highly evolved ransomware variant that both encrypts files and steals data, often used for double extortion, has been used by various actors in numerous high-profile attacks globally, including to steal and leak internal documents from the British Library and to disrupt operations at Seattle-Tacoma International Airport. Microsoft’s investigation further linked Fox Tempest to various additional ransomware affiliates and families, including INC, Qilin, Akira, and  others.

More broadly, this case points to how cybercrime is changing.  What once required a single group to carry out an attack from start to finish is now broken into a modular ecosystem where services are bought and sold and work interchangeably with one another. Some services are inexpensive and widely used. Others, like Fox Tempest, are highly specialized and expensive because they remove friction or bypass obstacles that make attacks fail, making them both more reliable and harder to detect. As seen with Fox Tempest, when these services are combined with AI-powered tactics, attacks can scale more easily, reaching more people and becoming more convincing.

This kind of abuse isn’t new, but it is evolving

Illicit code-signing certificates have been  sold and trafficked for more than a decade. That includes its use by nation-state actors to target critical infrastructure organizations in Europe. What’s changed is how this activity is marketed, packaged, and sold as a service, along with the scale at which it is now used across ransomware campaigns. Instead of buying certificates one-by-one, criminals upload their malware to a service that signs it for them.

What also makes this model notable is the level of investment. Unlike lower-cost services like RedVDS, a cybercriminal infrastructure provider that costs as little as $24 per  month, which Microsoft disrupted earlier this year, Fox Tempest shows that more sophisticated actors are willing to pay thousands of dollars for advanced capabilities that make attacks easier to carry out, harder to detect, and more likely to succeed.

How Fox Tempest sold “legitimacy” at scale

Fox Tempest’s business model was straightforward: sell fraudulent code-signing capability, let others package malware, and enable attacks downstream. The model has generated millions in proceeds, demonstrating significant financial profit.

Behind the scenes, the operators built access at scale. Using fabricated identities and impersonating legitimate organizations, they created hundreds of fraudulent Microsoft accounts to obtain real code-signing credentials in volume. Customers who paid for Fox Tempest’s services could then upload malicious files via an online portal for them to  be signed using Fox Tempest-controlled certificates. Cybercriminals paid thousands of dollars for the service, reflecting how valuable this capability was.

Fox Tempest’s pricing model form and Telegram channel where you could purchase the service. The more you pay, the quicker you get access to the service.

Once signed, their malware appeared legitimate. Attackers then distributed the signed malware through tactics such as search manipulation and malicious ads, where users are more likely to trust what they encounter.  AI then helped generate and refine these campaigns  to reach a broader audience.

How code-signed malware appears in search results.
Fake Microsoft Teams download page and delivery mechanism for disguised code-signed malware

That changed the odds. Malicious software that should have been blocked or flagged by antivirus and other safeguards was more likely to be opened, allowed to run, or pass security checks—essentially allowing malware to hide in plain sight. Instead of forcing their way in, attackers could slip through the front door by masquerading as a welcomed guest.

An overview of malware‑signing‑as‑a‑service.

As Microsoft disabled fraudulent accounts, revoked fraudulently obtained certificates and introduced enhanced protections, the Fox Tempest operators continually adapted. In February 2026, they ultimately shifted to networks of third-party-hosted virtual machines to maintain and scale operations. That kind of rapid change is part of the model: these services evolve quickly in response to pressure and friction. In fact, Microsoft has observed further adaptations in response to our layered disruption efforts, with Fox Tempest attempting to shift operations and customers to another code-signing service.

Fox Tempest’s response to the disruptive efforts—translated from Russian by a third-party partner

In addition to seizing the core infrastructure behind the operation and degrading its ability to function at scale, we have taken further steps to prevent similar abuse, removing fraudulent accounts, strengthening verification, and limiting how this type of access can be reused. More technical details on the operation and the steps we’re taking to prevent similar abuse are available in this Microsoft Threat Intelligence blog.

Cutting off a critical enabler of cybercrime

This action wasn’t about stopping one actor. It sought to strategically neutralize a vital service that many attackers, particularly ransomware groups, rely on. When legitimate code signing services are weaponized, everything downstream gets easier: malware looks legitimate, security warnings are less likely to trigger, and attacks are more likely to succeed. Degrading that capability adds friction and forces a reset. The success rates of attacks decrease, and attackers have to rebuild, find new ways in, and accept more risk with each attempt—driving up both the cost and the time required to operate.

Importantly, disruption actions don’t happen in isolation and are never one-and- done. Collaboration is critical, as different organizations and sectors have visibility into different parts of the cybercrime ecosystem. In this case, we are working closely with cybersecurity company Resecurity, whose insights help us better understand how Fox Tempest operates. We are also collaborating closely with Europol’s European Cybercrime Centre (EC3) and the Federal Bureau of Investigation (FBI). As we’ve seen in previous efforts, we expect actors to try to rebuild. Collectively, we will continue to take action and keep the pressure on. That also means strengthening the code signing ecosystem through intelligence sharing and partnering with other code signing services, so it’s harder for malicious actors to regain that ground in the first place.

When attackers can make malicious software look legitimate, it undermines how people and systems decide what’s safe. Disrupting that capability is key to raising the cost of cybercrime. As threats evolve, the Microsoft Digital Crimes Unit will continue working with partners across industry and law enforcement to persistently identify and cut off the services that enable them.

For more than a decade, the Microsoft Digital Crimes Unit (DCU) has persistently disrupted cybercrime and nation-state threats targeting people, organizations, and critical infrastructure. Explore major disruptions—and the ongoing cases and operations behind them here: Disrupting cyberthreats since 2008 | Microsoft

The post Disrupting Fox Tempest: A cybercrime service that turned “verified” software into a pathway for ransomware  appeared first on Microsoft On the Issues.

❌