FinOps Now Prices the Microsoft 365 Copilot Seat You Forgot
A renewing per-seat subscription is a different kind of cost problem than a cloud bill. A Copilot licence never shows up in a cost dashboard, because it isn’t a cloud resource. It’s a per-person software subscription that renews whether or not the person it was assigned to opened the tool once that month, the same way a forgotten dev account keeps billing long after anyone remembers it exists.
FinOps is the practice of giving engineering, finance, and product teams shared, real-time visibility into cloud cost so spending decisions get made where the usage happens. Connect a Microsoft 365 tenant now, and Cost Reports → AI Spend gains a Seat licences view: seats bought against seats handed out against seats actually used, how recently each person used Copilot, adoption over time, the renewal date, and what the unused seats cost every month. The three numbers, bought, handed out, used, are the whole point. A seat can be purchased and never assigned. It can be assigned and never opened. Either gap is money spent on nothing, and neither gap was visible before.
A Seat Is Treated Like Any Other Discovered Resource
The mechanism reuses the same pipeline every cloud resource already goes through. A seat lands as a discovered resource with its own metric points, and a Microsoft 365 billing provider writes its daily cost into the same cost_records table that AWS, Azure, and GCP costs already live in. There’s no separate, Microsoft-shaped system bolted on beside the real one.
Purchased and assigned counts, plus the renewal date, come from Microsoft’s own subscription endpoints, which need nothing more than read access to the organization’s directory. Per-person activity comes from Microsoft’s own 28-day usage report. Nothing here is inferred or estimated from a proxy signal. It’s read directly from the same APIs Microsoft’s own admin console would use. This works when a tenant grants the read permission the endpoints need. It breaks, by design, into a plain unconnected state rather than a guess, when that permission isn’t there.
What’s Confirmed Unavailable, Stated Plainly
Three things are not in this feature, and the release notes say so directly instead of leaving the gap to be discovered by a confused support ticket later: token counts, per-user cost, and agent inventory are confirmed unavailable from Microsoft at any grain.
| Shown | Confirmed unavailable |
|---|---|
| Seats bought, handed out, used | Token counts per user |
| Last-active date per person | Per-user cost breakdown |
| Adoption over time | Agent inventory |
| Renewal date, unused seat cost | — |
That’s a deliberate line, not a missing feature waiting on a roadmap. A tool that estimated token usage from a proxy signal would look more complete and be less trustworthy, because the estimate would eventually be wrong in a way nobody could catch until it mattered. Saying plainly what a vendor’s API doesn’t expose is the more useful answer, even though it’s the less impressive one.
The Same Tenant Showed 0, Then 1, Then 25 Seats
A tenant connected minutes earlier could show an empty seat panel, then a real number, then a different real number again on the next refresh. The cause was a cache each server replica held independently, each up to 30 minutes stale, with no way to force an early refresh. Whichever replica happened to answer a given request determined whether the answer was current or half an hour old. A newly connected tenant hadn’t existed long enough for every replica to have caught up.
The fix isn’t to remove the cache. A populated estate still reads from it, at no extra cost. Only an empty result gets retried once against fresh data before it’s shown, which closes the specific failure (a genuinely connected tenant reporting zero) without giving up the cache’s benefit everywhere else. A related bug sat in the internal support console: seat-holder names were permanently withheld behind a visibility check that could never actually pass. Staff saw every name blanked out with a message telling them to reload in a few minutes. Reloading was never going to fix it, because the check itself was broken, not stale.
The Confirmation Dialog Named the Tenant by Its Database Key
Microsoft 365 was the only connected provider missing from the list that turns an internal identifier into the name a person actually recognizes. The gap surfaced at the worst possible moment: the delete-confirmation dialog on the Cloud Accounts page. It asked to remove a tenant using its raw internal provider key rather than its real name. The same missing entry meant Microsoft 365 tenants were left out of the provider filter entirely, so finding one on a long list meant scrolling past everything else first.
Adoption over time carries its own small but deliberate design choice: a day Microsoft’s usage report published nothing for is treated as absent, not as zero. That distinction matters because a reporting gap and a real drop to zero adoption look identical on a chart that doesn’t separate them, and only one of those two things is a story worth telling a finance team.
