Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
155989 stories
·
33 followers

From package to postinstall payload: Inside the Mastra npm supply chain compromise

1 Share

Microsoft Threat Intelligence observed a large-scale npm supply chain attack affecting 140+ packages across the mastra and @mastra scopes on the npm registry. Microsoft shared its findings with the npm security team, and the compromised packages have been removed and the attacker’s publish access to the @mastra scope has been revoked. The compromise originated from the takeover of the ehindero npm maintainer account, which had publish rights across the Mastra ecosystem and was used to publish poisoned package versions that introduced easy-day-js, a malicious typosquat of the popular dayjs library.

Once installed, easy-day-js triggered a postinstall hook that executed an obfuscated dropper script, disabled Transport Layer Security (TLS) certificate verification, contacted attacker-controlled command-and-control (C2) infrastructure, downloaded a second-stage payload, and executed the payload as a detached hidden process. The activity followed a coordinated staged delivery pattern, with a clean bait version published first, followed by a weaponized version and rapid publication of the compromised Mastra packages.

Because the payload executes during installation, any developer workstation or continuous integration and continuous delivery (CI/CD) pipeline that ran npm install or npm update after the compromised versions were published was potentially exposed, regardless of whether the package was imported in application code.  This created risk to credentials, tokens, build environments, and downstream software integrity. Microsoft Defender Antivirus, Microsoft Defender for Endpoint, and Microsoft Defender XDR provide detections and hunting coverage for suspicious Node.js execution, malicious package behavior, reflective code loading, persistence activity and command-and-control communication.

Attack chain overview

Figure 1. End-to-end attack chain from npm account takeover through mass dependency injection to second-stage payload execution.

At a high level, the attack progressed through six phases:

  • Account compromise: The attacker gained control of the ehindero npm account , a listed maintainer with publish rights across the entire @mastra scope.
  • Typosquat creation: The attacker published easy-day-js, a package impersonating the legitimate dayjs library (57M+ weekly downloads), using a coordinating anonymous email account ).
  • Mass poisoning: Using the compromised account, the attacker published new versions of 140+packages across the @mastra scope, each injected with easy-day-js@^1.11.21 as a new dependency. All poisoned versions were tagged as latest.
  • Delivery: Developers and CI/CD pipelines running npm install automatically resolved to the compromised versions. The semantic versioning (SemVer) range ^1.11.21 resolved to 1.11.22, the version containing the malicious postinstall hook.
  • Execution: The postinstall hook executed an obfuscated 4,572-byte dropper that disabled TLS verification, dropped tracking markers, and contacted the C2 server.
  • Second-stage payload: The dropper fetched executable code from the C2 server, wrote it as a randomly named .js file, and spawned it as a fully detached, window-hidden Node.js process.

Discovery and initial indicators

Microsoft Threat Intelligence identified the compromise through anomalous publishing patterns on the mastra package. All previous versions of mastra (through v1.13.0) were published through GitHub Actions OpenID Connect (OIDC), the legitimate CI/CD pipeline. Version 1.13.1 was manually published by ehindero using a Tutamail address, an anonymous email service.

Figure 2. Publisher comparison across mastra versions showing the anomalous manual publish on v1.13.1.

The only change between mastra@1.13.0 and mastra@1.13.1 was the addition of easy-day-js@^1.11.21 as a dependency. No corresponding code changes were present in the Mastra GitHub repository. Both the compromised publisher (ehindero2016@tutamail.com) and the typosquat publisher (sergey2016@tutamail.com) used the same anonymous email provider, Tutamail.

Dependency injection: the poisoned package.json

The compromised mastra@1.13.1 package.json reveals the injected dependency alongside the anomalous publisher metadata:

Figure 3. The compromised mastra@1.13.1 package.json with the injected easy-day-js dependency and the anomalous npm publisher.

The easy-day-js dependency was not present in any prior versions of mastra npm packages. Its addition, paired with the SemVer range ^1.11.21, ensures that the npm resolves to the weaponized 1.11.22 release.

Typosquat analysis: easy-day-js

The easy-day-js package is a deliberate impersonation of the legitimate dayjs library:

AttributeLegitimate dayjsMalicious easy-day-js
Maintaineriamkun <kunhello@outlook[.]com>sergey2016 <sergey2016@tutamail[.]com>
Claimed authoriamkuniamkun (impersonated)
Repository URLgithub.com/iamkun/dayjsgithub.com/iamkun/dayjs (copied)
Weekly downloads57,251,792newly created
Version count89+ versions since 20182 versions (both June 16, 2026)
postinstall scriptNonenode setup.cjs –no-warnings (v1.11.22)

Staged delivery pattern

