On Control and above, Cirrova can authenticate your members through Microsoft Entra ID instead of a password we hold. That is the right thing to do. Your identity provider becomes the single place joiners, movers and leavers are handled, and Cirrova never sees a credential at all.
But handing authentication to Entra only moves the decision. It does not sharpen it. An SSO sign-in to Cirrova is governed by whatever your tenant already does for every other application — no more, no less. If your baseline is a password and nothing else, then a password and nothing else is what now stands in front of a complete view of your Azure spend.
Conditional Access is where that gets fixed. This is the policy we would write, the order we would turn it on in, and the two places people accidentally leave a way around it.
The exemption that catches people out
Cirrova has its own multi-factor control — Organisation Settings → Users → Authentication policy → Enforce two-factor authentication. It requires every local member to configure an authenticator app on their next sign-in.
It deliberately does not apply to SSO-only members. For those accounts MFA belongs to Entra, and demanding a second factor in two places is an efficient way to lock somebody out of one of them. That is the correct design, and it has a consequence worth saying out loud.
What you will need
- Cirrova on Control, Enterprise or Partner. Entra ID SSO is not available on Core — see pricing.
- Microsoft Entra ID P1 for Conditional Access at all, and P2 for the risk-based conditions further down. P1 is bundled in Microsoft 365 E3 and E5, Enterprise Mobility + Security, and Business Premium, so you may already hold it without having gone looking.
- Security Defaults turned off. Conditional Access and Security Defaults are mutually exclusive. Be honest with yourself about the trade: Security Defaults enforce MFA for everybody, and switching them off removes that protection everywhere until your own policies replace it. Do both in the same sitting, not on either side of a weekend.
- Conditional Access Administrator, Security Administrator or Global Administrator in Entra.
- At least one emergency access account, excluded from every policy you write. Microsoft has recommended this for years and it remains the cheapest available insurance against a policy that turns out to be broader than you intended.
Step 1: make sure Cirrova exists in your directory
Cirrova is registered in Entra as a shared multi-tenant application. You do not create an app registration of your own, and there is nothing to configure on your side beyond telling Cirrova your Tenant ID. The flip side is that the service principal — the object a Conditional Access policy actually targets — does not exist in your directory until somebody has consented to the app.
So if you go looking for Cirrova in the target-resources picker before anyone has ever signed in, you will not find it, and nothing is broken. Grant admin consent first. Cirrova builds the URL for you: Organisation Settings → Single sign-on → Admin consent URL. Open it as a Global Administrator and approve. The enterprise application appears in your tenant immediately.
Then confirm you are looking at the right object. In the Entra admin centre go to Entra ID → Enterprise applications, clear the default Application type filter, and search for:
- Name —
Cirrova - Azure Cost Management - Application ID —
db8f9f1f-688f-4657-8da4-d66ef1ad9af3
Match on the Application ID rather than the name. Names in a tenant full of enterprise applications can be similar; that ID is ours and only ours.
Step 2: the baseline policy
Start with one policy that does exactly one thing — require multi-factor authentication for Cirrova. The interesting conditions can come later, once you know the simple one behaves.
- Entra admin centre → Protection → Conditional Access → Policies → New policy. Give it a name a colleague can read in two years' time:
CA — Cirrova — Require MFA. - Users → Include All users, then Exclude your emergency access group. If you would rather start narrow, include a pilot group instead and widen once it is proven.
- Target resources (labelled Cloud apps in older tenants) → Include → Select resources → paste
db8f9f1f-688f-4657-8da4-d66ef1ad9af3into the search box and pick Cirrova - Azure Cost Management. - Conditions → leave Client apps at the default. Cirrova is a browser application over OpenID Connect; there is no legacy authentication path here to carve out.
- Grant → Grant access → Require multifactor authentication.
- Enable policy → Report-only. Not On. Not yet.
- Create.
Step 3: report-only first, then on
Report-only evaluates the policy against every real sign-in and records what would have happened without actually doing it. It is the difference between discovering on a quiet Tuesday that you would have locked out your finance director, and discovering it at 4pm on the Friday of month-end close.
Two ways to read the results:
- What If — Protection → Conditional Access → What If. Choose a user, choose Cirrova as the resource, run it. An immediate sanity check with nobody waiting on you.
- Sign-in logs — Monitoring → Sign-in logs, filtered by application to Cirrova - Azure Cost Management. Open any entry and read its Conditional Access tab: every policy evaluated, and how each one resolved. Report-only policies show as would have succeeded or would have failed.
Leave it running for a working week if you can. That is long enough to catch the person who only opens Cirrova at month end and would otherwise meet the new policy as a surprise. When the report-only results have become boring, set the policy to On.
Going further
The baseline is a floor, not a finished job. Add whichever of these matches how your organisation actually works — each is a separate policy, and each starts in report-only for the same reason the first one did.
Require a managed device
Grant → Require device to be marked as compliant (Intune) or Require Microsoft Entra hybrid joined device, joined with OR if you run a mix of both. This is the control that turns "somebody with the password and a phone" into "somebody at a company laptop", which for a complete view of your Azure estate is usually the honest requirement. Budget time for the exceptions before you switch it on: contractors, BYOD, and the one person on a Mac.
Require phishing-resistant MFA for owners
Organisation owners in Cirrova can invite and remove members, add and delete tenants, configure SSO, and change billing and licence settings. It is reasonable to hold that group to a higher bar than everyone else: a second policy, scoped to a group, with Grant → Require authentication strength → Phishing-resistant MFA — FIDO2 security keys, passkeys, Windows Hello for Business, or certificate-based authentication.
One thing to be clear about. Conditional Access has no idea what a Cirrova role is; it can only target Entra users and groups. So this policy rests on an Entra group that mirrors your Cirrova owners, and that mirror is maintained by hand. Put it in the same calendar reminder as your access recertification, because it will drift — usually harmlessly, with somebody keeping the stronger requirement after they stopped being an owner, right up until it drifts the other way.
Location
Named locations let you require MFA from anywhere outside your offices, or block sign-ins from countries you do not operate in. Genuinely useful, as long as you are honest about what it is: IP-based location is a signal, not a boundary, and a VPN defeats it in one click. Use it to raise friction and to put something interesting in the logs — not as the thing standing between an attacker and your data.
Risk-based conditions
With Entra ID P2 you can bring Identity Protection into the policy: require MFA at medium-or-above sign-in risk, require a secure password change on elevated user risk. This is the closest thing on the list to a control that responds to something actually happening, rather than to a static rule you wrote months ago and have not revisited since. If you hold the licence, it is the highest-value addition here.
Session controls
Sign-in frequency and disabling persistent browser session are the obvious pairing for unmanaged devices: a session that ends, rather than one that lives in a browser profile indefinitely.
Test this one rather than assuming it. Continuous access evaluation — the mechanism that lets Entra revoke a session mid-flight — is supported by Microsoft's own services and not universally by third-party applications, so a sign-in frequency setting may only bite when a token is next renewed rather than at the moment you would expect. Set it, then watch a real session in the sign-in logs and see when re-authentication actually fires in your tenant.
Close the side door
A Conditional Access policy on the Cirrova application governs Entra sign-ins to Cirrova. It has nothing whatsoever to say about a member who signs in with a Cirrova password instead.
Cirrova lets both coexist on purpose — an organisation can hold a mix of regular accounts, SSO-capable accounts and SSO-only accounts, which is what makes a phased rollout possible in the first place. But it does mean your policy is only as strong as the absence of an alternative. Two settings finish the job:
- Tick SSO-only on every member. It is set when adding somebody and can be changed afterwards. An SSO-only account cannot sign in with a password at all, which is precisely the point.
- Leave Enforce two-factor authentication on, to cover whatever local accounts remain during and after the transition.
Then keep one deliberate exception: a single organisation owner account that is not SSO-only, carrying a long random password and its own Cirrova authenticator enrolment, both held in your password manager. If a Conditional Access policy turns out to be wrong, or Entra has a bad morning, that account is how you get back into Cirrova to fix it. Write down who holds it and review it on a schedule — an emergency account nobody ever checks is just an old account.
What Conditional Access does not cover
Worth being precise about the boundary, because "we have Conditional Access" turns quietly into "we're covered".
- API keys. The Cirrova REST API authenticates with a key in an
X-API-Keyheader, not an Entra token. Conditional Access never sees an API request — no MFA, no device check, no location condition. Treat keys as the standing credentials they are: create them with an expiry, keep them in a secrets manager, and delete them from Organisation Settings → API keys the moment one is redundant or might have leaked. Revocation takes effect immediately. - Local accounts. Covered above, and the most common way a good policy ends up decorative.
- The Azure connection. The service principal or managed identity that lets Cirrova read your cost data is a workload identity, not a user. It never signs in interactively, and a standard Conditional Access policy does not apply to it. (Conditional Access for workload identities exists, but it is separately licensed and a different conversation.) What protects it is least privilege — read-only
Cost Management Reader,ReaderandMonitoring Readerat subscription scope — and credential hygiene. - The Cirrova session itself. Conditional Access governs the moment of authentication. What a member can see and do once they are inside is Cirrova's own access model: organisation roles, plus a per-tenant role for each connected Azure tenant. Both need to be right, and neither substitutes for the other.
Checking it still works
Two logs, answering two different questions.
Entra sign-in logs tell you what happened at the door. Filter by application, open an entry, read the Conditional Access tab. When a member reports being blocked, the entry names the policy that did it — and two error codes cover most of what you will see: AADSTS53003 (blocked by a Conditional Access policy) and AADSTS53000 (the device is not in the required state, which means your compliance policy).
Cirrova's Activity log tells you what happened inside. Invitations, removals, role changes, tenant access grants, SSO configuration changes and MFA policy changes are all recorded with the actor, the target, the change and a timestamp. If somebody flips a member back off SSO-only, that is where it surfaces — which makes it the log that tells you whether your Conditional Access policy still covers everybody it is meant to.
The policy as code
If you manage Conditional Access through Microsoft Graph rather than the portal, here is the same baseline policy. Note the state: enabledForReportingButNotEnforced is report-only, matching the walkthrough above. Change it to enabled once the results have gone quiet.
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess","Application.Read.All"
$params = @{
displayName = "CA - Cirrova - Require MFA"
state = "enabledForReportingButNotEnforced"
conditions = @{
users = @{
includeUsers = @("All")
excludeGroups = @("<object-id-of-your-emergency-access-group>")
}
applications = @{
includeApplications = @("db8f9f1f-688f-4657-8da4-d66ef1ad9af3")
}
clientAppTypes = @("all")
}
grantControls = @{
operator = "OR"
builtInControls = @("mfa")
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params Half an hour, once
The baseline policy takes about ten minutes to write, a week to observe, and one click to enforce. Moving your members to SSO-only takes about as long again. That is roughly half an hour of work, once, to close the gap between "we use SSO" and "we require multi-factor authentication to see our Azure spend" — which are not the same sentence, however much they sound alike.
And if SSO is not turned on yet, our access control guide covers the setup. It is a five-minute job: find your Tenant ID, paste it in, save.