The typosquat used a two-phase delivery strategy:

  • Phase 1 (clean bait): easy-day-js@1.11.21 was published at 07:05 UTC on June 16, 2026. This version contained only legitimate dayjs code with no postinstall hook.
  • Phase 2 (weaponization): easy-day-js@1.11.22 was published at 01:01 UTC on June 17, 2026, adding the setup.cjs payload and the postinstall hook. The dayjs.min.js file is byte-identical between both versions, confirming only the dropper was added.

The weaponized package.json in version 1.11.22 exposes the postinstall hook:

Figure 4. The weaponized easy-day-js@1.11.22 package.json. The postinstall hook runs setup.cjs automatically on npm install.

Obfuscation and payload analysis

Stage 0: Obfuscated dropper (setup.cjs)

The setup.cjs payload is protected with JavaScript obfuscation using rotated string arrays and a custom base64 decoder function:

Figure 5. The obfuscated setup.cjs dropper with rotated string array and base64 encoded string lookups.

The obfuscation technique uses a common pattern: an array of 40 Base64-encoded strings is shuffled at initialization using a numeric seed (0x4c11d), then accessed through a decoder function that performs Base64 decoding with character substitution. This prevents static analysis tools from extracting meaningful strings.

Stage 1: String table decryption

Decoding the rotated string array reveals the payload’s true capabilities:

Figure 6. The decoded string table revealing C2 addresses, file system operations, and process spawning functionality.

Key decoded strings include the secondary C2 address (23.254.164[.]123:443), Node.js built-in module references (node:child_process, node:os), and file system operations (writeFileSync, rmSync).

Stage 2: Deobfuscated payload logic

After resolving all string references and control flow, the full payload logic emerges as a five-step attack sequence:

Figure 7. The fully deobfuscated setup.cjs payload showing the five-step attack sequence from.

TLS bypass to self-deletion

Step 1: Disable TLS verification. The payload sets NODE_TLS_REJECT_UNAUTHORIZED to ‘0’, disabling certificate validation for all HTTPS requests in the Node.js process. This enables communication with the C2 server without valid certificates.

Step 2: Drop filesystem markers. Two tracking files are written to the OS temp directory: $TMPDIR/.pkg_history contains the install path of the compromised package, and $TMPDIR/.pkg_logs contains the package name encoded with XOR 0x80:

Figure 8. XOR 0x80 decoding of the .pkg_logs marker reveals the string easy-day-js.

Step 3: Fetch second-stage payload. The dropper issues a GET request to hxxps://23.254.164[.]92:8000/update/49890878 and reads the response body as text.

The second-stage payload is a ~41 KB cross-platform Node.js tasking client. Unlike a fire-and-forget stealer, the implant installs sign-in persistence, sends a Start beacon to the C2, then enters a repeated Check poll loop. Tasks returned by the server are dispatched to built-in runners (a Node runner and a Shell runner), and it honors configuration update and exit commands, meaning the operator can push and execute arbitrary follow-on code on the host at any time. On Windows, the payload additionally executes reflective .NET assembly injection for in-memory code execution.

Step 3.A: Windows execution chain. On Windows, the payload performs host reconnaissance and reflective in-memory code execution before establishing persistence.

The payload enumerates all installed applications across three sources—Start Menu entries (Get-StartApps), registry Uninstall keys, and UWP packages (Get-AppxPackage)—to fingerprint the compromised host:

Each enumeration is wrapped in try/catch with silent error handling. The deduplicated results are exfiltrated back to the C2 for victim profiling, enabling the attacker to identify installed security products and high-value targets.

A second PowerShell script receives two C2 endpoint URLs through the SCRIPT_ARGS environment variable. It disables SSL certificate validation and defines an HTTP POST function that Base64-encodes request bodies using a legacy IE8 User-Agent string:

The first C2 request downloads a .NET DLL that is loaded directly into memory via reflection, completely bypassing disk-based detection. The script resolves the Extension.SubRoutine class and invokes its Run2 method with a second downloaded payload, the path to cmd.exe, and the C2 callback address:

This pattern is consistent with process injection, where the payload is injected into a cmd.exe process that communicates back to the C2 over HTTPS (port 443). The entire chain is fileless—no artifacts are written to disk.

Step 3.B: Cross-platform persistence. The implant installs login persistence on all three major operating systems, using a consistent NVM/Node masquerade theme across platforms:

OSPersistence mechanismDrop locationArtifact name
WindowsRegistry Run key
(HKCU\…\CurrentVersion\Run)
C:\ProgramData\NodePackages\NvmProtocal
macOSLaunchAgent
 (RunAtLoad)
~/Library/NodePackages/com.nvm.protocal.plist
Linuxsystemd user unit
 (WantedBy=default.target)
~/.config/systemd/nvmconf/nvmconf.service

On Windows, the Run key launches a hidden PowerShell process that invokes Node.js:

On Linux, the systemd user unit restarts the implant on failure with a 5-second delay:

All three persistence paths drop the implant as protocal.cjs (a deliberate misspelling) into directories named to mimic legitimate Node.js installations. The value name NvmProtocal, the macOS label com.nvm.protocal, and the Linux unit nvmconf.service are deliberately designed to blend into a developer workstation.

Step 3.C: Collection and exfiltration. The implant performs the following collection before exfiltrating to the C2:

  • Cryptocurrency wallet inventory: A hardcoded list of 166 wallet browser-extension IDs (MetaMask, Phantom, Coinbase Wallet, Binance Wallet, TronLink, and others) is matched against installed extensions across Chrome, Edge, and Brave profiles.
  • Browser history: Each profile’s History SQLite database is copied to a temp directory prefixed with browser-hist- and queried through node:sqlite.
  • Host reconnaissance: Gather hostname, architecture, platform, user ID, installed applications, and running processes.

Collected data is exfiltrated using a custom ICAP-style protocol over HTTPS POST (reqmod, PrimaryUrl, SecondaryUrl headers), with hostnames resolved through node:dns and traffic carrying a spoofed legacy IE8 User-Agent string.

Step 4: Writing and executing the payload. The downloaded code is written to a file with a cryptographically random name (<12 random hex bytes>.js) in the OS temp directory, then spawned as a detached, window-hidden Node.js process using child_process.spawn with unref().

Step 5: Self-deletion. The dropper removes itself (fs.rmSync(__filename)) to eliminate forensic evidence from the installed package directory.

Timeline analysis

Every package published by the ehindero account contained easy-day-js as an injected dependency. Packages last published by GitHub Actions CI/CD or other legitimate maintainers were not affected.

Attack timeline

Timestamp (UTC)Event
June 16, 07:05easy-day-js@1.11.21 published (clean bait, no payload)
June 17, 01:01easy-day-js@1.11.22 published (adds postinstall with setup.cjs)
June 17, 01:20mastra@1.13.1 and 140+ other @mastra/* packages published with easy-day-js dependency

** Microsoft Threat Intelligence monitoring observed easy-day-js@1.11.22 at 01:07 UTC and mastra@1.13.1 at 01:28 UTC on June 17, 2026

Mitigation and protection guidance

Microsoft recommends the following mitigations to reduce the impact of this threat:

  • Review dependency trees for direct or transitive usage of affected @mastra packages at the compromised versions listed above.
  • Check for the presence of easy-day-js in node_modules/ or package-lock.json files across your projects and CI/CD environments.
  • Pin known-good package versions where possible. For mastra, version 1.13.0 and earlier are unaffected. For @mastra/core, version 1.42.0 and earlier are unaffected.
  • Run npm install with –ignore-scripts to prevent automatic execution of postinstall hooks during dependency installation.
  • Check systems for indicators of compromise (IOC) artifacts: Look for $TMPDIR/.pkg_history, $TMPDIR/.pkg_logs, and unexpected .js files in the user’s home or temp directories.
  • Rotate any credentials, tokens, or API keys that may have been present on systems where the compromised packages were installed.
  • Block the C2 IP addresses 23.254.164[.]92 and 23.254.164[.]123 at the network perimeter.
  • Audit CI/CD logs for unexpected outbound connections to the C2 IP addresses or suspicious postinstall script execution.
  • Enable cloud-delivered protection in Microsoft Defender Antivirus or equivalent antivirus protection.

Microsoft Defender XDR detections

Microsoft Defender XDR customers can refer to the list of applicable detections below. Microsoft Defender XDR coordinates detection, prevention, investigation, and response across endpoints, identities, email, and apps to provide integrated protection against attacks like the threat discussed in this blog.

TacticObserved activityMicrosoft Defender coverage
Initial accessSuspicious script execution during npm install or package lifecycle activityMicrosoft Defender Antivirus – Trojan:JS/NpmStealz.Z!MTB
– Trojan:JS/NpmStealz.ZA!MTB
 
Microsoft Defender for Endpoint
– Suspicious Node.js process behavior
– Suspicious Node.js script execution
 
Execution
( Stage 1  )
Postinstall hook automatically executes obfuscated setup.cjs dropper (4,572 bytes) during npm install;Microsoft Defender for Endpoint
– Suspicious Node.js process behavior
– Suspicious Node.js script execution  
Execution / Defense evasion 
(Stage 2)
Second-stage payload: Reflective .NET assembly injection: PowerShell downloads DLL, loads via [Reflection.Assembly]::Load(), invokes Extension.SubRoutine.Run2 method to inject payload into cmd.exe process; entire chain is filelessMicrosoft Defender Antivirus
Trojan:JS/NpmSteal.DB!MTB
Trojan:PowerShell/PsExec.DE!MTB

Microsoft Defender for Endpoint
-Process loaded suspicious .NET assembly
-A process was injected with potentially malicious code
-Reflective code loading (Fileless In-Memory Execution)

Microsoft Defender for Cloud
-Possible AI Tools Reconnaissance Detected
-Possible Secret Reconnaissance Detected
-Access to cloud metadata service detected
-Possible Post-Compromise Activity Detected in CICD Runner
PersistenceRegistry Run key created, executing hidden PowerShell that launches protocal.cjs on every user loginMicrosoft Defender for Endpoint
– Anomaly detected in ASEP registry  
Command and controlGET request to hxxps://23.254.164[.]92:8000/update/49890878 and reads the response body as text.Microsoft Defender for Endpoint
– Command-line process communicating with malicious network endpoint  

Microsoft Security Copilot

Security Copilot customers can use the standalone experience to create their own prompts or run the following prebuilt promptbooks to automate incident response or investigation tasks related to this threat:  

  • Incident investigation  
  • Microsoft User analysis  
  • Threat actor profile  
  • Threat Intelligence 360 report based on MDTI article  
  • Vulnerability impact assessment  

Note that some promptbooks require access to plugins for Microsoft products such as Microsoft Defender XDR or Microsoft Sentinel.  

Advanced hunting

The following KQL queries can be used in Microsoft Defender XDR Advanced Hunting to identify potential exposure to this supply chain compromise.

Detect postinstall execution of setup.cjs

DeviceProcessEvents 
 | where Timestamp > ago(7d) 
 | where FileName in ("node", "node.exe") 
 | where ProcessCommandLine has "setup.cjs" 
     or ProcessCommandLine has "easy-day-js" 
|  where ProcessCommandLine has “--no-warnings” 
 | project Timestamp, DeviceName, AccountName, 
     ProcessCommandLine, FolderPath, InitiatingProcessFileName 
 | sort by Timestamp desc 

Outbound connections to C2 infrastructure

DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteIP in ("23.254.164.92", "23.254.164.123")
| project Timestamp, DeviceName, RemoteIP, RemotePort, RemoteUrl,
    InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by Timestamp desc

Indicators of compromise (IOC)

Network indicators

IndicatorTypeDescription
23.254.164.92IP addressPrimary C2 server
23.254.164.123IP addressSecondary C2 address (from deobfuscated strings)
https[:]//23[.]254[.]164[.]92:8000/update/49890878URLPayload download endpoint

File indicators

IndicatorTypeDescription
B122A9873BEDF145AE2A7FD024B5F309007DBB025149F4DC4AC3F7E4F32A36A4SHA256setup.cjs (malicious postinstall dropper)
AE70DD4F6BC0D1C8C2848E4E6B51934626C4818DCB5AF99D080DDBD7DC337185SHA256easy-day-js-1.11.22.tgz (weaponized tarball)
4A8860240E4231C3A74C81949BE655A28E096A7D72F38FBE84E5B37636B98417SHA256easy-day-js-1.11.21.tgz (clean bait tarball)
B73DE25C053C3225A077738A1FCBD9CA6966D7B3CD6F5494A30F0AA0EAE55C7ESHA256mastra-1.13.1.tgz (compromised CLI tarball)
221c45a790dec2a296af57969e1165a16f8f49733aeab64c0bbd768d9943badfSHA256protocol.cjs

Host indicators

IndicatorTypeDescription
$TMPDIR/.pkg_historyFile artifactContains the install path of the compromised package
$TMPDIR /.pkg_logs File artifactContains XOR 0x80 encoded string “easy-day-js”
<homedir>/<random_hex>.jsFile artifactDownloaded second-stage payload

Package indicators

IndicatorTypeDescription
easy-day-jsnpm packageMalicious typosquat of dayjs
sergey2016npm accountPublisher of easy-day-js
ehinderonpm accountCompromised publisher of 140+ Mastra packages

References

Security: mastra@1.13.1 is compromised — malicious postinstall payload via `easy-day-js` dependency · Issue #18046 · mastra-ai/mastra

Microsoft has identified a supply chain attack on the Mastra-AI npm ecosystem, with 80+ packages compromised through npm account takeover. The attacker introduced a phantom dependency into the… | Microsoft Threat Intelligence

This research is provided by Microsoft Defender Security Research, Suriyaraj Natarajan, Sagar Patil, Rajesh Kumar Natarajan, Mahesh Mandava, Arvind Gowda, and with contributions from members of Microsoft Threat Intelligence.

Learn more

For the latest security research from the Microsoft Threat Intelligence community, check out the Microsoft Threat Intelligence Blog.

To get notified about new publications and to join discussions on social media, follow us on LinkedInX (formerly Twitter), and Bluesky.

To hear stories and insights from the Microsoft Threat Intelligence community about the ever-evolving threat landscape, listen to the Microsoft Threat Intelligence podcast.

Review our documentation to learn more about our real-time protection capabilities and see how to enable them within your organization.   

The post From package to postinstall payload: Inside the Mastra npm supply chain compromise appeared first on Microsoft Security Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

New in Cowork – the UI refresh and the cost question everyone’s asking

1 Share

Have you noticed the new Cowork UI in the Microsoft 365 Copilot app? Overnight, the experience got a proper makeover in Frontier — and with it came a small skill that I think is going to matter a lot for everyone right now: /cost.

I of course tested it out first thing this morning. A few things moved around, one model finally showed up on my demo account, and there is a new way to see exactly how many Copilot Credits a task is eating. After last week’s posts on how to write blog posts with Cowork and Cowork hitting general availability, this one is a natural follow-up — and yes, I am going to keep the meta tradition alive and show you what it cost to write this very post. 🤠

Let’s take a closer look.

  1. Cowork is now its own mode – Chat or Cowork
  2. GPT-5.5 is in the list now
  3. Scheduled prompts moved to the left navigation
  4. Customization options
  5. The /cost skill – this is where it gets good
  6. But cost has to be governed – control, visibility, efficiency
  7. New: Cowork has its own section in the Microsoft 365 admin center
  8. So… what did this post cost?
  9. Closing thoughts

Cowork is now its own mode – Chat or Cowork

I have been writing about the Cowork in the Microsoft 365 Copilot app. Well, Cowork has been promoted. It is no longer just an agent you pick from a list — it is now its own mode, right next to Chat. At the top you simply choose Copilot Chat or Cowork, and you are in the full experience.

This is a small UI change with a big signal behind it. It tells you Cowork is not a side feature anymore — it is one of the two main ways you work with Copilot. Chat for the traditional chats you had with Copilot Chat, Cowork for the heavy, multi-step, do-the-actual-work tasks. I like the clarity of it.

Copilot Chat

Copilot Cowork

GPT-5.5 is in the list now

Remember in my GA post I said GPT-5.5 was part of the Frontier lineup but I did not see it on my demo account yet? This morning it was there. 😎

Open the model picker and you now get:

  • Auto – best model for the task
  • Claude Sonnet 4.6 – efficient for everyday tasks
  • Claude Opus 4.8 – for complex, high-stakes work
  • GPT 5.5 – versatile across task types

This is exactly the multi-model choice I keep going on about. You are not locked into one brain. Reach for the efficient model for everyday work, pick Opus 4.8 when the task is genuinely complex, try GPT-5.5 when you want it — and let Auto decide when you would rather not think about it. Model choice is also one of your levers for managing cost per task, which ties straight into the /cost story below.

Scheduled prompts moved to the left navigation

Scheduled prompts now live right in the left navigation — alongside New task and Search. No more digging for them. If you have set up recurring tasks (the “create a weekly status update from my emails every Monday morning” kind of thing), they are now one click away.

Small change, but this is the sort of thing that makes a tool feel like it respects your time. The features you use regularly should be where your eyes already are.

Customization options

There are also new options for plugins and skills under Customize in the navigation. With the partner plugins that landed at GA, being able to tune how they show up and behave is a welcome addition. This is also the place where you can manage your skills.

The /cost skill – this is where it gets good

Now the part I am most excited about. There is a new /cost skill, and it does exactly what you hope: type /cost and Cowork tells you how many Copilot Credits your conversation (task) has used so far.

That sounds simple. It is actually one of the most useful things you can do right now — because the question I hear more than any other is “yes, but what does it cost?” And the honest answer is: it depends entirely on the job. So let’s make it concrete.

Here is a real example. I gave Cowork a genuinely complex task — the kind I would normally never hand to a single tool. It:

  • analyzed an Excel data set and created an Excel KPI summary,
  • built a PowerPoint presentation, a Word document, and an HTML dashboard from that KPI summary,
  • re-styled the PowerPoint with a new template,
  • drafted several emails,
  • and posted a couple of messages to Teams.

One prompt-driven task, six-plus outputs, across Excel, PowerPoint, Word, HTML, Outlook and Teams. This is a textbook heavy task. Running on Claude Opus 4.8/cost told me it used over 1,300 credits — about $13 on PayGo at $0.01 per credit.

Now read that next to the value: How long would it take you to analyze that data, build the Excel summary, make the PowerPoint, write the Word document, design an HTML dashboard, then draft the stakeholder emails and Teams messages? An afternoon? A whole day? As I put it in the GA postwork that took a week now collapses into a morning. A light task is the price of a coffee; a heavy multi-output analysis like this one is the price of a nice lunch — for work that used to take a person an hour to a day. And all that is left for you to do is check the results and edit the drafts before sending them. That is the trade I will take every time.

That is the real story of Cowork’s cost: it is not an expense you weigh on its own, it is a number you put next to the hours — and the kind of work — it just gave back to you. This is AI that actually does the work, end to end, not AI that drafts a suggestion and hands it back to you. And while Cowork is working, you are free to do other work. You don’t have to stare at Cowork and wait – and you should not do that! Instead make use the time – do other work or have a short break you didn’t have time to do before.

But cost has to be governed – control, visibility, efficiency

Here is the other half, and it is just as important: usage-based pricing only works if you govern it. You do not get to enjoy “the price of a nice lunch” if nobody is watching the tab. The good news is Microsoft built the guardrails right into GA, around three themes — and /cost is your front-row seat to one of them.

Visibility is where /cost lives. For the first time you can see, per conversation (task), what a task actually cost — instead of guessing. So here is my tip, and it is the single most useful thing you can do this week: go back through your existing Cowork conversations and run /cost on the kinds of tasks you really do. That turns “I have no idea what this will cost” into a grounded number you can plan around — for yourself, your team, and your whole organization. At the org level this is backed by usage reporting broken down by user, group, and feature, so there is real accountability.

Control is the admin side, and it is off by default — Cowork does not spend a credit until you turn it on. It now has its own section in the Microsoft 365 admin center, where admins create spending policies at company and group level (per-user is coming) to cap spend, alongside scoped billing and usage alerts. And when a user genuinely needs more, they can request additional credits from inside Cowork. Turn it on, set the policy, stay in control.

Efficiency is the lever you pull on every single task: PayGo or P3, and model choice in the picker. Those 1,300 credits ran on Opus 4.8 because the task deserved a frontier model — but a lighter job does not need one. Match the model to the work, and commit to P3 if you already know Cowork is going to be core to how your team works, and the same output costs you less.

Put those three together and the message is simple: the cost is knowable, cappable, and tunable. That is what lets you say yes to usage-based pricing with confidence.

New: Cowork has its own section in the Microsoft 365 admin center

This is fresh, and it directly updates what I showed you in the GA postCowork now has its own section in the Microsoft 365 admin center — and it is where governance actually happens. You can see your Cowork usage there, and the cost management area has been reworked.

Here is the change: instead of the budget tab I walked through last time, you now create a spending policy. And it is a proper guided wizard with five steps. Let me walk you through it, because this is exactly what your admins should set up before July 1.

1. Applies to – name it and choose who it covers. Give the policy a name, then pick the scope. You can apply it to All users (Microsoft recommends having an all-users policy as your default, for when no other policy applies), to Specific groups (security groups — and helpfully, the list is pre-populated with groups that have credit requests), and Specific users is coming soon. So today you govern at company and group level; per-user is on the way — exactly the layered control orgs need.

2. Limits and alerts – cap the spend and get warned early. Choose Don’t limit monthly spending or Limit monthly spending, and set the monthly credit cap. Be clear-eyed about what the cap does: when a policy hits its limit, users assigned to it lose access to agents and services until credits reset on the 1st of next month. There is also an optional per-user monthly budget limit so one person can’t burn the whole pool, and a Define alerts toggle that emails a weekly summary to the recipients you choose when the policy reaches a credit threshold you set. I added myself as the alert recipient — set this up, you will want the heads-up.

3. Agents and services – what the policy governs. Right now the policy applies to Copilot Cowork (Copilot license required) and the Work IQ API. There is also an Allow new services and agents as they become available toggle, so the policy automatically extends to future agents instead of leaving a gap. Other pay-as-you-go services are still managed in classic Billing & usage for now.

4. Billing method – where the credits come from. Credits are billed to the subscription you select; new policies use your organization default by default, and when credits run out, billing switches to pay-as-you-go.

5. Review & create. A clean summary of scope, services, billing method, and your limits and alerts before you commit. Review, create, done.

My tip: do this now, before July 1. Start with an All users policy as your safety net, then layer group-level policies on the teams you expect to lean on Cowork hardest, and turn on alerts so nothing creeps up on you. This is the guardrail that lets you say yes to usage-based pricing with confidence — set the spending policy, and stay in control.

And the clock matters here. Starting July 1, 2026, you need Copilot Credits available to keep using Copilot Cowork (for tenants on the grace period).

This is how it looks, when you go to Consumption page. Tasks run before yesterday are not included, as that number looks roughly like the total I have done only today.

So… what did this post cost?

Keeping the meta tradition going — because the last writing post was “that meta” too 🤠 — I asked /cost what it took to write this article. Research across my own earlier posts, drafting, screenshot placement, the lot.

The answer for the initial draft: 60,8 credits — about $0,61 on PayGo at $0.01 per credit. At the end of writing the blog post I had spent 310,4 credits. Which is about $3,1 on Pay-as-you-Go (PayGo). This included looking up more information, sharing and analyzing screenshots of Admin center, and adding up more text to cost chapters.

Sit that next to the heavy task above: a six-output, cross-app monster ran over 1,300 credits (~$13), while drafting a full blog post came in at around three euros. That is the whole point of paying attention to /cost — tasks are not all priced the same, and once you can see the numbers, you can match the model and the effort to the job. A blog post is a light task. A leadership-ready, multi-format analysis is not.

A blog post written with Cowork, reporting its own cost, in a post about the cost skill. I do like when it loops around like that.🤠

Closing thoughts

Together Cowork as its own mode, GPT-5.5 in the picker, scheduled prompts and plugin & skills customization where you can actually find them, /cost, and a real spending-policy wizard in the admin center — they tell you the experience is maturing fast, and maturing in the right direction: more capable, and more transparent and governable about what it costs you.

Turn on /cost, look back at your real conversations, set your spending policies, and walk into July 1 knowing your numbers instead of guessing them.

Work is changing. Keep an eye on the costs, but don’t block the use: instead apply cost control and governance that fits your organization needs.





Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Software Engineering Principles That Still Hold Up in an Agentic World - Old Lessons Made New

1 Share

The skills problem isn't going anywhere — it's just wearing new clothes. In this episode, I unpack how the lessons we learned decades ago (limiting work in progress, the theory of constraints, test-driven development) are coming roaring back as the fundamentals that will carry you through the agentic shift. The bottleneck has moved, and knowing where it went changes how you should work.

A lot of what we're learning about building with agentic tooling isn't new at all — it's a re-emphasis on lessons software engineers learned twenty years ago, just arriving in a new form. In today's episode, I walk through why the fundamentals are becoming more important than ever, why so many of us feel scattered despite having the most powerful tooling we've ever had, and where the real bottleneck in software delivery has quietly moved. My goal isn't to convince you that your job is now babysitting AI — it's to show you which parts of the work are still squarely yours, and how older principles can make you faster and more confident right now.

  • Limiting Work in Progress Is Back: Just because you can spin up fifty agents doesn't mean you should split your focus across fifty things. Orchestrated fan-outs are powerful, but a human juggling agents across hiring, on-call, and a project all at once still pays the same old context-switching tax — and the quality drops while the speed never improves.
  • Work Deeper, Not Wider: Instead of spreading yourself shallowly across more tickets, run multiple sessions on the same domain. Write a competing or adversarial version that critiques your assumptions, develop better documentation, or capture what you're learning as a reusable skill. Depth beats breadth.
  • The Scattered-Engineer Epidemic: Engineers are burning out faster, not slower. We have the capacity to push more through the pipeline, so we're getting handed (or choosing) more than we can carry. Reducing parallelism often holds your delivery speed steady while dropping your cycle time and raising quality.
  • The Theory of Constraints, Revisited: Treat your software development lifecycle as a pipeline with a bottleneck — and if you can't find one, you've optimized one part too far. Writing code used to be the choke point, so we spent enormous energy de-risking work before it ever reached an engineer.
  • The Bottleneck Has Moved: When production gets cheap, it's no longer worth heavily de-risking upstream — which is why engineers are picking up more experimental, proof-of-concept, discovery work, and product folks are prototyping with these tools too. The new constraint isn't writing the code; it's verifying the agent didn't ship something broken.
  • Verification Scales With Your Effort: The more an agent produces, the bigger the pile of PRs, MRs, and outputs waiting on human review. That backlog is the new bottleneck — and skepticism is creeping in because we're not even sure our tests are sufficient to verify what the agent built.
  • Why TDD Fits This Moment: The honest question isn't "Can I trust the agent?" — it's "What verification loop do I need to build so I can trust it more?" Clear requirements feed a clear testing loop: write the failing test, let the agent write the code to turn it green, and you bridge the gap between requirements gathered and requirements met. It's not as simple as "go write a test," but it's a strong fit for where we are right now.
  • Episode Homework: Go dig into the fundamentals — limiting WIP, the theory of constraints, test-driven development. Find the old lesson that still applies to your workflow today, bring it to your team's flow, and email me about what you discover.

🙏 Today's Episode is Brought To you by: Unblocked

Your coding agents probably have access to your codebase — and maybe your tools and MCPs too — but access doesn't mean context. Agents don't know your architectural decisions, your team's patterns, or why your API is shaped the way it is, so Claude ends up building a new model when it should have changed an existing one, and you're left clawing back bad outputs and burning tokens on correction loops. Unblocked is the smart context layer your agents are missing. Instead of dumping everything into a giant context window, it builds reasoning over shared context — turning code, docs, tickets, and conversations into actionable context so engineers move faster, agents make better plans, write higher quality code, use fewer tokens, and need fewer corrections. If you're running Claude Code, Cursor, or any agentic workflow, go check it out. Free three-week trial at getunblocked.com/developertea.

📮 Ask a Question

If you enjoyed this episode and would like me to discuss a question that you have on the show, drop it over at: developertea.com.

📮 Join the Discord

If you want to be a part of a supportive community of engineers (non-engineers welcome!) working to improve their lives and careers, join us on the Developer Tea Discord community today!

🗞️ Subscribe to The Tea Break

We are developing a brand new newsletter called The Tea Break! You can be the first in line to receive it by entering your email directly over at developertea.com.

🧡 Leave a Review

If you're enjoying the show and want to support the content head over to iTunes and leave a review!





Download audio: https://dts.podtrac.com/redirect.mp3/cdn.simplecast.com/audio/c44db111-b60d-436e-ab63-38c7c3402406/episodes/04d3e337-bdce-4424-b2ef-afe0f43f0406/audio/37fb5035-c3cb-42d8-8f59-b11e7c3437a8/default_tc.mp3?aid=rss_feed&feed=dLRotFGk
Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

The bouba-kiki effect in baby chicks, with Dr. Maria Loconsole

1 Share

1195. This week, we talk to Dr. Maria Loconsole from the University of Padua about her research into the bouba-kiki effect, the near-universal tendency to associate round shapes with "bouba" sounds and spiky shapes with "kiki" sounds. We look at what her experiments with newly hatched chicks reveal about whether this association predates language entirely. 


"Matching sounds to shapes: Evidence of the bouba-kiki effect in naive baby chicks"


🔗 Join the Grammar Girl Patreon.

🔗 Share your familect recording in Speakpipe or by leaving a voicemail at 833-214-GIRL (833-214-4475)

🔗 Watch my LinkedIn Learning writing courses.

🔗 Subscribe to the newsletter.

🔗 Take our advertising survey.

🔗 Get the edited transcript here.

🔗 Get Grammar Girl books.

| HOST: Mignon Fogarty

| Grammar Girl is part of the Quick and Dirty Tips podcast network.


  • Audio Engineer: Dan Feierabend
  • Director of Podcast: Holly Hutchings
  • Advertising Operations Specialist: Morgan Christianson
  • Marketing and Video: Nat Hoopes, Rebekah Sebastian
  • Podcast Associate: Maram Elnagheeb

| Theme music by Catherine Rannus.

| Grammar Girl Social Media: YouTubeTikTokFacebookThreadsInstagramLinkedInMastodonBluesky.


Hosted on Acast. See acast.com/privacy for more information.





Download audio: https://sphinx.acast.com/p/open/s/69c1476c007cdcf83fc0964b/e/6a2c4202252d86e84646338f/media.mp3
Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Keynote: After the AI Hype – What’s Real, and What’s Next - Richard Campbell - 2026

1 Share
From: NDC
Duration: 49:59
Views: 4

This talk was recorded at NDC Copenhagen in Copenhagen, Denmark. #ndccopenhagen #ndcconferences #developer #softwaredeveloper

Attend the next NDC conference near you:
https://ndcconferences.com
https://ndccopenhagen.com/

Subscribe to our YouTube channel and learn every day:
/ @NDC

Follow our Social Media!

https://www.facebook.com/ndcconferences
https://twitter.com/NDC_Conferences
https://www.instagram.com/ndc_conferences/

#ai #ethics #security

Artificial Intelligence dominates the headlines—and it’s clear we’re in the middle of a major hype cycle. But beneath the buzz, genuine innovations are delivering tangible value.

So what’s real, what’s exaggerated, and what’s next? Join Richard Campbell for an insightful look at the current AI surge, why it matters, and where the real success stories are happening today. Explore the opportunities, the challenges, and the eventual end of the hype cycle—so you can separate the promise from the noise and prepare for the future of AI in business and development.

Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Node.js 22.23.0 (LTS)

1 Share
Read the whole story
alvinashcraft
3 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories