<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>ACloud.Solutions notes</title>
  <subtitle>Azure cost and security, Microsoft 365, automation and ISO 27001.</subtitle>
  <link href="https://acloud.solutions/notes/feed.xml" rel="self"/>
  <link href="https://acloud.solutions/notes/"/>
  <id>https://acloud.solutions/notes/</id>
  <updated>2026-09-08T11:15:48Z</updated>
  <author><name>ACloud.Solutions</name></author>
  <entry>
    <title>AI tools for security teams of one: what to hand over and what to keep</title>
    <link href="https://acloud.solutions/notes/ai-in-the-security-team-of-one/"/>
    <id>https://acloud.solutions/notes/ai-in-the-security-team-of-one/</id>
    <updated>2026-09-01T09:00:00Z</updated>
    <published>2026-09-01T09:00:00Z</published>
    <category term="AI and regulation"/>
    <summary>AI tools for security teams help with first drafts and KQL, and fail at anything that must be true about your environment. Where the line sits.</summary>
    <content type="html">&lt;p&gt;The model produced a Sentinel rule in nine seconds. It was well-formed KQL, it
referenced a table, it had a sensible name and a MITRE tactic. It also queried a
table that does not exist in the workspace, and it would have sat in the portal
looking exactly like the working rules and never firing.&lt;/p&gt;
&lt;p&gt;That is the shape of the whole question. Ai tools for security teams are
genuinely useful for things where being roughly right is a good starting point,
and actively dangerous for anything that has to be true about your specific
environment, because the failure mode is a confident, plausible, well-formatted
answer.&lt;/p&gt;
&lt;h2&gt;Where ai tools for security teams actually earn their keep&lt;/h2&gt;
&lt;p&gt;Four categories, and the common property is that you can verify the output
cheaply.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First drafts of documents.&lt;/strong&gt; Policies, procedures, incident report structures,
questionnaire answers you then correct. A first draft you rewrite is faster than
a blank page, and the rewriting is where your knowledge gets added. The risk is
adopting the draft rather than editing it, which produces a policy asserting
practices you do not have, which is
&lt;a href=&quot;/notes/iso-27001-policies-people-read&quot;&gt;a finding you wrote yourself&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Query syntax.&lt;/strong&gt; KQL, PowerShell, Graph filters, Resource Graph. This is a good
use because the output is immediately testable: run it, see whether it returns
what you expected. The model is helping with syntax rather than with facts about
your estate, and syntax it knows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summarising things you already have.&lt;/strong&gt; A long alert, a vendor&#x27;s SOC 2 report,
a supplier&#x27;s terms. Summarising a document you can check beats reading forty
pages, provided you check the parts that matter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rephrasing.&lt;/strong&gt; Turning a technical finding into something a director will read,
or an answer you already wrote into the wording a questionnaire wants. Nothing
factual is being generated.&lt;/p&gt;
&lt;h2&gt;Where it fails, specifically&lt;/h2&gt;
&lt;p&gt;Not vaguely, because the specific failures are predictable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anything about your environment.&lt;/strong&gt; Table names, policy names, group names,
which subscriptions exist, what your retention is set to. The model does not
know and will produce something plausible. The Sentinel rule at the top of this
note is the canonical example, and it is why
&lt;a href=&quot;/notes/sentinel-analytics-rules-validation&quot;&gt;validation before deployment&lt;/a&gt;
matters more once you start generating rules quickly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Current facts about products and regulation.&lt;/strong&gt; Cloud services change monthly
and regulation changes by amendment. A confident statement about a licensing
requirement, a retention default or a compliance deadline is exactly the kind of
thing to verify at source. The EU AI Act timeline has already moved once by
amendment, which is a good illustration: a model trained before that change
would state the old dates with complete confidence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anything where being 90 percent right is worthless.&lt;/strong&gt; A policy that is mostly
right is fine, because you edit it. A firewall rule that is mostly right is not.
A questionnaire answer that is mostly right is a contractual representation
that is partly false.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Judgement about your risks.&lt;/strong&gt; A model can list generic risks for a SaaS
company. It cannot know which of them matter to you, what your contracts commit
you to, or what your board will accept, which is the entire content of
&lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;a risk assessment&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Rules for what goes in the window&lt;/h2&gt;
&lt;p&gt;The practical question people avoid: can you paste logs into a chatbot.&lt;/p&gt;
&lt;p&gt;The honest answer is that it depends on the tool, the contract behind it and what
is in the logs, and that most people have not checked any of the three.&lt;/p&gt;
&lt;p&gt;Four rules that survive scrutiny:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Know whether inputs are retained or used for training.&lt;/strong&gt; This is a
configurable setting on most business offerings and a contractual term. It is
also the single question a customer or an auditor will ask, so find out and write
it down. Consumer accounts and business accounts frequently differ.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No customer personal data, by default.&lt;/strong&gt; If a log contains user identifiers,
email addresses or content, it is personal data and pasting it into a
third-party service is a processing decision with a legal basis and, frequently,
an
&lt;a href=&quot;https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/international-transfers/&quot;&gt;international transfer&lt;/a&gt;
question behind it. That does not make it impossible, it makes it something to decide
deliberately rather than at the point of debugging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No secrets, ever.&lt;/strong&gt; Keys, tokens, connection strings, certificates. Obvious,
and it happens constantly because the fastest way to get help with a
configuration is to paste the configuration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Redact before pasting, and make it easy.&lt;/strong&gt; If sanitising a log takes five
minutes, nobody does it under pressure. If there is a script that strips
identifiers, people use it. The tooling determines the behaviour more than the
policy does.&lt;/p&gt;
&lt;p&gt;Then record the decision. Which tools are approved, on what account type, for
what data. That record is
&lt;a href=&quot;/notes/ai-system-inventory&quot;&gt;an entry in the AI inventory&lt;/a&gt; and it is the answer
to the questionnaire question about internal AI use, which arrives eventually.&lt;/p&gt;
&lt;h2&gt;The audit trail problem&lt;/h2&gt;
&lt;p&gt;A harder question that gets less attention. If a model drafted your policy,
suggested your risk scoring, or produced the detection logic, what does that mean
for the evidence.&lt;/p&gt;
&lt;p&gt;The reasonable position: the artefact is yours because you reviewed and approved
it, and the review is the control. What matters is that a competent person
checked it, and that they could defend it if asked. An auditor is unlikely to
ask what tool produced a draft. They are certain to ask who approved it and
whether that person understands it.&lt;/p&gt;
&lt;p&gt;Which sets a clear line. If you cannot explain why a detection rule is written
the way it is, or why a risk is scored as it is, you have not reviewed it, you
have accepted it. That is fine for prose and not fine for anything you will be
asked to defend.&lt;/p&gt;
&lt;h2&gt;The honest summary&lt;/h2&gt;
&lt;p&gt;These tools have made the documentation half of a one-person security function
materially faster, which matters because documentation was the part that got
deferred. They have not made the judgement half faster at all, and they
introduce a new failure mode where a confident answer about your own environment
is wrong in a way that looks right.&lt;/p&gt;
&lt;p&gt;So the split that works: hand over the writing, keep the deciding. Verify
anything that claims to be a fact about your estate, and verify anything that
claims to be a current fact about a product or a regulation, because both change
and the model&#x27;s confidence does not vary with its accuracy.&lt;/p&gt;
&lt;p&gt;The rest of &lt;a href=&quot;/notes/ai-regulation/&quot;&gt;the AI regulation notes&lt;/a&gt; cover the
obligations rather than the tooling, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; is the option where the
judgement half is what you are short of.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 evidence automation: exported in February, asked for in March</title>
    <link href="https://acloud.solutions/notes/audit-evidence-automation/"/>
    <id>https://acloud.solutions/notes/audit-evidence-automation/</id>
    <updated>2026-08-25T09:00:00Z</updated>
    <published>2026-08-25T09:00:00Z</published>
    <category term="Automation"/>
    <summary>ISO 27001 evidence automation means the export already exists when the auditor asks. What to schedule, where to store it, and what cannot be automated.</summary>
    <content type="html">&lt;p&gt;The auditor asks for evidence that access reviews happened quarterly. It is
March. The reviews did happen, in the sense that somebody looked at the access
list and thought about it, and there is no record of any of them.&lt;/p&gt;
&lt;p&gt;So the next two days go on reconstructing what can be reconstructed and being
honest about the rest. This is the most avoidable category of audit finding
there is, because the evidence existed at the time and nobody captured it.&lt;/p&gt;
&lt;h2&gt;What iso 27001 evidence automation can and cannot do&lt;/h2&gt;
&lt;p&gt;Being clear about this first, because the pitch for compliance tooling
frequently is not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A script can produce the artefact.&lt;/strong&gt; A dated export of who has which role, of
MFA registration status, of device compliance, of backup job outcomes. These are
queries against systems that already hold the answer, and running them on a
schedule and keeping the output is genuinely most of the evidence burden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A script cannot make the decision.&lt;/strong&gt; An access review is not a list of who has
access. It is somebody looking at that list and deciding each entry should
continue, with their name against the decision. The export is the input to the
review, not the review.&lt;/p&gt;
&lt;p&gt;That distinction is where automated compliance platforms are oversold and where
they are genuinely useful. They will collect the evidence. They will not do the
thinking, and an auditor asking &quot;who reviewed this and what did they conclude&quot;
is asking about the thinking.&lt;/p&gt;
&lt;p&gt;So the target is not a fully automated evidence pack. It is that every recurring
artefact exists, dated, without anybody remembering to produce it, so the human
effort goes entirely on the decisions.&lt;/p&gt;
&lt;h2&gt;What is worth scheduling&lt;/h2&gt;
&lt;p&gt;Ranked by how much manual effort it removes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Access lists.&lt;/strong&gt; Azure role assignments, Entra role assignments and eligible
roles, group memberships for anything privileged, guest accounts with what they
can reach. Monthly. This is the highest-value export because the underlying data
changes constantly and reconstructing a past state is impossible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MFA and authentication method coverage.&lt;/strong&gt; Per user, monthly. Answers a
question that appears in almost every customer questionnaire as well as in the
audit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Device compliance status.&lt;/strong&gt; Per device, with the policy applied. Monthly.
Pairs with &lt;a href=&quot;/notes/intune-configuration-as-code-drift&quot;&gt;Intune configuration exports&lt;/a&gt;,
which cover the configuration side while this covers the outcome side.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Backup and restore outcomes.&lt;/strong&gt; Job status is easy. Restore &lt;em&gt;tests&lt;/em&gt; are the
evidence that matters and cannot be automated into existence, only recorded.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Patch and vulnerability status.&lt;/strong&gt; A point-in-time export monthly is worth more
than a live dashboard, because the auditor&#x27;s question is about a period rather
than about today.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certificate and credential expiry.&lt;/strong&gt; Monthly, from
&lt;a href=&quot;/notes/expiring-credentials-app-registrations&quot;&gt;the credential note&lt;/a&gt;. Doubles as
operational monitoring.&lt;/p&gt;
&lt;h2&gt;Where to put it&lt;/h2&gt;
&lt;p&gt;Three properties matter, and the ordering is deliberate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It has to be dated by the system rather than by the filename.&lt;/strong&gt; A file called
&lt;code&gt;access-review-q1.xlsx&lt;/code&gt; proves nothing about when it was produced. Storage with
immutable timestamps, or a repository where the commit carries the date, does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It has to survive the person.&lt;/strong&gt; Not a folder on your laptop, and not a
personal OneDrive. A document library or a storage account with a retention
policy, owned by the company.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It has to be retained longer than the audit cycle.&lt;/strong&gt; Surveillance audits
sample the period since the last one, so anything with a retention shorter than
about eighteen months will have aged out of the window you get asked about.&lt;/p&gt;
&lt;p&gt;A storage account with a lifecycle policy and immutability, or a repository
with one commit per export, both work. The repository option has a side benefit:
a diff between months shows what changed, which turns an evidence archive into a
drift report for free.&lt;/p&gt;
&lt;h2&gt;The naming that saves you two days&lt;/h2&gt;
&lt;p&gt;Name exports so a human can find one under time pressure. Control reference,
artefact, date:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A-5-18_azure-role-assignments_2026-05-01.csv
A-5-18_entra-eligible-roles_2026-05-01.csv
A-8-5_mfa-registration_2026-05-01.csv
A-8-8_vulnerability-status_2026-05-01.csv
A-8-13_backup-job-outcomes_2026-05-01.csv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The control reference in the filename is what turns &quot;we have the evidence
somewhere&quot; into handing over a folder. When an auditor asks about a specific
control, you filter by prefix. Without it you are opening files to find out what
they are, in a meeting, which is where the two days go.&lt;/p&gt;
&lt;h2&gt;Retention, and the thing people get backwards&lt;/h2&gt;
&lt;p&gt;An evidence archive has a retention requirement that runs in the opposite
direction to most data policies, and it catches people out.&lt;/p&gt;
&lt;p&gt;Ordinary data retention is about deleting things you no longer need, and the
instinct from GDPR work is to minimise. The ICO&#x27;s
&lt;a href=&quot;https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/individual-rights/individual-rights/right-to-erasure/&quot;&gt;guidance on storage limitation&lt;/a&gt;
is about personal data held without a continuing purpose, and an evidence
archive does have a continuing purpose, which is demonstrating that controls
operated.&lt;/p&gt;
&lt;p&gt;The tension is real where the evidence contains personal data, and access lists
and MFA status both do. Two things resolve it in practice. Export the minimum
identifying detail needed for the evidence to mean anything, which is usually a
user principal name rather than a full profile. And state the retention period
and its purpose in your own retention schedule, so holding it is a documented
decision rather than an oversight.&lt;/p&gt;
&lt;p&gt;What does not work is deciding at audit time. Either you have eighteen months of
dated exports or you do not, and a policy that quietly deleted them at twelve
months is a worse conversation than not having automated it at all, because the
gap is visible and dated.&lt;/p&gt;
&lt;h2&gt;The part that still needs a person&lt;/h2&gt;
&lt;p&gt;For each export, somebody has to look and record what they concluded. That
record is short and it is the thing being audited:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Access review, Azure role assignments, 2026-05-01
Reviewed by: [name], [date]
Assignments reviewed: 34
Removed: 2 (orphaned, deleted identities)
Retained with justification: 1 (external contractor, integration support,
  reviewed again 2026-08-01)
No other changes required.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Four lines and a date. That is what distinguishes a review from an export, and
it is what was missing in the opening paragraph. Automating the export makes
producing this take five minutes instead of an afternoon, which is the actual
reason the reviews start happening reliably.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;This is the operational half of what &lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers, and the
evidence question is the one that separates companies that pass Stage 2 from
companies that have a good ISMS on paper. The controls are usually fine. Proving
they operated over a period is the work.&lt;/p&gt;
&lt;p&gt;Scheduling it properly means it has to fail loudly, per
&lt;a href=&quot;/notes/powershell-scripts-exit-codes-logging&quot;&gt;the exit code note&lt;/a&gt;. An evidence
job that silently stops producing exports leaves a gap in exactly the period you
will be asked about, and you will not discover it until the audit.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure Advisor recommendations need triage rather than obedience</title>
    <link href="https://acloud.solutions/notes/azure-advisor-recommendations-reality/"/>
    <id>https://acloud.solutions/notes/azure-advisor-recommendations-reality/</id>
    <updated>2026-08-18T09:00:00Z</updated>
    <published>2026-08-18T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>Azure Advisor recommendations are useful and frequently wrong for small estates. Which ones to act on, which to ignore, and why rightsizing misleads.</summary>
    <content type="html">&lt;p&gt;Advisor has produced 34 recommendations. Fourteen are cost. One of them suggests
buying a three year reserved instance for a virtual machine you were planning to
delete next month, which would be an expensive way to take your own advice.&lt;/p&gt;
&lt;p&gt;Azure Advisor recommendations get treated in one of two unhelpful ways. Either
the list becomes a target and somebody works through it top to bottom, or it
gets dismissed after the third bad suggestion and never opened again. Both are
understandable and both waste it, because the mix of genuinely useful and
confidently wrong is high enough that the only sensible approach is triage.&lt;/p&gt;
&lt;h2&gt;Where azure advisor recommendations are reliable&lt;/h2&gt;
&lt;p&gt;Advisor is at its best where the answer does not depend on anything it cannot
see.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reliability and resiliency findings.&lt;/strong&gt; No redundancy on a storage account, a
single instance where an availability set was intended, backups not configured.
These are statements about configuration, and configuration is something Advisor
can read completely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Security findings&lt;/strong&gt;, which are mostly a view onto Defender for Cloud. Same
reasoning: it is reporting a setting rather than inferring an intention.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service retirements and deprecations.&lt;/strong&gt; Genuinely valuable, and the category
people most often miss because they filter to cost. An API version going away or
an extension reaching end of support is a real deadline with a real date, and
Advisor is a reasonable place to find out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Operational excellence items&lt;/strong&gt; such as missing diagnostic settings. Dull,
correct, and quick.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/advisor/advisor-overview&quot;&gt;Advisor documentation&lt;/a&gt;
sets out the five categories and what feeds each one, which is worth reading
once because knowing the data source tells you how much to trust the output.&lt;/p&gt;
&lt;h2&gt;Where it misleads on a small estate&lt;/h2&gt;
&lt;p&gt;The cost category is the problem, and specifically two kinds of recommendation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rightsizing based on averages.&lt;/strong&gt; Advisor watches CPU and network over a
lookback window and suggests a smaller SKU when utilisation is low. The logic is
sound and the failure is in what an average hides. A machine that sits at 4
percent CPU for 29 days and pins at 95 percent during a month-end batch run has
a low average and a hard requirement. Downsize it and you find out on the last
working day of the month, which is the worst available time.&lt;/p&gt;
&lt;p&gt;Advisor does not know that the batch job exists, or that the machine was sized
for a load test, or that it is deliberately oversized because resizing it
requires a change window nobody wants to book.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reservation and savings plan suggestions.&lt;/strong&gt; These assume the workload
continues. On a mature estate that is a reasonable assumption. On a small estate
mid-cleanup it is exactly wrong, because the machines with the steadiest usage
patterns are frequently the legacy ones you are trying to retire. A three year
commitment on a VM that appears in your decommissioning plan is a way of paying
in advance for something you intend to stop doing.&lt;/p&gt;
&lt;p&gt;The order matters here more than the recommendation does. Delete first, then
commit. Advisor cannot know which order you are in.&lt;/p&gt;
&lt;h2&gt;The recommendation it cannot make&lt;/h2&gt;
&lt;p&gt;Worth noticing what is absent. Advisor will tell you a virtual machine is
underutilised. It will not tell you that the machine has no owner, sits in a
resource group called &lt;code&gt;rg-poc-2022&lt;/code&gt;, and has had no inbound network traffic
other than monitoring for eleven months.&lt;/p&gt;
&lt;p&gt;That is because Advisor is answering &quot;is this correctly sized&quot; while the
question you have is &quot;should this exist at all&quot;. Those produce different
actions, and the second one saves considerably more money. Nothing in Advisor
covers unattached disks, unassociated public IP addresses, snapshots whose
source disk was deleted, or empty App Service plans, which is the entire subject
of &lt;a href=&quot;/notes/orphaned-azure-resources&quot;&gt;the orphaned resources note&lt;/a&gt; and typically
where the first real savings in a small estate are found.&lt;/p&gt;
&lt;p&gt;So Advisor is a check on the things you are keeping. It is not an inventory of
the things you have forgotten.&lt;/p&gt;
&lt;h2&gt;Triaging the list&lt;/h2&gt;
&lt;p&gt;What works, on a list of 30 or so, in about twenty minutes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read the retirement and deprecation items first&lt;/strong&gt; and put dates in a calendar.
These are the only ones with a deadline attached and they are the ones a quarterly
skim will miss.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Take the reliability and security items at face value&lt;/strong&gt; and fix or dismiss
them individually. If you dismiss one, use the built-in dismissal with a reason
rather than mentally ignoring it, so the list stays meaningful next month.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Treat every rightsizing suggestion as a question&lt;/strong&gt;, not an instruction. The
question is: what is the peak, and what happens at the peak. Check the maximum
rather than the average over the same window Advisor used. If maximum utilisation
is also low, the machine is a candidate for deletion rather than resizing, which
is a better outcome than Advisor proposed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Park reservation advice until the cleanup is finished.&lt;/strong&gt; Then revisit it
properly, because at that point the assumption it rests on is true and the
savings are real.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dismiss with a reason.&lt;/strong&gt; An Advisor list nobody has curated is noise within two
quarters, and the dismissal reason is the only thing that stops you re-litigating
the same fourteen items every time somebody new looks at the portal.&lt;/p&gt;
&lt;h2&gt;Using it alongside your own checks&lt;/h2&gt;
&lt;p&gt;The two are complementary rather than competing, and they answer different
questions.&lt;/p&gt;
&lt;p&gt;Advisor is the better source for anything that depends on Microsoft&#x27;s roadmap or
on Defender&#x27;s signals. Your own inventory is the better source for anything that
depends on knowing what the business is doing, because that context does not
exist in any telemetry Advisor can read.&lt;/p&gt;
&lt;p&gt;The practical arrangement: run your own orphan and idle sweeps to decide what to
delete, act on those first, then use Advisor to right-size and commit on what
remains. Doing it in the other order means paying to optimise things you were
about to throw away.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt; covers the inventory half of
that, and &lt;a href=&quot;/notes/azure-cost-report-for-finance&quot;&gt;the note on reporting findings&lt;/a&gt;
covers presenting the result in a way that survives a finance meeting.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Read only Azure scripts: why these tools never write to Azure</title>
    <link href="https://acloud.solutions/notes/read-only-by-default/"/>
    <id>https://acloud.solutions/notes/read-only-by-default/</id>
    <updated>2026-08-11T09:00:00Z</updated>
    <published>2026-08-11T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>Read only Azure scripts can run on day one of an engagement. Why blast radius, consultant trust and failing loudly all point the same direction.</summary>
    <content type="html">&lt;p&gt;A client gives you access to a subscription on a Tuesday. You have not seen it
before. There are four hundred resources, two of which are named in a way that
suggests production, and nobody available this week can tell you which.&lt;/p&gt;
&lt;p&gt;That is the situation these tools were designed around, and it settles the
design question immediately. Read only azure scripts can run on that Tuesday.
Anything that writes cannot, because writing requires knowing what you are
touching, and knowing what you are touching is the thing you do not yet have.&lt;/p&gt;
&lt;h2&gt;Read only azure scripts and blast radius, the boring reason&lt;/h2&gt;
&lt;p&gt;A script that can delete resources has a worst case involving somebody&#x27;s
production data. A script that reads has a worst case involving an API rate
limit.&lt;/p&gt;
&lt;p&gt;That asymmetry does not go away with careful coding. Every safety mechanism you
add to a destructive script is another thing that can be wrong: a &lt;code&gt;-WhatIf&lt;/code&gt; that
somebody omits, a confirmation prompt that gets &lt;code&gt;-Confirm:$false&lt;/code&gt; in a scheduled
job, an exclusion list that does not match what the author assumed. The safest
delete logic is the delete logic that is not there.&lt;/p&gt;
&lt;p&gt;So the tools produce a list and a cost, and a human deletes things. That is
slower and it is the correct division of labour: the script is good at
enumerating four hundred resources and pricing them, and terrible at knowing
that &lt;code&gt;disk-sqlbackup-temp&lt;/code&gt; is genuinely temporary.&lt;/p&gt;
&lt;h2&gt;The consultant trust problem&lt;/h2&gt;
&lt;p&gt;The second reason is commercial rather than technical, and it is the one that
decided it.&lt;/p&gt;
&lt;p&gt;If you are a consultant, an MSP, or simply the new person, the access
conversation happens before the value conversation. Asking for Contributor
across a subscription on day one is a reasonable request that will slow you down
by a week while somebody senior decides how they feel about it.&lt;/p&gt;
&lt;p&gt;Asking for Reader is nearly frictionless, because the answer to &quot;what is the
worst thing this can do&quot; is &quot;read a list of resources&quot;. Being able to say the
tooling cannot write, as a property of the tooling rather than a promise about
your intentions, is worth more than any amount of reassurance.&lt;/p&gt;
&lt;p&gt;The permissions that actually run the &lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt;
are Reader at the scopes you want covered, plus directory read for the
credential and RBAC checks. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles&quot;&gt;built-in roles reference&lt;/a&gt;
sets out what Reader permits, which is worth linking when somebody asks, because
&quot;Reader&quot; sounds vaguer than it is.&lt;/p&gt;
&lt;h2&gt;Found nothing is not the same as could not look&lt;/h2&gt;
&lt;p&gt;This is the design decision I would defend hardest, and it is the least visible.&lt;/p&gt;
&lt;p&gt;A cost script authenticates, enumerates, finds no orphaned resources, and prints
a clean report. Good news.&lt;/p&gt;
&lt;p&gt;A cost script fails to authenticate, enumerates nothing, finds no orphaned
resources, and prints a clean report. Identical output. Catastrophically
different meaning.&lt;/p&gt;
&lt;p&gt;The second case is worse than a crash, because a crash gets investigated and a
clean report gets filed. Somebody tells a client the estate is tidy. A scheduled
job goes green for eight months while the token it depends on has been expired
for seven of them.&lt;/p&gt;
&lt;p&gt;So the scripts exit non-zero when they cannot do the job, and the distinction is
enforced in a specific place. The connection check does not test whether a
context object exists; &lt;code&gt;Get-AzContext&lt;/code&gt; returns a fully populated context even
when the cached token behind it has expired, which is exactly the trap. It
acquires a token, and treats failure to acquire one as a failure of the run
rather than an absence of findings.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;function Assert-AzConnection {
    $ctx = Get-AzContext
    if (-not $ctx -or -not $ctx.Account) {
        Write-Error &#x27;Not connected. Run Connect-AzAccount.&#x27;
        exit 1
    }
    # A populated context is not proof of a valid token. Force an acquisition.
    try   { $null = Get-AzAccessToken -ErrorAction Stop -WarningAction SilentlyContinue }
    catch { Write-Error &amp;quot;Cannot acquire a token: $($_.Exception.Message)&amp;quot;; exit 1 }
    return $ctx
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The same principle applies to anything scheduled, and it is the subject of a
&lt;a href=&quot;/notes/powershell-scripts-exit-codes-logging&quot;&gt;separate note on exit codes and the silent zero&lt;/a&gt;.
A script that always exits 0 is a script whose monitoring is decorative.&lt;/p&gt;
&lt;h2&gt;What read-only does not protect you from&lt;/h2&gt;
&lt;p&gt;Worth stating plainly, because &quot;read-only&quot; gets treated as a synonym for &quot;safe&quot;
and it is narrower than that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reading is still access.&lt;/strong&gt; A Reader on a subscription can enumerate resource
names, configurations, tags and network topology. Resource names alone often
disclose more than people expect: customer names in resource groups, project
codenames, the fact that you run a particular database engine. Granting Reader is
a smaller decision than granting Contributor, not a null one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It can still take a subscription down.&lt;/strong&gt; Not by writing, but by volume. An
unthrottled enumeration across nine subscriptions with a few thousand resources
will hit ARM rate limits, and hitting them affects other callers in the same
subscription, including deployments. The tools page a request at a time and back
off on 429 for that reason, which is unglamorous and the difference between a
tool you can run at 10am and one you cannot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It cannot tell you a finding is safe to action.&lt;/strong&gt; The output says a disk is
unattached. It does not say the data is unwanted, and the read-only guarantee
offers no protection whatsoever against somebody deleting the wrong thing off
the back of a correct report. The guarantee is about the tool, not about the
afternoon.&lt;/p&gt;
&lt;h2&gt;What this costs&lt;/h2&gt;
&lt;p&gt;Being honest about the trade-off, because a design note that only lists
advantages is marketing.&lt;/p&gt;
&lt;p&gt;You do the deleting. For fourteen unattached disks that is fourteen portal
operations or a short script you write yourself, and it is genuinely more work
than a tool that cleaned up as it went.&lt;/p&gt;
&lt;p&gt;There is no remediation automation to buy. If what you want is something that
enforces a tagging policy or removes orphans nightly, this is not it, and Azure
Policy with deployIfNotExists is a better fit for that job.&lt;/p&gt;
&lt;p&gt;And a read-only tool cannot verify its own recommendation. It tells you the disk
is unattached. It cannot tell you the deletion succeeded, so the loop is closed
by re-running it rather than by a confirmation.&lt;/p&gt;
&lt;p&gt;Those are real costs. They buy a tool that can be pointed at any subscription by
anybody without a risk assessment, which for the way this work actually happens
has been worth it every time.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;Everything in the &lt;a href=&quot;/notes/azure-security/&quot;&gt;azure security notes&lt;/a&gt; and the
&lt;a href=&quot;/notes/azure-cost/&quot;&gt;azure cost notes&lt;/a&gt; is checkable this way, which is not a
coincidence: the checks were chosen partly because they can be answered by
reading. The categories that would need write access, such as remediating a
policy or rotating a credential, are deliberately absent.&lt;/p&gt;
&lt;p&gt;The licence terms ship inside each download rather than living on a page that
can change, which is the same instinct applied to a different problem: the thing
you are relying on should travel with the artefact.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>A business continuity tabletop exercise that does not need a conference room</title>
    <link href="https://acloud.solutions/notes/bcdr-tabletop-exercise-small-company/"/>
    <id>https://acloud.solutions/notes/bcdr-tabletop-exercise-small-company/</id>
    <updated>2026-08-04T09:00:00Z</updated>
    <published>2026-08-04T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>A business continuity tabletop exercise needs five people and two hours, not a conference room. Choosing a scenario, what to record, and the findings.</summary>
    <content type="html">&lt;p&gt;The business continuity plan is fourteen pages. It has a call tree with two
people who have left, an RTO of four hours that nobody has tested, and a section
on relocating to an alternative site, which is notable for a company that does
not have a site.&lt;/p&gt;
&lt;p&gt;A business continuity tabletop exercise is how you find that out in two hours
rather than during an incident. It needs no venue, no consultant and no
technology. Five people, a scenario, and somebody writing down what nobody can
answer.&lt;/p&gt;
&lt;h2&gt;What a business continuity tabletop exercise is&lt;/h2&gt;
&lt;p&gt;A facilitated discussion, not a technical test. You describe a situation, then
ask the people in the room what they would do, in what order, and who they would
tell. Nothing is switched off and nothing is restored. The output is a list of
things that turned out not to work.&lt;/p&gt;
&lt;p&gt;Two hours is right. Under ninety minutes and you get through one phase. Over two
and a half and attention goes.&lt;/p&gt;
&lt;p&gt;Five people is right: whoever holds technical recovery, whoever talks to
customers, whoever can authorise spending, whoever handles contracts, and a
facilitator who is not answering questions. In a company of forty that is
typically the technical lead, a support lead, a director and whoever holds
contracts, with you facilitating.&lt;/p&gt;
&lt;p&gt;If you are running the ISMS alone you should not be both facilitator and
principal respondent, so ask somebody else to facilitate from a script you
wrote. It works better than it sounds, because a facilitator who does not know
the answers asks better follow-up questions.&lt;/p&gt;
&lt;h2&gt;Choosing a scenario&lt;/h2&gt;
&lt;p&gt;One scenario. Not three. The temptation is to cover everything and the result is
that nothing gets tested properly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ransomware on the production platform.&lt;/strong&gt; The strongest default. It touches
recovery, communications, legal notification, customer contracts and the
decision about payment, which is a decision nobody wants to make for the first
time under pressure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loss of the identity provider.&lt;/strong&gt; Underrated and increasingly the right choice.
If your directory is unavailable, nobody can sign into anything, including the
tools you would use to coordinate the response. This surfaces the dependency
nobody maps, and it pairs with
&lt;a href=&quot;/notes/break-glass-accounts&quot;&gt;break-glass accounts&lt;/a&gt;, which is exactly the
control the scenario tests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key person unavailable.&lt;/strong&gt; Uncomfortable and the most valuable at this size. If
the one person who knows how deployment works is unreachable for a fortnight,
what stops. In a one-person IT function this is a genuine risk that belongs in
your register honestly rather than a hypothetical.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Supplier failure.&lt;/strong&gt; Your hosting provider has a regional outage, or a critical
SaaS supplier is breached. Tests whether you know what depends on what, and
whether the contract says anything useful.&lt;/p&gt;
&lt;p&gt;Pick the one that makes you most uncomfortable. That is where the findings are.&lt;/p&gt;
&lt;h2&gt;Running it&lt;/h2&gt;
&lt;p&gt;Three phases, roughly forty minutes each.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase one, detection and triage.&lt;/strong&gt; How do we find out. Who is told first. What
do we know at this point, and what do we assume. Push on the difference between
those two, because that is where incidents go wrong.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase two, response.&lt;/strong&gt; What do we do in the first hour. Who decides. What do
we tell customers, when, and who writes it. Do we have an obligation to notify
anyone, within what period, and who makes that call.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase three, recovery and after.&lt;/strong&gt; How do we get back. How do we know we are
back. What do we tell people afterwards, and what do we do differently.&lt;/p&gt;
&lt;p&gt;Inject one complication partway through. The person who would normally handle
this is on a flight. The status page is hosted on the thing that is down. The
backup is fine but nobody has ever restored one. Complications are where the
useful findings come from, because the plan covers the straightforward path.&lt;/p&gt;
&lt;p&gt;Two rules that keep it honest. Nobody says &quot;we would just&quot; without saying who
and how. And &quot;I would check the runbook&quot; is followed immediately by &quot;show me&quot;,
which is where the exercise usually stops being comfortable.&lt;/p&gt;
&lt;h2&gt;The findings that come out every time&lt;/h2&gt;
&lt;p&gt;There is a pattern, and it is remarkably consistent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nobody knows where the runbook is&lt;/strong&gt;, or the version they find is out of date.
This finding appears in essentially every first exercise, and it is the argument
for
&lt;a href=&quot;/notes/documentation-nobody-reads&quot;&gt;documentation people actually use&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The contact list is stale.&lt;/strong&gt; Personal phone numbers nobody has, a supplier
contact who left, an escalation path into a company that has been acquired.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nobody has restored a backup.&lt;/strong&gt; The jobs are green. Green means the backup
job succeeded, not that a restore works, and those are different claims.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The recovery time objective was invented.&lt;/strong&gt; Somebody wrote four hours because
it sounded reasonable. Ask what the actual recovery steps are and time them
honestly, and it is frequently longer. Worth checking whether any customer
contract commits you to a figure, because a contractual number and an aspirational
number in your own plan are very different things and the contract wins.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The notification clock is not understood.&lt;/strong&gt; Who decides whether an incident is
notifiable, on what basis, and within what period. The ICO&#x27;s
&lt;a href=&quot;https://ico.org.uk/for-organisations/report-a-breach/personal-data-breach/&quot;&gt;personal data breach guidance&lt;/a&gt;
sets out the obligation, and the exercise is where you find out whether anyone
in the room knows it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Everything routes through one person.&lt;/strong&gt; Which is the honest finding in a small
company, and the useful output is not to pretend otherwise but to identify the
two or three things that must be documented well enough for somebody else to
do them.&lt;/p&gt;
&lt;h2&gt;Recording it&lt;/h2&gt;
&lt;p&gt;The record is the evidence, and it is short.&lt;/p&gt;
&lt;p&gt;Date, scenario, participants and roles, the timeline as discussed, findings, and
actions with owners and dates. Two pages. The findings and actions are the part
that matters; the narrative is context.&lt;/p&gt;
&lt;p&gt;Then the actions have to go somewhere that gets reviewed, which is your
corrective action log rather than a document in a folder. A finding raised in an
exercise and never closed is worse than not having exercised, because you
documented knowing about it.&lt;/p&gt;
&lt;h2&gt;What it satisfies&lt;/h2&gt;
&lt;p&gt;Annex A 5.29 covers information security during disruption and 5.30 covers ICT
readiness for business continuity, and both expect the arrangements to be
tested. A two-hour tabletop with a written record satisfies &quot;tested&quot; for a
company of this size. It is not a full failover test and it does not claim to
be.&lt;/p&gt;
&lt;p&gt;Annually is the usual commitment, and it is the one that lapses first because
nothing prompts it, per
&lt;a href=&quot;/notes/iso-27001-surveillance-audit&quot;&gt;the surveillance audit pattern&lt;/a&gt;. Book next
year&#x27;s the day you finish this one.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; covers business continuity at SME scale, including how much
plan is enough, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; includes facilitating one of
these, which solves the problem of not being able to facilitate and answer at
the same time.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>When to hire an IT consultant, and what to make them leave behind</title>
    <link href="https://acloud.solutions/notes/when-to-hire-a-consultant/"/>
    <id>https://acloud.solutions/notes/when-to-hire-a-consultant/</id>
    <updated>2026-07-28T09:00:00Z</updated>
    <published>2026-07-28T09:00:00Z</published>
    <category term="Running IT alone"/>
    <summary>When to hire an IT consultant: three situations where it genuinely pays, several where it does not, and the handover test that decides whether it worked.</summary>
    <content type="html">&lt;p&gt;This is a post about my own service, so treat it accordingly. I have tried to
write the version I would want to read before spending money, which means it
spends more words on when not to bother than on when to.&lt;/p&gt;
&lt;p&gt;Deciding when to hire an it consultant is mostly a question about what your
actual constraint is. If the constraint is hours, outside help works. If the
constraint is that nobody will fund the fix, it produces a document.&lt;/p&gt;
&lt;h2&gt;When to hire an it consultant, honestly&lt;/h2&gt;
&lt;p&gt;Three situations where it genuinely pays.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A fixed external deadline you cannot move.&lt;/strong&gt; A certification date, a customer
contractual commitment, a migration weekend. The risk with one person is not
competence, it is that a single individual being unwell that week takes the
deadline with them. Buying capacity around a fixed date is buying insurance
against a concentration you cannot otherwise reduce.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Independence you structurally cannot provide.&lt;/strong&gt; An internal audit needs
somebody who did not build the thing, which is
&lt;a href=&quot;/notes/iso-27001-internal-audit-one-person&quot;&gt;the clause 9.2 problem&lt;/a&gt; and has no
in-house answer at this size. Same for a genuine review of an architecture you
designed: you will find what you were already worried about and miss what you
assumed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Depth you need once every two years.&lt;/strong&gt; A platform&#x27;s specific quirks, a
migration pattern, a particular compliance regime. Learning it properly costs
you a fortnight and you will have forgotten it by the time it recurs.&lt;/p&gt;
&lt;p&gt;Notice what those have in common. Each is a case where the constraint is not
your ability or even primarily your time, but something about your position.&lt;/p&gt;
&lt;h2&gt;When it does not help&lt;/h2&gt;
&lt;p&gt;More situations, and worth being direct about them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When nobody will fund the outcome.&lt;/strong&gt; An assessment produces a ranked list of
things to fix. If there is no budget or appetite to fix them, you have paid for
a document that says what you already suspected, and you now have it in writing,
which is occasionally useful politically and rarely worth the fee.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When you want a certificate without operational change.&lt;/strong&gt; An auditor will
establish that faster than any consultant can paper over it, per
&lt;a href=&quot;/notes/iso-27001-stage-1-stage-2&quot;&gt;what Stage 2 actually tests&lt;/a&gt;. Consultants
who imply otherwise are selling something that does not exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When the real problem is headcount.&lt;/strong&gt; If the honest answer is that the company
needs a second IT person, a consultant is a more expensive way to not hire one,
and the underlying position is unchanged when they leave.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When you have not defined the question.&lt;/strong&gt; &quot;Look at our Azure setup and tell us
what you think&quot; produces a broad report and a broad invoice. &quot;Our bill went up
40 percent and we do not know why&quot; produces an answer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For the everyday queue.&lt;/strong&gt; Handing over the helpdesk removes the signal you use
to know what is breaking, and it is the cheapest part of the job in hours.&lt;/p&gt;
&lt;h2&gt;The handover test&lt;/h2&gt;
&lt;p&gt;The test I hold myself to, and the one worth applying to anybody you engage: if
you cannot maintain it after they leave, it was built wrong.&lt;/p&gt;
&lt;p&gt;That has specific consequences, and they are worth writing into the engagement
before it starts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No automation authenticating as a named person.&lt;/strong&gt; A script running as the
consultant&#x27;s account stops working when their access is removed, which is
usually the week after they leave. Service principals or managed identities,
handed over with the permission list and the reason for each, per
&lt;a href=&quot;/notes/graph-api-permissions-least-privilege&quot;&gt;least privilege&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No credential with an expiry nobody knows.&lt;/strong&gt; If the work created a client
secret or certificate, its expiry date goes in your calendar before the
engagement closes. Otherwise it fails at 3am on a Saturday about eighteen months
later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Documentation that stops at the interesting part is not documentation.&lt;/strong&gt; &quot;Run
the pipeline&quot; is not a handover. What it does, what it assumes, what breaks it,
and how to tell whether it worked.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Read-only where possible.&lt;/strong&gt; Assessment work should not require write access.
Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles&quot;&gt;built-in roles reference&lt;/a&gt;
is worth having open during that conversation, because it lets you offer a
specific narrow role rather than negotiating in the abstract.
If somebody asks for Contributor to tell you what is in your subscriptions, ask
why, because
&lt;a href=&quot;/notes/read-only-by-default&quot;&gt;the read-only argument&lt;/a&gt; applies to consultants
more than to anyone.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Everything in your repository, not theirs.&lt;/strong&gt; Obvious, and it happens anyway.&lt;/p&gt;
&lt;h2&gt;What to ask before engaging anybody&lt;/h2&gt;
&lt;p&gt;Five questions that filter well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What will I have that I do not have now, in artefacts.&lt;/strong&gt; A report, a script, a
configuration, a decision. Vagueness here predicts vagueness later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What access do you need, and why that level.&lt;/strong&gt; A good answer is specific and
minimal and comes with a reason. A request for broad access &quot;to be safe&quot; is a
signal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What happens when you leave.&lt;/strong&gt; Whether they have thought about handover at
all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What will you not do.&lt;/strong&gt; Anybody who claims a broad remit at a small company is
either overselling or about to subcontract.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I speak to somebody you have handed over to.&lt;/strong&gt; Not a testimonial about the
work, a conversation about the handover, which is the part that determines
whether the money was well spent.&lt;/p&gt;
&lt;h2&gt;The uncomfortable part&lt;/h2&gt;
&lt;p&gt;The most useful engagement I could sell somebody is frequently the smallest one:
a couple of days establishing what is actually there and what the priorities
are, after which they do the work themselves. That converts a large project into
a small one and it is the correct advice for a company with a competent person
already in post.&lt;/p&gt;
&lt;p&gt;The reason more consultants do not lead with it is straightforward. It is a much
smaller invoice. Which is a reason to be sceptical of a broad proposal arriving
before anyone has looked at your estate, including from me.&lt;/p&gt;
&lt;p&gt;If it is useful, &lt;a href=&quot;/consulting/&quot;&gt;that is what this is&lt;/a&gt;, and a read-only
assessment is generally the cheapest way to find out whether there is anything
worth doing. If the compliance half is the problem and you would rather keep it
in-house, &lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; is the version where you do it yourself, which for
a lot of companies is the better answer.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Microsoft 365 audit log retention: there right up until you needed it</title>
    <link href="https://acloud.solutions/notes/microsoft-365-audit-log-retention/"/>
    <id>https://acloud.solutions/notes/microsoft-365-audit-log-retention/</id>
    <updated>2026-07-21T09:00:00Z</updated>
    <published>2026-07-21T09:00:00Z</published>
    <category term="Microsoft 365, Entra and Intune"/>
    <summary>Microsoft 365 audit log retention depends on licence, and the default outlives most investigations by nothing at all. What to ship elsewhere, and when.</summary>
    <content type="html">&lt;p&gt;A customer emails in March asking whether a document was accessed by anyone
outside the company. The document was shared in September. You open the audit
log search, set the date range, and get nothing, because the retention window
closed months ago and nobody chose that window or knew it existed.&lt;/p&gt;
&lt;p&gt;Microsoft 365 audit log retention is one of the few settings where the default
is fine until the single moment it is not, and at that moment there is no
remedy. You cannot retrospectively retain a log.&lt;/p&gt;
&lt;h2&gt;What the unified audit log actually holds&lt;/h2&gt;
&lt;p&gt;More than people expect, which is what makes the retention question matter.&lt;/p&gt;
&lt;p&gt;Sign-ins and authentication events. Mailbox activity including access to other
people&#x27;s mailboxes, which is the one that answers most internal questions.
SharePoint and OneDrive file access, sharing and downloads. Teams messages sent
and channels created. Administrative actions across Exchange, SharePoint, Entra
and Purview. Sharing link creation, which is how you answer the question in the
opening paragraph.&lt;/p&gt;
&lt;p&gt;That last one is worth dwelling on. The record of a link having been created,
and of who used it, is in the audit log and nowhere else that a small tenant is
likely to be keeping.&lt;/p&gt;
&lt;h2&gt;Microsoft 365 audit log retention by licence&lt;/h2&gt;
&lt;p&gt;The shape, rather than exact numbers, because Microsoft has changed these and
will again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Standard audit&lt;/strong&gt;, included in the common business and E3 plans, retains for a
period measured in months rather than years. It covers the event types above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Premium audit&lt;/strong&gt;, in E5 or as an add-on, retains substantially longer, adds
some higher-value event types, and permits configurable retention policies per
event type or per user.&lt;/p&gt;
&lt;p&gt;Because the specifics move, check
&lt;a href=&quot;https://learn.microsoft.com/en-us/purview/audit-log-retention-policies&quot;&gt;Microsoft&#x27;s audit log retention documentation&lt;/a&gt;
against your own tenant rather than trusting any figure in a blog post,
including this one. The relevant question is not what the documentation says in
general, it is what your tenant is configured for right now, and that is worth
checking today rather than in March.&lt;/p&gt;
&lt;h2&gt;The gap between retention and investigation&lt;/h2&gt;
&lt;p&gt;Here is the practical problem, and it is a mismatch of timescales rather than a
configuration error.&lt;/p&gt;
&lt;p&gt;Security incidents are frequently discovered long after they happen. A
compromised account is noticed when somebody reports an odd email. A data
question arrives when a customer asks, or when a former employee&#x27;s new employer
sends something suspicious. Breach notification obligations begin when you become
aware, not when the event occurred, and the ICO&#x27;s
&lt;a href=&quot;https://ico.org.uk/for-organisations/report-a-breach/personal-data-breach/&quot;&gt;personal data breach guidance&lt;/a&gt;
sets out what you are expected to be able to establish.&lt;/p&gt;
&lt;p&gt;The investigation you will need is almost always about a period that has already
passed. So the retention window is not &quot;how long until we notice a problem&quot;, it
is &quot;how far back might we need to look, from a starting point we do not control&quot;.&lt;/p&gt;
&lt;p&gt;For a company handling customer data under contractual obligations, a window
measured in a few months is uncomfortably short. Twelve months is a defensible
answer. Longer if your contracts say so, and some customer contracts do specify
log retention without anybody internally having read that clause.&lt;/p&gt;
&lt;h2&gt;Shipping it somewhere you control&lt;/h2&gt;
&lt;p&gt;If the built-in window is shorter than you need, the options are to buy longer
retention or to export.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ship to Sentinel.&lt;/strong&gt; The &lt;code&gt;OfficeActivity&lt;/code&gt; table holds unified audit log data,
and once it is in Log Analytics you control retention independently. The
trade-off is ingestion cost, which is the entire subject of
&lt;a href=&quot;/notes/sentinel-cost-control&quot;&gt;the Sentinel cost note&lt;/a&gt;, and &lt;code&gt;OfficeActivity&lt;/code&gt; is
one of the higher-volume tables. Worth filtering to the operations you actually
need rather than taking everything.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Export to storage.&lt;/strong&gt; Cheaper by a wide margin, and worse to query. A scheduled
job pulling the audit log via Graph or the Office Management API into blob
storage with a lifecycle policy costs very little. When you need it you are
parsing JSON out of blobs rather than writing KQL, which is fine for an
occasional investigation and painful for anything routine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Buy Premium audit.&lt;/strong&gt; Simplest, no engineering, and the cost scales with
headcount rather than volume, which for a small company is often the cheaper
answer than it first appears.&lt;/p&gt;
&lt;p&gt;The decision usually comes down to whether you also want detections on this
data. If yes, Sentinel, because the data has to be there anyway. If you only
need it for retrospective questions, storage export is the economical answer.&lt;/p&gt;
&lt;h2&gt;What an investigation looks like without it&lt;/h2&gt;
&lt;p&gt;Worth describing, because it is the argument that gets budget.&lt;/p&gt;
&lt;p&gt;A former employee is suspected of taking a customer list before leaving. With
the audit log, this is an afternoon: search file access and sharing events for
that user over their final month, identify what was downloaded or shared
externally, and produce a timeline with timestamps. The answer is either
reassuring or actionable, and either way it is defensible.&lt;/p&gt;
&lt;p&gt;Without it, you have their mailbox if it still exists, whatever the endpoint
tooling retained, and inference. You cannot establish what was accessed. You
cannot rule it out either, which is the worse half: an inconclusive
investigation means you cannot tell the customer nothing happened, and you
cannot tell your insurer or a regulator what did.&lt;/p&gt;
&lt;p&gt;That asymmetry is the point. Retention does not only help you prove something
went wrong. Most of the time it lets you prove nothing did, and &quot;we checked and
here is the evidence&quot; is a materially different conversation from &quot;we have no
way of knowing&quot;.&lt;/p&gt;
&lt;p&gt;The same applies to the mundane version. Somebody asks whether a file was
shared externally before a deal closed. With logs it is a query. Without them it
is a discussion about what people remember.&lt;/p&gt;
&lt;h2&gt;The check worth doing this week&lt;/h2&gt;
&lt;p&gt;Two things, twenty minutes.&lt;/p&gt;
&lt;p&gt;Confirm audit logging is actually enabled. It has been on by default for new
tenants for some time, and older tenants and specific mailbox audit settings
still catch people out. A tenant where somebody disabled mailbox auditing years
ago to reduce noise is not a hypothetical.&lt;/p&gt;
&lt;p&gt;Then run a search for something you know happened four months ago and see
whether it returns. That is a more reliable answer than any documentation,
because it tests your tenant rather than the general case. If it comes back
empty, you have found out on a quiet Tuesday rather than during an incident.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;Log retention is one of the least interesting controls to implement and one of
the most consequential to have got wrong, which is a poor combination for
something nobody is asked about until it matters.&lt;/p&gt;
&lt;p&gt;It sits alongside the rest of
&lt;a href=&quot;/notes/microsoft-365/&quot;&gt;the Microsoft 365 notes&lt;/a&gt;, and if you are documenting
this for a certification or a customer questionnaire,
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers logging and monitoring evidence in the context of the
relevant Annex A controls.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>An AI system inventory: finding out which features are AI before a customer asks</title>
    <link href="https://acloud.solutions/notes/ai-system-inventory/"/>
    <id>https://acloud.solutions/notes/ai-system-inventory/</id>
    <updated>2026-07-14T09:00:00Z</updated>
    <published>2026-07-14T09:00:00Z</published>
    <category term="AI and regulation"/>
    <summary>An AI system inventory is the artefact every AI compliance question depends on. How to find every feature that uses AI, and what to record about each.</summary>
    <content type="html">&lt;p&gt;A customer&#x27;s questionnaire asks you to list all AI systems in your product,
their purpose, and the models behind them. You know about the ticket
summarisation feature. Then somebody mentions the smart search, which turns out
to use embeddings. Then the support team says the chat widget has had an
autocomplete for a year. Then marketing asks whether the website chatbot counts.&lt;/p&gt;
&lt;p&gt;An ai system inventory exists because that conversation is otherwise unanswerable,
and because it is the artefact every other AI compliance obligation depends on.
Classification needs it. Supplier assessment needs it. The transparency
obligations in &lt;a href=&quot;/notes/eu-ai-act-saas-guide&quot;&gt;the AI Act note&lt;/a&gt; need it. Nothing
else can be done first.&lt;/p&gt;
&lt;h2&gt;Why the ai system inventory is harder than it sounds&lt;/h2&gt;
&lt;p&gt;Because AI arrived in your product through several doors and only one of them
was a decision.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Features somebody built deliberately.&lt;/strong&gt; These you know about.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Capabilities that came with a dependency.&lt;/strong&gt; A search library that added
semantic search. A support platform whose vendor switched on an AI assistant.
Nobody in your company chose it and it is processing your customers&#x27; text.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Somebody&#x27;s prototype that shipped.&lt;/strong&gt; A proof of concept behind a feature flag,
enabled for one customer, still enabled.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tools your own staff adopted.&lt;/strong&gt; Not in the product, and still in scope as a
deployer question, and still processing company data.&lt;/p&gt;
&lt;p&gt;So the inventory is a discovery exercise before it is a documentation exercise,
and the discovery is the part that finds surprises.&lt;/p&gt;
&lt;h2&gt;Where to look&lt;/h2&gt;
&lt;p&gt;Six places, in order of how much they turn up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your dependency manifests.&lt;/strong&gt; Search for the obvious provider SDKs and any
package with a model-shaped name. This is the fastest single pass.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Outbound network destinations.&lt;/strong&gt; Egress logs or firewall data showing calls to
model provider endpoints. This catches the dependency nobody declared, because
the traffic is there whether or not anyone documented the feature.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your card statement and enterprise applications list.&lt;/strong&gt; Same two sources as
&lt;a href=&quot;/notes/vendor-risk-review-small-company&quot;&gt;the supplier register&lt;/a&gt;, for the same
reason: they record what was actually bought and signed into rather than what
somebody remembers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Feature flags.&lt;/strong&gt; Especially the ones enabled for a subset of customers, which
are the prototypes that shipped.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your own product documentation and marketing.&lt;/strong&gt; If a page says &quot;AI-powered&quot;,
that is a claim you have made publicly, and it is in scope whether or not the
implementation matches the adjective.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask the engineers.&lt;/strong&gt; Last, because the sources above give you a list to
confirm rather than a blank page, and confirming is easier than recalling.&lt;/p&gt;
&lt;h2&gt;The eight columns worth recording&lt;/h2&gt;
&lt;p&gt;Enough to answer a questionnaire and to classify, and not so many that nobody
maintains it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Name and where it lives.&lt;/strong&gt; The feature, and the part of the product or the
internal process it sits in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose, in one sentence.&lt;/strong&gt; What decision or output it produces. This is the
column that determines classification, so write it precisely: &quot;suggests a reply
for an agent to edit&quot; is a different system from &quot;sends a reply&quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Provider and model.&lt;/strong&gt; Who, and which model family. Version if you pin one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data sent.&lt;/strong&gt; Categories, not examples. Customer support text, user names,
document contents. This is the column customers care about most.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data retention at the provider.&lt;/strong&gt; Whether the provider retains inputs, for how
long, and whether they are used for training. This is a contractual question and
the answer is usually configurable, which means somebody has to have configured
it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Human oversight.&lt;/strong&gt; Whether output is reviewed before it has an effect, and by
whom. Central to classification and to any honest description of risk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who owns it.&lt;/strong&gt; A person, for the same reason every other register needs an
owner: a system with no owner is a system nobody will update.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Classification and reasoning.&lt;/strong&gt; The category you have assigned and one
sentence of why. The reasoning is the valuable part, because the categories may
change and the reasoning explains your position either way.&lt;/p&gt;
&lt;h2&gt;Classifying without a lawyer&lt;/h2&gt;
&lt;p&gt;Enough to triage. Anything ambiguous or commercially material goes to advice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prohibited.&lt;/strong&gt; A short list including certain manipulative techniques,
untargeted facial image scraping, emotion inference in workplaces and education
in defined circumstances, and social scoring. If you are near any of these you
already know.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;High-risk.&lt;/strong&gt; Defined by use case rather than by technology, covering areas
such as employment decisions, access to essential services, education, law
enforcement and critical infrastructure, plus AI as a safety component in
regulated products. Most B2B SaaS is not here. If your product makes or
materially informs decisions about people in those areas, take advice, and note
the obligations were deferred to December 2027 and August 2028 respectively.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transparency obligations.&lt;/strong&gt; Where a person interacts with an AI system, or
where content is generated or manipulated. This is where most ordinary product
features land, and it applies now.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Minimal.&lt;/strong&gt; Everything else. Still worth having in the inventory, because a
customer asking for a complete list wants the complete list.&lt;/p&gt;
&lt;p&gt;The Commission&#x27;s
&lt;a href=&quot;https://ai-act-service-desk.ec.europa.eu/en/ai-act/timeline/timeline-implementation-eu-ai-act&quot;&gt;AI Act service desk&lt;/a&gt;
is the source worth checking rather than a summary, both for the category
definitions and because the dates attached to them have already been amended
once.&lt;/p&gt;
&lt;p&gt;The output is not a compliance verdict, it is a triage. Most rows are minimal or
transparency, a few need a decision, and one or two might need advice, and now
you know which.&lt;/p&gt;
&lt;h2&gt;Where to keep it&lt;/h2&gt;
&lt;p&gt;Wherever your asset register lives, because that is what this is.&lt;/p&gt;
&lt;p&gt;If you hold ISO 27001 the pragmatic answer is to extend the asset register with
the columns above rather than starting a parallel document. One register with an
AI flag beats two registers that disagree, and the review cadence you already
have carries it.&lt;/p&gt;
&lt;p&gt;The properties that matter are the same as for any register: an owner per row, a
review date, and a change history. Quarterly review, and a check at the point a
new supplier or feature is onboarded, which folds into the same gate as
supplier onboarding.&lt;/p&gt;
&lt;h2&gt;What makes it worth doing anyway&lt;/h2&gt;
&lt;p&gt;The regulatory timeline has already moved once, by amendment, and can move
again. That argues against building a programme around a date and for building
the artefact that is useful regardless.&lt;/p&gt;
&lt;p&gt;An inventory answers the customer questionnaire, which is the pressure you will
actually feel first. It answers the data protection question about what leaves
your estate and to whom. It tells you which providers you depend on, which is an
availability and supplier question independent of AI. And it turns any future
classification exercise into an afternoon.&lt;/p&gt;
&lt;p&gt;That is a reasonable return on a day&#x27;s discovery work, and it does not depend on
any particular version of the rules surviving.&lt;/p&gt;
&lt;p&gt;If the classification turns out to be the hard part rather than the discovery,
that is usually a sign the question is commercial rather than technical, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; covers it alongside the rest of
&lt;a href=&quot;/notes/ai-regulation/&quot;&gt;the AI regulation notes&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Microsoft Graph API permissions least privilege, not the first result</title>
    <link href="https://acloud.solutions/notes/graph-api-permissions-least-privilege/"/>
    <id>https://acloud.solutions/notes/graph-api-permissions-least-privilege/</id>
    <updated>2026-07-07T09:00:00Z</updated>
    <published>2026-07-07T09:00:00Z</published>
    <category term="Automation"/>
    <summary>Microsoft Graph API permissions least privilege in practice. Application versus delegated, reading the reference properly, and reviewing what you granted.</summary>
    <content type="html">&lt;p&gt;The reporting script needs to list users and their MFA registration status. It
has &lt;code&gt;Directory.ReadWrite.All&lt;/code&gt;, because that was granted eighteen months ago when
somebody was making it work at half past six on a Thursday, and it has worked
ever since so nobody has revisited it.&lt;/p&gt;
&lt;p&gt;Microsoft graph api permissions least privilege is not a difficult principle. It
fails in practice for a specific and forgivable reason: the permission that
definitely works is easy to find, and the minimum permission that works takes
twenty minutes to establish.&lt;/p&gt;
&lt;h2&gt;Why microsoft graph api permissions least privilege loses to expedience&lt;/h2&gt;
&lt;p&gt;The sequence is always the same. A call returns 403. You search the error. The
first useful result mentions a permission. You grant it, the call works, and you
move on to the actual task, which was never &quot;configure Graph permissions&quot;.&lt;/p&gt;
&lt;p&gt;Nothing in that sequence is unreasonable. The problem is that the permission is
now permanent, and it is attached to a credential that will be copied into a
pipeline, a config file and possibly a ticket. The script was correct. The grant
outlived the afternoon that produced it.&lt;/p&gt;
&lt;p&gt;The fix is not discipline, it is knowing where to look, which turns twenty
minutes into two.&lt;/p&gt;
&lt;h2&gt;Application versus delegated, which decides everything else&lt;/h2&gt;
&lt;p&gt;This distinction is the one that causes the most trouble, and it is worth being
precise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Delegated permissions&lt;/strong&gt; act on behalf of a signed-in user. The effective
access is the intersection of what the app was granted and what that user can
already do. A delegated &lt;code&gt;User.ReadWrite.All&lt;/code&gt; held by an app a standard user
signs into does not let that user rewrite the directory, because they could not
anyway.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Application permissions&lt;/strong&gt; act as the app itself, with no user context. There is
no intersection and no ceiling. &lt;code&gt;User.ReadWrite.All&lt;/code&gt; as an application
permission means exactly that, across the whole tenant, at three in the morning,
with nobody signed in.&lt;/p&gt;
&lt;p&gt;So an over-permissioned application registration is materially worse than an
over-permissioned person, and unattended automation is precisely where
application permissions are used. That is the combination worth auditing.&lt;/p&gt;
&lt;p&gt;The corollary people miss: for anything scheduled, you want the narrowest
application permission that works, and you should assume it grants exactly what
it says with no mitigating context.&lt;/p&gt;
&lt;h2&gt;Reading the reference properly&lt;/h2&gt;
&lt;p&gt;Every Graph operation&#x27;s documentation lists its permissions in a table, ordered
from least to most privileged, split by delegated and application. The least
privileged one that appears is the answer, and it is frequently much narrower
than the one in the search result that fixed your 403.&lt;/p&gt;
&lt;p&gt;Concretely, for the reporting script above, listing users needs &lt;code&gt;User.Read.All&lt;/code&gt;
rather than &lt;code&gt;Directory.Read.All&lt;/code&gt;, and certainly rather than
&lt;code&gt;Directory.ReadWrite.All&lt;/code&gt;. Reading authentication methods needs
&lt;code&gt;UserAuthenticationMethod.Read.All&lt;/code&gt;, which is narrow and specific and exists
precisely for this.&lt;/p&gt;
&lt;p&gt;The pattern to internalise from the names: &lt;code&gt;.Read.&lt;/code&gt; beats &lt;code&gt;.ReadWrite.&lt;/code&gt;,
resource-specific beats &lt;code&gt;Directory.&lt;/code&gt;, and if a permission&#x27;s name does not
contain the resource you are touching, you are probably holding something too
broad. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/graph/permissions-reference&quot;&gt;permissions reference&lt;/a&gt;
is the canonical list and is worth having open while writing anything new.&lt;/p&gt;
&lt;h2&gt;Certificates over secrets&lt;/h2&gt;
&lt;p&gt;Once the permission set is right, the credential holding it matters.&lt;/p&gt;
&lt;p&gt;A client secret is a string. It gets pasted into pipelines, copied into
&lt;code&gt;.env&lt;/code&gt; files, shared in a message to unblock somebody, and it is readable by
anyone who can see any of those places. A certificate keeps the private key
where it was generated, so the thing you distribute is a thumbprint rather than
the credential itself.&lt;/p&gt;
&lt;p&gt;Both expire, and the expiry is its own problem covered in
&lt;a href=&quot;/notes/expiring-credentials-app-registrations&quot;&gt;the credential note&lt;/a&gt;. The
difference is what happens between now and then.&lt;/p&gt;
&lt;p&gt;Better again: if the thing authenticating runs in Azure, use a managed identity
and hold no credential at all. That removes the expiry problem, the distribution
problem and the leaver problem simultaneously, and it applies to more workloads
than people assume.&lt;/p&gt;
&lt;h2&gt;Reviewing what you already granted&lt;/h2&gt;
&lt;p&gt;The audit is short and almost always surprising.&lt;/p&gt;
&lt;p&gt;List your application registrations and service principals with their granted
permissions, and sort by breadth. You are looking for three things:
&lt;code&gt;Directory.ReadWrite.All&lt;/code&gt; on anything that only reads, &lt;code&gt;.ReadWrite.&lt;/code&gt; where the
name of the app suggests reporting, and any application whose purpose nobody can
state.&lt;/p&gt;
&lt;p&gt;Then check last sign-in per service principal. An app registration holding
tenant-wide write access with no sign-ins in six months is not a permissions
problem, it is a deletion opportunity, and deleting it removes the permission,
the credential and next quarter&#x27;s review item together.&lt;/p&gt;
&lt;p&gt;The uncomfortable finding on most first passes is an app called something like
&lt;code&gt;test-app-2&lt;/code&gt; with &lt;code&gt;Directory.ReadWrite.All&lt;/code&gt;, created during an integration trial
that did not proceed. Nobody remembers it, it still authenticates, and it can
rewrite the directory. That single deletion is usually worth more than any
amount of narrowing elsewhere.&lt;/p&gt;
&lt;p&gt;Consent grants are worth the same treatment. A user-consented app somebody
authorised years ago may hold delegated access nobody reviewed, and admin
consent granted tenant-wide applies to everybody including future joiners.&lt;/p&gt;
&lt;h2&gt;Finding the minimum without guessing&lt;/h2&gt;
&lt;p&gt;Two techniques beat reading documentation, when the documentation is ambiguous
or the operation is undocumented.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Start with nothing and add.&lt;/strong&gt; Grant no permissions, run the script, and read
the 403. Graph error responses frequently name the permission the call wanted,
which turns the search into a lookup. Add that one, re-run, repeat. Three
iterations gets you a minimal set derived from your actual calls rather than
from what somebody else&#x27;s script needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Check what the module is really calling.&lt;/strong&gt; A cmdlet wrapping several Graph
calls needs the union of their permissions, which is often broader than the
cmdlet&#x27;s own documentation implies. Turning on request debugging shows the URIs,
and once you have the URIs you can look each one up individually. This is how
you discover that a convenience cmdlet needs write access because of a call it
makes for display purposes rather than for the operation you wanted.&lt;/p&gt;
&lt;p&gt;Both are worth doing once per script and never again, and the output belongs in
a comment at the top of the file next to the connect call. That comment is the
single most useful line for whoever inherits it, because it converts &quot;which of
these permissions can I safely remove&quot; from an experiment into a fact.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;The permission set is part of the handover rather than an implementation detail.
Automation delivered as part of &lt;a href=&quot;/consulting/&quot;&gt;consulting work&lt;/a&gt; comes with the
service principal, the permission list, the reason each permission is there, and
the expiry date, because the alternative is an app registration nobody can
safely remove in two years.&lt;/p&gt;
&lt;p&gt;It sits alongside
&lt;a href=&quot;/notes/joiner-mover-leaver-automation-graph&quot;&gt;the leaver automation note&lt;/a&gt;, which
is the one case in this cluster where broad write access is genuinely required,
and &lt;a href=&quot;/notes/automation/&quot;&gt;the rest of the automation notes&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Turning a CSV of findings into an Azure cost report finance will act on</title>
    <link href="https://acloud.solutions/notes/azure-cost-report-for-finance/"/>
    <id>https://acloud.solutions/notes/azure-cost-report-for-finance/</id>
    <updated>2026-06-30T09:00:00Z</updated>
    <published>2026-06-30T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>An Azure cost report that gets acted on ranks findings by monthly cost, states its caveats first, and ends in decisions rather than data.</summary>
    <content type="html">&lt;p&gt;You have run the checks. There is a folder of CSVs. Somewhere in it is about 140
dollars a month of avoidable spend, which is either a rounding error or a
meaningful percentage of the bill depending on the company.&lt;/p&gt;
&lt;p&gt;The failure mode from here is not technical. It is sending a spreadsheet to
someone who has thirty minutes between meetings and expecting them to derive a
decision from it. A good azure cost report does the deriving for them.&lt;/p&gt;
&lt;h2&gt;What an azure cost report needs to do&lt;/h2&gt;
&lt;p&gt;Three things, in this order, and the order is the point.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Say what it does not know, first.&lt;/strong&gt; Reservations, savings plans, enterprise
agreement discounts and Hybrid Benefit all change the real figure, and none of
them are visible in the resources you queried. If the caveat is in a footnote,
somebody in the meeting will find it and it will look like you were hiding it.
If it is the first paragraph, you are the person who understands the limits of
their own numbers, which is a much better position to hold.&lt;/p&gt;
&lt;p&gt;The wording that has served me: these figures are for prioritising work rather
than for billing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rank by monthly cost, descending.&lt;/strong&gt; Not by resource type, not by subscription,
not alphabetically. The reader wants to know what to look at first and there is
exactly one correct sort order for that question.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;End in decisions, not data.&lt;/strong&gt; Split every finding into recommended, deferred,
or ignore, with a reason on the deferrals. A report where all 40 findings are
&quot;recommended&quot; has not been triaged and shifts the whole judgement onto the
reader. A report where 12 are recommended, 9 are deferred pending a conversation
with a named person and 19 are noise has done the work.&lt;/p&gt;
&lt;h2&gt;Three formats, three audiences&lt;/h2&gt;
&lt;p&gt;Sending one audience another audience&#x27;s format is how good findings get ignored.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML for whoever decides.&lt;/strong&gt; Caveats at the top, findings ranked by cost, the
recommended and deferred split, and totals at the bottom. Self-contained so it
survives an email gateway that strips external references. This is the artefact
that goes to a client or to finance and gets forwarded.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Markdown for whoever does the work.&lt;/strong&gt; One block per finding, with the resource
ID and the check that produced it, paste-ready into a ticket. No narrative. The
person clearing the backlog does not need the caveats because they are not the
one deciding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A digest for the channel.&lt;/strong&gt; Four lines. Total monthly cost of open findings,
the change since the last run, the top three by cost, and a link to the full
report. Nobody reads a report in Teams. They read a number, notice whether it
moved, and click if it did.&lt;/p&gt;
&lt;h2&gt;The numbers have to be right in the boring direction&lt;/h2&gt;
&lt;p&gt;One thing will destroy the credibility of every subsequent report, and it is not
being slightly wrong. It is being wrong in a way that flatters the exercise.&lt;/p&gt;
&lt;p&gt;If you understate the saving, somebody acts, the saving turns out to be larger,
and you look conservative. If you overstate it, somebody acts, the saving does
not appear on the invoice, and every number you produce afterwards gets checked
by hand.&lt;/p&gt;
&lt;p&gt;That is the practical reason
&lt;a href=&quot;/notes/azure-managed-disk-pricing-provisioned-tier&quot;&gt;disk tier pricing&lt;/a&gt; matters
so much to this. A flat per-GB estimate understates a Premium disk by roughly
3.7x, which sounds like the safe direction to be wrong in until you realise it
makes the whole cleanup look not worth doing. Eight findings totalling 137.26 a
month is an afternoon&#x27;s work with an obvious answer. The same eight findings
reported as 40 dollars a month gets deferred, and correctly so.&lt;/p&gt;
&lt;h2&gt;Structure that works&lt;/h2&gt;
&lt;p&gt;For anything longer than a page:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;One paragraph of scope.&lt;/strong&gt; Which subscriptions, which date, what was
   checked, what was not.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Caveats.&lt;/strong&gt; Three or four lines. What could move these numbers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Headline.&lt;/strong&gt; Total monthly cost of findings, and the count.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recommended.&lt;/strong&gt; Ranked by cost, with the action for each.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deferred.&lt;/strong&gt; With the reason and, where possible, the name of the person the
   decision needs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ignore.&lt;/strong&gt; Briefly, because listing what you deliberately did not raise is
   what stops somebody else raising it next quarter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to re-run it.&lt;/strong&gt; The command, so the improvement is verifiable without
   you.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That last section is the one people leave out, and it is the difference between
a report and a dependency. If the client can re-run the checks next month, the
number becomes a metric. If they cannot, it was a one-off observation and it
expires the day you leave.&lt;/p&gt;
&lt;h2&gt;Reconciling against actual spend&lt;/h2&gt;
&lt;p&gt;A findings report is a projection. At some point somebody sensible will ask
whether it happened.&lt;/p&gt;
&lt;p&gt;Cost Management is the right source for that, not your own tooling. Export
actual billed cost for the resource types you acted on, for the month before and
the month after, and compare. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/cost-management-billing/costs/tutorial-export-acm-data&quot;&gt;Cost Management export documentation&lt;/a&gt;
covers scheduling those exports to storage, which is worth setting up before you
need the comparison rather than after.&lt;/p&gt;
&lt;p&gt;Expect the actual saving to differ from the projection, and expect to be able to
explain why. Usually it is a reservation you did not know about, a resource
somebody recreated, or a price change. All three are fine answers. Not knowing
is not.&lt;/p&gt;
&lt;h2&gt;White-labelling, if you are billing for this&lt;/h2&gt;
&lt;p&gt;If you are a consultant or a managed service provider, the report is a
deliverable rather than an internal document, and a report carrying somebody
else&#x27;s brand is not much use.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/tools/azclean-reporting/&quot;&gt;AzClean Reporting&lt;/a&gt; produces all three formats from
toolkit CSVs or any CSV where you can name the cost and resource columns, with
white-labelling and the recommended and deferred thresholds as parameters. The
thresholds matter more than they sound: what counts as worth doing differs
between a startup and a company with a change board, and hardcoding that
judgement into a tool is how you end up arguing with your own report.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;/notes/azure-tagging-strategy-that-survives&quot;&gt;tagging note&lt;/a&gt; covers the other
half of this, which is being able to attribute the spend you did not eliminate.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure app registration secret expiry: they will go at 3am on a Saturday</title>
    <link href="https://acloud.solutions/notes/expiring-credentials-app-registrations/"/>
    <id>https://acloud.solutions/notes/expiring-credentials-app-registrations/</id>
    <updated>2026-06-23T09:00:00Z</updated>
    <published>2026-06-23T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>Azure app registration secret expiry breaks integrations at the worst possible time. Finding what expires in 30 days, and why a ten-year secret is worse.</summary>
    <content type="html">&lt;p&gt;Nothing about the failure will make sense at first. The nightly job did not run.
The logs say the token request was rejected. Nobody deployed anything, nobody
changed a firewall rule, and the thing has worked every night for two years.&lt;/p&gt;
&lt;p&gt;Azure app registration secret expiry is the answer roughly a third of the time,
and it has a particular cruelty to it: the expiry date was chosen two years ago
by somebody picking from a dropdown, and it lands whenever it lands. Which is
statistically likely to be outside working hours, because most of the week is.&lt;/p&gt;
&lt;h2&gt;Azure app registration secret expiry comes in two kinds&lt;/h2&gt;
&lt;p&gt;App registrations authenticate with either a client secret or a certificate, and
both expire.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Client secrets&lt;/strong&gt; are strings. Easy to create, easy to paste somewhere, and the
value is only visible once at creation. Maximum lifetime is capped, and the
portal nudges you toward shorter ones now, which is an improvement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Certificates&lt;/strong&gt; are better and more work. The thumbprint is what the app
registration holds, and the private key lives wherever the client runs. They
expire the same way and are less likely to be pasted into a Teams message.&lt;/p&gt;
&lt;p&gt;Both are held on the application object, and both are invisible until they fail
unless somebody is looking. There is no default alert. Nothing emails you. The
&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/how-to-add-credentials&quot;&gt;app registration credential documentation&lt;/a&gt;
covers creation but the monitoring is your problem.&lt;/p&gt;
&lt;h2&gt;Finding what expires soon&lt;/h2&gt;
&lt;p&gt;The Graph query is straightforward. The trap is in the property names.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;Connect-MgGraph -Scopes &#x27;Application.Read.All&#x27;
$horizon = (Get-Date).AddDays(30)

Get-MgApplication -All | ForEach-Object {
    $app = $_
    foreach ($c in @($app.PasswordCredentials) + @($app.KeyCredentials)) {
        # EndDateTime, not EndDate. A null here becomes a date in year 1,
        # which reports every credential as expired 739,000 days ago.
        if (-not $c.EndDateTime) { continue }
        if ($c.EndDateTime -le $horizon) {
            [pscustomobject]@{
                App       = $app.DisplayName
                AppId     = $app.AppId
                Kind      = if ($c.Hint) { &#x27;Secret&#x27; } else { &#x27;Certificate&#x27; }
                Name      = $c.DisplayName
                Expires   = $c.EndDateTime
                DaysLeft  = [int]($c.EndDateTime - (Get-Date)).TotalDays
            }
        }
    }
} | Sort-Object DaysLeft
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two things worth stealing. The property is &lt;code&gt;EndDateTime&lt;/code&gt; and not &lt;code&gt;EndDate&lt;/code&gt;; I
wrote &lt;code&gt;EndDate&lt;/code&gt; once, got null for every credential, subtracted it from today,
and produced a report claiming everything had expired roughly two thousand years
ago. It was a memorable way to learn to guard for null before doing date
arithmetic.&lt;/p&gt;
&lt;p&gt;And service principals hold their own credentials separately from applications.
An app registration created in your tenant has both objects, and a credential
can sit on either. &lt;code&gt;Get-MgApplication&lt;/code&gt; alone misses some, so check
&lt;code&gt;Get-MgServicePrincipal&lt;/code&gt; too, particularly for anything set up by a vendor.&lt;/p&gt;
&lt;h2&gt;The ten-year secret is a different problem&lt;/h2&gt;
&lt;p&gt;Finding a secret expiring in 30 days is an operational task. Finding one that
expires in 2034 is a security finding, and the two want different responses.&lt;/p&gt;
&lt;p&gt;A long-lived secret is a password that never rotates, held by however many
systems and people have touched it since creation. Its expiry date is not
protecting anything; it is deferring a conversation. And because it will not
fail, nobody will ever be forced to look at it, so it accumulates copies: in a
pipeline variable, in a config file, in the ticket where somebody shared it, in
a former employee&#x27;s password manager.&lt;/p&gt;
&lt;p&gt;So the audit should sort both ways. Expiring soonest, which is the ticket queue.
And longest-lived, which is the risk register. The second list is more
interesting and gets looked at less.&lt;/p&gt;
&lt;p&gt;Setting a tenant-wide maximum credential lifetime through app management policy
stops new ones being created with absurd expiry dates, which is preventive
rather than corrective and therefore worth more than any amount of auditing.&lt;/p&gt;
&lt;h2&gt;Managed identity, where it fits&lt;/h2&gt;
&lt;p&gt;The correct answer to most secret expiry problems is to stop having a secret.&lt;/p&gt;
&lt;p&gt;Managed identity gives an Azure resource an identity in your directory with no
credential you hold. The platform handles it. Nothing expires, nothing gets
pasted anywhere, and there is nothing for a leaver to take with them. If the
thing authenticating runs in Azure, which for a VM, Function, App Service,
Automation account or container app it usually does, this is available and is
almost always right.&lt;/p&gt;
&lt;p&gt;Where it does not apply: something running outside Azure, such as a script on a
laptop, a build agent elsewhere, or a third-party SaaS product calling your
tenant. Those need a real credential, and for those, certificates beat secrets
and short lifetimes beat long ones.&lt;/p&gt;
&lt;p&gt;The practical migration order is to work through the list produced above and ask
one question per app: does this run in Azure. Everything that does becomes a
managed identity and drops off the list permanently. What remains is a smaller
set worth actually monitoring, which is the point.&lt;/p&gt;
&lt;h2&gt;The inventory question underneath this&lt;/h2&gt;
&lt;p&gt;Working through an expiry list surfaces a question people find harder than the
credentials themselves: what is this app registration actually for.&lt;/p&gt;
&lt;p&gt;A tenant that has been running for a few years accumulates them. One per
integration, several from vendor onboarding, a handful somebody created while
testing and never removed, and at least one called something like &lt;code&gt;test-app-2&lt;/code&gt;
holding &lt;code&gt;Directory.ReadWrite.All&lt;/code&gt;. The credential expiry is the prompt to ask,
because it is the only moment anyone is forced to look.&lt;/p&gt;
&lt;p&gt;Three questions per app, and the answers take minutes:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What permissions does it hold, and are they application permissions or
delegated.&lt;/strong&gt; Application permissions apply tenant-wide with no user context,
which is what makes an over-permissioned app registration worse than an
over-permissioned person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When did it last sign in.&lt;/strong&gt; Service principal sign-in activity answers this.
An app registration with a live secret and no sign-ins in six months is a
credential with no purpose, and deleting it is the cheapest security improvement
available.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who owns it.&lt;/strong&gt; Not who created it, who would notice if it stopped. If nobody
can answer, that is the finding rather than the expiry date.&lt;/p&gt;
&lt;p&gt;The ones that fail all three are safe to remove, and removing an app removes its
credentials, its permissions and its place on next quarter&#x27;s list at the same
time.&lt;/p&gt;
&lt;h2&gt;Alerting on it properly&lt;/h2&gt;
&lt;p&gt;Two mechanisms, and you want both.&lt;/p&gt;
&lt;p&gt;A scheduled check that reports credentials expiring within 30 days, running
weekly, emailing somebody. Simple, and it works as long as the job itself is
monitored, which means it must exit non-zero on failure rather than reporting
nothing.&lt;/p&gt;
&lt;p&gt;And a detection on credentials being &lt;strong&gt;added&lt;/strong&gt;, which is the security half. A
new secret appearing on an existing app registration is a recognised persistence
technique: an attacker with sufficient privilege adds their own credential to an
app that already has the access they want, and nothing else about the tenant
appears to change. That event is in &lt;code&gt;AuditLogs&lt;/code&gt;, it is rare, and it belongs in
the same category as the configuration drift rules in
&lt;a href=&quot;/notes/sentinel-analytics-rules-validation&quot;&gt;the Sentinel validation note&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;Expiring credentials is one of the ten checks in the
&lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt;, reported both ways: soonest expiry
for the queue, longest lifetime for the risk conversation.&lt;/p&gt;
&lt;p&gt;It pairs with &lt;a href=&quot;/notes/azure-rbac-stale-assignments&quot;&gt;the RBAC review&lt;/a&gt;, because
the two questions combine into the one that matters: what can authenticate
against this tenant, and does anybody still need it to.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Supplier risk assessment ISO 27001 wants, without a procurement department</title>
    <link href="https://acloud.solutions/notes/vendor-risk-review-small-company/"/>
    <id>https://acloud.solutions/notes/vendor-risk-review-small-company/</id>
    <updated>2026-06-16T09:00:00Z</updated>
    <published>2026-06-16T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>Supplier risk assessment ISO 27001 needs a register, tiering by data access, and the supplier&#x27;s own certification rather than a questionnaire you sent.</summary>
    <content type="html">&lt;p&gt;Somebody in marketing signed up for a transcription service with the company
card. It processes recordings of customer calls. It was fourteen pounds a month,
it solved a real problem, and nobody told you, because there is no process that
would have required them to.&lt;/p&gt;
&lt;p&gt;That is the shape of supplier risk at forty people. Not a procurement failure,
because there is no procurement. A supplier risk assessment iso 27001 asks for
under Annex A 5.19 to 5.23 has to work in an environment where anybody with a
card can onboard a data processor in four minutes.&lt;/p&gt;
&lt;h2&gt;Building the register, from what you already have&lt;/h2&gt;
&lt;p&gt;The register is the prerequisite for everything and people start it from memory,
which produces about half of it.&lt;/p&gt;
&lt;p&gt;Four sources, in order of yield:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The card statement.&lt;/strong&gt; Twelve months of it. Every recurring charge is a
supplier, and this catches the ones nobody mentioned.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your identity provider&#x27;s enterprise applications list.&lt;/strong&gt; Every SaaS product
anybody signed into with a work account, including the ones authorised by a user
rather than an administrator. This is frequently the most surprising list in the
company.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DNS and email records.&lt;/strong&gt; A supplier with a CNAME or a DKIM record in your zone
is integrated deeply enough to matter, and those records outlive the
relationship.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask the team.&lt;/strong&gt; Last, not first, because memory produces the obvious ones and
the sources above produce the rest.&lt;/p&gt;
&lt;p&gt;Expect the real number to be two to three times what anybody guessed.&lt;/p&gt;
&lt;h2&gt;Tiering by data access, not by spend&lt;/h2&gt;
&lt;p&gt;The instinct is to sort by cost. Cost is nearly irrelevant to risk.&lt;/p&gt;
&lt;p&gt;The transcription service at fourteen pounds a month processes customer
conversations. The accounting package at several hundred a month processes your
own invoices. One of those is a sub-processor of customer personal data and one
is not, and the cheap one is the problem.&lt;/p&gt;
&lt;p&gt;Three tiers are enough:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tier one: processes customer data, or has production access.&lt;/strong&gt; Hosting,
identity, anything embedded in the product, any sub-processor named in your
customer contracts. These get a real assessment and an annual review.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tier two: holds company data but not customer data.&lt;/strong&gt; Accounting, HR systems,
your code repository if it holds no customer data. Assessment at onboarding,
review on a longer cycle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tier three: no access to anything sensitive.&lt;/strong&gt; A design tool, a scheduling
app. Recorded in the register, no assessment.&lt;/p&gt;
&lt;p&gt;Tiering is what makes this maintainable. Forty suppliers assessed equally is a
job nobody completes. Eight tier one suppliers assessed properly and thirty-two
recorded is defensible and finishable.&lt;/p&gt;
&lt;h2&gt;Obtain their assurance rather than sending a questionnaire&lt;/h2&gt;
&lt;p&gt;This is the part most guidance gets backwards, and it is the difference between
a supplier programme that works and one that generates paperwork.&lt;/p&gt;
&lt;p&gt;The instinct is to build a vendor security questionnaire and send it to
suppliers. Resist it. For a company of forty, that approach fails in both
directions: large suppliers will ignore you, because you are not a material
customer and they have a trust portal precisely so they do not answer bespoke
questionnaires. Small suppliers will answer, and their answers are
self-assessed, unverified, and worth very little.&lt;/p&gt;
&lt;p&gt;What works instead is obtaining the assurance they already produce. Their ISO
27001 certificate, with the scope checked against what they do for you. Their
SOC 2 Type II report, requested under NDA. Their published sub-processor list.
Their status page history. Their breach disclosure history, which is a search
rather than a request.&lt;/p&gt;
&lt;p&gt;That is better evidence than a questionnaire because it is independently
verified, and it is less work for everybody. Where a supplier has none of it,
that absence is itself the finding, and the question becomes whether the risk is
acceptable rather than what they claim about their firewalls.&lt;/p&gt;
&lt;p&gt;The lever people forget is the contract. A data processing agreement with an
audit clause, and a requirement to notify you of sub-processor changes and of
breaches within a stated period, gives you more actual protection than any
questionnaire response. Getting that into the agreement at signature is easy;
adding it two years later is not.&lt;/p&gt;
&lt;h2&gt;What to actually check, per tier one supplier&lt;/h2&gt;
&lt;p&gt;Six things, and it takes under an hour once you know where to look.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Their certification, and its scope.&lt;/strong&gt; A certificate whose scope excludes the
service you use is a common and easily missed problem, the same trap as
&lt;a href=&quot;/notes/iso-27001-scope-statement&quot;&gt;your own scope statement&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A data processing agreement&lt;/strong&gt;, signed, covering the categories of data they
actually process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Their sub-processors.&lt;/strong&gt; Who they pass your data to. This is where data
residency questions come from, and it is the part customers ask you about.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where the data sits&lt;/strong&gt;, and where it can be accessed from, which are different
questions, as
&lt;a href=&quot;/notes/security-questionnaires-how-to-answer&quot;&gt;the questionnaire note&lt;/a&gt;
covers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Breach history&lt;/strong&gt;, from a search. Not disqualifying, and how they handled it is
informative.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What happens when it ends.&lt;/strong&gt; Data return or deletion, and whether you could
actually leave.&lt;/p&gt;
&lt;p&gt;Record the answers, the date, and your conclusion. The conclusion is the part
that matters, and &quot;acceptable, reviewed 2026-03-01, next review 2027-03-01&quot; is
what an auditor is looking for rather than a folder of PDFs.&lt;/p&gt;
&lt;h2&gt;The onboarding gate&lt;/h2&gt;
&lt;p&gt;Reviewing annually while anybody can onboard a supplier in four minutes means
the register is always out of date.&lt;/p&gt;
&lt;p&gt;The gate that works at this size is not a procurement process, it is one
question in the expense approval path: does this handle customer data. If yes,
it comes to you before the card is used. If no, it goes in the register and
nothing else happens.&lt;/p&gt;
&lt;p&gt;That is a single question, it is answerable by a non-technical person, and it
catches the tier one cases which are the only ones that matter urgently. A
heavier process gets routed around, and a supplier onboarded around the process
is worse than one onboarded through a light one.&lt;/p&gt;
&lt;h2&gt;The supplier risk assessment iso 27001 asks for, without procurement&lt;/h2&gt;
&lt;p&gt;Controls 5.19 through 5.23 cover supplier relationships, addressing security
within agreements, managing the ICT supply chain, monitoring and review, and
managing changes to supplier services. Written for organisations with a
procurement function, and satisfiable without one.&lt;/p&gt;
&lt;p&gt;What satisfies them at forty people: a register, a tiering rule, evidence of
assurance obtained for tier one, DPAs in place, an annual review with dates and
conclusions, and the onboarding question above. That is a page of process and a
spreadsheet, and it is genuinely what the controls ask for.&lt;/p&gt;
&lt;p&gt;The one that lapses in year two is the review, because nothing prompts it, which
is &lt;a href=&quot;/notes/iso-27001-surveillance-audit&quot;&gt;the surveillance audit pattern&lt;/a&gt;. Put
it in the calendar the week you finish the first one.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; covers the supplier controls in detail, and the
&lt;a href=&quot;https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/accountability-and-governance/contracts-and-liabilities-between-controllers-and-processors/&quot;&gt;ICO&#x27;s guidance on processor contracts&lt;/a&gt;
sets out what a data processing agreement has to contain, which is the half of
this that is a legal requirement rather than a standard&#x27;s requirement.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>IT documentation best practices small business advice keeps missing</title>
    <link href="https://acloud.solutions/notes/documentation-nobody-reads/"/>
    <id>https://acloud.solutions/notes/documentation-nobody-reads/</id>
    <updated>2026-06-09T09:00:00Z</updated>
    <published>2026-06-09T09:00:00Z</published>
    <category term="Running IT alone"/>
    <summary>IT documentation best practices small business advice misses the obvious: three pages get read constantly and the wiki does not. Write those three.</summary>
    <content type="html">&lt;p&gt;The wiki has ninety-one pages. Fourteen were written in a burst two years ago
and describe a system that has since been replaced. The most recently edited
page is the one you updated last week, and you are also the only person who has
opened any of them this quarter.&lt;/p&gt;
&lt;p&gt;Meanwhile three specific pages get read constantly, mostly by you, mostly at
speed, and two of them are not in the wiki at all.&lt;/p&gt;
&lt;h2&gt;What it documentation best practices small business guidance gets wrong&lt;/h2&gt;
&lt;p&gt;The standard advice is to document comprehensively. Cover everything, keep it
current, structure it well. That advice is not incorrect so much as
unachievable by one person, and the failure is not partial: a wiki that is 40
percent current is worse than one that is obviously incomplete, because a reader
cannot tell which 40 percent.&lt;/p&gt;
&lt;p&gt;The alternative is not to document less. It is to be honest that documentation
serves two entirely different purposes, which pull in opposite directions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Documentation people use&lt;/strong&gt; is short, findable under stress, and tells you what
to do. Its enemy is length.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Documentation that satisfies a requirement&lt;/strong&gt; is complete, approved, versioned
and reviewed. Its enemy is drift.&lt;/p&gt;
&lt;p&gt;Trying to make one artefact do both produces a document that is too long to
follow and too informal to audit. Separating them is the whole technique, and it
is the same policy-plus-procedure split as
&lt;a href=&quot;/notes/iso-27001-policies-people-read&quot;&gt;the ISO 27001 policies note&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The three pages that get read&lt;/h2&gt;
&lt;p&gt;Consistently, across every small company I have worked in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to get emergency access.&lt;/strong&gt; Where the break-glass credentials are, how to
retrieve them, and what to do afterwards. Read exactly when something is badly
wrong, so it has to be findable when the usual systems are not available. That
constraint rules out putting it in the wiki that requires the identity provider
you cannot reach, which is
&lt;a href=&quot;/notes/break-glass-accounts&quot;&gt;the circular dependency&lt;/a&gt; people build without
noticing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The leaver checklist.&lt;/strong&gt; Read every time somebody leaves, by whoever is
available, under time pressure, with a compliance consequence for getting it
wrong. This one should be a script rather than a page, per
&lt;a href=&quot;/notes/joiner-mover-leaver-automation-graph&quot;&gt;the offboarding note&lt;/a&gt;, and the
page is then about how to run the script and what to check.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who to call.&lt;/strong&gt; Which supplier, which support contract, which account number,
which escalation path. Nobody memorises this and everybody needs it at the worst
moment. It is the single highest-value page in most companies and it is usually
stale, because supplier contacts change and nothing prompts a review.&lt;/p&gt;
&lt;p&gt;Get those three genuinely right and you have covered most of the actual reading.
Everything else is reference material consulted occasionally, which is a lower
bar.&lt;/p&gt;
&lt;h2&gt;What makes a page usable under stress&lt;/h2&gt;
&lt;p&gt;Different properties from what makes a page complete.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Findable without search.&lt;/strong&gt; If retrieving it depends on remembering a title or
on a working search index, it fails at the moment it matters. Three pinned
links, or a printed card in a drawer for the emergency one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Answers &quot;what do I do&quot; in the first screen.&lt;/strong&gt; Context and rationale below the
steps, not above. Somebody reading this is not curious, they are stuck.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;States its own freshness.&lt;/strong&gt; A date and an owner at the top. A reader can then
weigh it. An undated page is either current or two years stale and there is no
way to tell.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Names systems as they appear on screen.&lt;/strong&gt; Not &quot;the identity platform&quot;. The
actual name in the actual portal, because the reader is looking at the portal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Says what success looks like.&lt;/strong&gt; &quot;You will see the account status change to
Disabled.&quot; Otherwise somebody stops halfway and cannot tell whether it worked.&lt;/p&gt;
&lt;h2&gt;Where the ISO 27001 requirement diverges&lt;/h2&gt;
&lt;p&gt;Clause 7.5 covers documented information: it has to be identified, in a suitable
format, reviewed and approved, available where needed, and protected. Annex A
adds specific documents.&lt;/p&gt;
&lt;p&gt;That overlaps with usefulness in one place and diverges in two.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The overlap.&lt;/strong&gt; Both want a named owner and a review date. Do that once and it
serves both.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The divergence on length.&lt;/strong&gt; The standard does not ask for long documents, but
audit anxiety produces them, and a forty-page procedure is unusable. Keep the
procedure short and let the evidence do the proving.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The divergence on audience.&lt;/strong&gt; A leaver script&#x27;s output is better audit
evidence than any document, because it shows the process ran rather than
asserting that it exists. So the thing satisfying the requirement is a report,
not a page, and
&lt;a href=&quot;/notes/audit-evidence-automation&quot;&gt;scheduled evidence&lt;/a&gt; covers more of clause 7.5
than a wiki ever will.&lt;/p&gt;
&lt;h2&gt;The runbook that is worth writing properly&lt;/h2&gt;
&lt;p&gt;Beyond the three, there is one category worth real effort: whatever you would
have to do during an incident.&lt;/p&gt;
&lt;p&gt;The NCSC&#x27;s
&lt;a href=&quot;https://www.ncsc.gov.uk/collection/incident-management&quot;&gt;incident management guidance&lt;/a&gt;
is a reasonable structure to borrow, and the part that matters for a small
company is having decided in advance who declares an incident, who talks to
customers, and who can authorise spending. Those three decisions are slow to
make under pressure and fast to write down beforehand.&lt;/p&gt;
&lt;p&gt;What makes an incident runbook different from other documentation is that it
will be read by somebody stressed, possibly not you, possibly at three in the
morning, and possibly on a phone. So it is a sequence of decisions with names
against them rather than a description of systems. The systems are documented
elsewhere; the runbook is about who does what and in what order.&lt;/p&gt;
&lt;p&gt;This is also the document
&lt;a href=&quot;/notes/bcdr-tabletop-exercise-small-company&quot;&gt;a tabletop exercise&lt;/a&gt; tests, and
the most common finding from a first exercise is that nobody could find it. That
is a documentation finding rather than a process one, and it is fixed by
pinning a link rather than by writing more.&lt;/p&gt;
&lt;h2&gt;What to do with the ninety-one pages&lt;/h2&gt;
&lt;p&gt;Not a rewrite, which will not finish.&lt;/p&gt;
&lt;p&gt;Mark them. A one-line banner at the top of each: current, unverified, or
superseded. That takes an afternoon for ninety-one pages because you are not
reading them properly, only classifying them, and it makes the whole wiki usable
immediately, because a reader can now tell which pages to trust.&lt;/p&gt;
&lt;p&gt;Then delete the superseded ones rather than archiving them. An archived page
still appears in search results, which is the entire problem.&lt;/p&gt;
&lt;p&gt;The remaining unverified ones get promoted to current when somebody next uses
them and finds them correct. That distributes the verification across the year
and attaches it to actual use, which is the only mechanism that survives.&lt;/p&gt;
&lt;h2&gt;The honest test&lt;/h2&gt;
&lt;p&gt;For each page, ask when it was last read by somebody other than its author. If
the answer is never, it is not documentation, it is notes, and that is fine as
long as nobody is relying on it.&lt;/p&gt;
&lt;p&gt;Then ask the harder version: if you were unavailable for two weeks, which three
pages would somebody need. Write those properly. That is the whole job, and it
is also the only mitigation available for the key person risk that belongs
honestly in your &lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;risk register&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Microsoft 365 guest user cleanup: 340 externals, 12 of whom you can name</title>
    <link href="https://acloud.solutions/notes/microsoft-365-guest-access-cleanup/"/>
    <id>https://acloud.solutions/notes/microsoft-365-guest-access-cleanup/</id>
    <updated>2026-06-02T09:00:00Z</updated>
    <published>2026-06-02T09:00:00Z</published>
    <category term="Microsoft 365, Entra and Intune"/>
    <summary>Microsoft 365 guest user cleanup without deleting anyone active. Where guests come from, why sign-in date is a trap, and a sharing policy that holds.</summary>
    <content type="html">&lt;p&gt;Filter the user list by external and the number is always higher than expected.
Three hundred and forty, in a company of forty. You can name twelve of them.
About sixty have email addresses at domains you do not recognise, and at least
one is a personal Gmail address invited to a SharePoint folder in 2021.&lt;/p&gt;
&lt;p&gt;Microsoft 365 guest user cleanup is one of those jobs where the naive approach
is actively dangerous, because the obvious signal for &quot;this guest is inactive&quot; is
wrong in a way that takes real customers with it.&lt;/p&gt;
&lt;h2&gt;Where the 340 came from&lt;/h2&gt;
&lt;p&gt;Nobody sat down and invited three hundred people. They arrived through four
routes, all of which are working as designed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Teams meeting invitations.&lt;/strong&gt; An external participant in a Teams meeting can
end up as a guest object depending on tenant settings and how they joined. A
year of customer calls produces a lot of these.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SharePoint and OneDrive sharing.&lt;/strong&gt; The most productive source. Anyone with
sharing rights sends a link to an external address, and a guest object appears.
The person sharing had no idea they were creating a directory object, and they
were not doing anything wrong.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Teams channel membership&lt;/strong&gt;, where somebody adds an external collaborator to a
project team. Correct at the time, and the team outlives the project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Application and integration invitations.&lt;/strong&gt; A vendor&#x27;s support engineer invited
during onboarding, still there two years later.&lt;/p&gt;
&lt;p&gt;None of these routes has an exit. There is no process that removes a guest when
the project ends, because no system knows the project ended.&lt;/p&gt;
&lt;h2&gt;Why last sign-in is the wrong signal for microsoft 365 guest user cleanup&lt;/h2&gt;
&lt;p&gt;This is the part worth getting right before you delete anything, and it is the
mistake I have actually made.&lt;/p&gt;
&lt;p&gt;The obvious query sorts guests by last successful sign-in and treats a distant
date as evidence of dormancy. It is not reliable, because a B2B guest can access
your resources in ways that do not produce an interactive sign-in record against
your tenant in the way you would expect. Their home tenant authenticates them.
Depending on the resource and the access path, your view of their activity can
show nothing while they are using a shared document weekly.&lt;/p&gt;
&lt;p&gt;Delete on that basis and you remove live client contacts. It reads as a tidy-up
in your logs and as an access failure in their inbox, and the first you hear of
it is an email asking why a link stopped working. Deleted guest objects can be
restored within a window, but the access grants that referenced them are messier
to reconstruct.&lt;/p&gt;
&lt;p&gt;So treat the sign-in date as a prompt to investigate rather than a verdict. The
signals worth combining:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do they actually have access to.&lt;/strong&gt; A guest with no group memberships and
no resource permissions is genuinely removable regardless of dates. A guest who
is a member of an active Team is not, whatever the sign-in data says.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who invited them, and is that person still here.&lt;/strong&gt; The inviter is recorded on
the guest object. A guest invited by a leaver, for a project that finished, with
no current memberships, is the clear case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Does the domain still matter.&lt;/strong&gt; A guest at a domain you no longer do business
with is a different conversation from one at your largest customer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask.&lt;/strong&gt; For anything ambiguous, one message to the internal person who owns
that relationship resolves it in minutes. This is slower than a query and it is
the difference between a cleanup and an incident.&lt;/p&gt;
&lt;h2&gt;The review that works&lt;/h2&gt;
&lt;p&gt;Quarterly, in three passes, most restrictive first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pass one: guests with no memberships and no permissions.&lt;/strong&gt; These are pure
residue. Remove them. No conversation needed because there is nothing to remove
access to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pass two: guests whose inviter has left.&lt;/strong&gt; Find the current internal owner of
that relationship. If nobody claims it, remove. If somebody does, record who and
move on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pass three: everything else, by domain.&lt;/strong&gt; Group by email domain and review by
relationship rather than by person. &quot;Are we still working with this company&quot; is
a question somebody can answer, whereas &quot;should Sarah at this domain still have
access&quot; usually is not.&lt;/p&gt;
&lt;p&gt;Entra access reviews can automate the mechanics of this, including asking the
inviter to attest, and they produce the dated record an auditor wants. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/id-governance/access-reviews-overview&quot;&gt;access review documentation&lt;/a&gt;
covers the licensing, which needs P2 for the automated version, the same gate as
&lt;a href=&quot;/notes/privileged-identity-management-small-tenant&quot;&gt;PIM&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Without P2 the manual version is a spreadsheet and an afternoon, and it counts
just as much provided you write down what you decided.&lt;/p&gt;
&lt;h2&gt;Stopping the inflow&lt;/h2&gt;
&lt;p&gt;Cleaning up without changing the sharing policy means doing this again next
quarter with similar numbers.&lt;/p&gt;
&lt;p&gt;The settings worth changing, none of which stop legitimate work:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Default sharing links to &quot;specific people&quot; rather than &quot;anyone&quot;.&lt;/strong&gt; Anonymous
links do not create guest objects but they also cannot be reviewed, which is
worse. Specific-people links create a reviewable object.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Set an expiry on guest access&lt;/strong&gt; where your licensing supports it, so access
lapses by default and has to be renewed deliberately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Restrict who can invite guests.&lt;/strong&gt; Not to administrators only, which creates a
bottleneck people route around, but not to everyone either.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Turn off guest creation from Teams meetings&lt;/strong&gt; if you do not need it, which most
companies do not.&lt;/p&gt;
&lt;p&gt;The one to resist is disabling external sharing entirely. Somebody will need to
send a file to a customer, and if the platform will not let them they will use
personal email or a consumer file service, which removes the visibility you were
trying to gain.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;Guests are one of the categories in
&lt;a href=&quot;/notes/conditional-access-policies-small-business&quot;&gt;the Conditional Access set&lt;/a&gt;,
where restricting what a guest can reach is a policy rather than a review. The
two work together: policy limits the blast radius, review removes what is no
longer needed.&lt;/p&gt;
&lt;p&gt;If a customer questionnaire has asked you about third-party access, this is the
control they mean, and it is one of
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance areas&lt;/a&gt; where the evidence is usually
missing rather than the practice.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>EU AI Act SaaS compliance: transparency now, high-risk later than you think</title>
    <link href="https://acloud.solutions/notes/eu-ai-act-saas-guide/"/>
    <id>https://acloud.solutions/notes/eu-ai-act-saas-guide/</id>
    <updated>2026-05-26T09:00:00Z</updated>
    <published>2026-05-26T09:00:00Z</published>
    <category term="AI and regulation"/>
    <summary>EU AI Act saas compliance after the Digital Omnibus: transparency applies now, high-risk moved to December 2027. What a small SaaS company must do.</summary>
    <content type="html">&lt;p&gt;Your product summarises support tickets using a third-party model. A customer&#x27;s
procurement team has asked how you comply with the EU AI Act. Somebody has
forwarded you an article about high-risk systems and conformity assessments, and
it is forty pages of obligations that appear to require a quality management
system.&lt;/p&gt;
&lt;p&gt;Almost none of that applies to you, and the parts that do have been in force
since August. Eu ai act saas compliance for a small B2B software company is
mostly a much smaller job than the coverage suggests, and it is more urgent,
which is an awkward combination.&lt;/p&gt;
&lt;h2&gt;What eu ai act saas compliance requires today&lt;/h2&gt;
&lt;p&gt;The dates that matter, from the Commission&#x27;s own
&lt;a href=&quot;https://ai-act-service-desk.ec.europa.eu/en/ai-act/timeline/timeline-implementation-eu-ai-act&quot;&gt;implementation timeline&lt;/a&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Obligation&lt;/th&gt;
&lt;th&gt;Applies from&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Prohibited practices&lt;/td&gt;
&lt;td&gt;2 February 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;General-purpose AI model obligations&lt;/td&gt;
&lt;td&gt;2 August 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majority of the rules, including Article 50 transparency&lt;/td&gt;
&lt;td&gt;2 August 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prohibitions on deepfakes and child abuse material&lt;/td&gt;
&lt;td&gt;2 December 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-risk systems under Annex III&lt;/td&gt;
&lt;td&gt;2 December 2027&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-risk embedded in regulated products under Annex I&lt;/td&gt;
&lt;td&gt;2 August 2028&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note the ordering. Transparency is already live. High-risk is over a year away
for standalone systems and nearly two for embedded ones.&lt;/p&gt;
&lt;p&gt;That is not the original schedule. High-risk obligations for Annex III systems
were due on 2 August 2026 and were deferred by the Digital Omnibus on AI,
adopted as
&lt;a href=&quot;https://eur-lex.europa.eu/eli/reg/2026/1744/oj/eng&quot;&gt;Regulation (EU) 2026/1744&lt;/a&gt;,
which entered into force on 27 July 2026. The Commission&#x27;s
&lt;a href=&quot;https://digital-strategy.ec.europa.eu/en/news/ai-omnibus-enters-force&quot;&gt;announcement&lt;/a&gt;
describes it as targeted simplification, and alongside the deferral it expanded
regulatory sandboxes, simplified obligations for small and mid-cap companies,
and streamlined registration for exempted systems.&lt;/p&gt;
&lt;p&gt;The mechanism matters as much as the dates. The timeline was changed by a
regulation amending the original regulation, which means it can be changed
again. Treat any date here as current rather than settled, and check the
timeline page before making a commercial commitment on the strength of it.&lt;/p&gt;
&lt;h2&gt;Which obligations you are actually under&lt;/h2&gt;
&lt;p&gt;This is where most reading goes wrong, because the Act imposes different duties
on different roles and the words are specific.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Provider&lt;/strong&gt; means you develop an AI system and put it on the market under your
own name. If your product has an AI feature that your customers use, you are
probably a provider of that AI system, even though the model underneath is
somebody else&#x27;s.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deployer&lt;/strong&gt; means you use an AI system in your own operations. If your support
team uses a third-party AI tool internally, you are a deployer of it.&lt;/p&gt;
&lt;p&gt;You are frequently both, in different directions, and the obligations differ.&lt;/p&gt;
&lt;p&gt;The one worth correcting explicitly: &lt;strong&gt;Article 26 covers deployers of high-risk
systems&lt;/strong&gt;, so it tracks the high-risk timeline rather than applying now. A lot
of commentary implies deployer obligations are live for everybody. For a
non-high-risk system they largely are not, and the duties that do apply to you
today are the transparency and literacy ones below.&lt;/p&gt;
&lt;h2&gt;Article 50, which is live and probably applies&lt;/h2&gt;
&lt;p&gt;Article 50 covers transparency, and it is the obligation most likely to touch a
B2B SaaS product. In broad terms it requires that people are told when they are
interacting with an AI system, and that certain generated or manipulated content
is disclosed or marked as such.&lt;/p&gt;
&lt;p&gt;For a typical product that means three practical things.&lt;/p&gt;
&lt;p&gt;If a user talks to a chatbot or an assistant, it should be evident that it is an
AI system rather than a person. In practice this is a label, not a legal notice.&lt;/p&gt;
&lt;p&gt;If your product generates content that a person might take for human-authored or
authentic, that needs to be disclosed. The marking and detection requirements
have transitional arrangements for systems that were already on the market, and
the detail there is worth reading in the text rather than taking from a summary,
including this one.&lt;/p&gt;
&lt;p&gt;If you use AI for emotion recognition or biometric categorisation, there are
specific and stricter duties. Most B2B SaaS does not, and if you do, this note is
not sufficient.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Article 4&lt;/strong&gt; covers AI literacy, and it applies to providers and deployers now.
The Omnibus amended it: the Commission&#x27;s
&lt;a href=&quot;https://digital-strategy.ec.europa.eu/en/faqs/ai-literacy-questions-answers&quot;&gt;AI literacy questions and answers&lt;/a&gt;
states that literacy remains an obligation for providers and deployers but no
specific sufficient level is mandated, while for deployers of high-risk systems
the obligation to train staff for human oversight remains. So the duty is real
and the bar is not numerically defined, which in practice means doing something
deliberate and recording it.&lt;/p&gt;
&lt;h2&gt;What to do, in about a day&lt;/h2&gt;
&lt;p&gt;Five things, none of which require a lawyer to start.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Build an inventory.&lt;/strong&gt; Every feature that uses AI, the model, the provider,
what data goes to it, the purpose, and who uses it. This is the artefact
everything else hangs off and it is
&lt;a href=&quot;/notes/ai-system-inventory&quot;&gt;a separate note&lt;/a&gt; because it is the piece of work
that actually takes time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Classify each entry.&lt;/strong&gt; Prohibited, high-risk, limited-risk with transparency
duties, or minimal. Most B2B SaaS features land in the third or fourth
category. Write down the reasoning, because the reasoning is the thing you will
be asked for.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fix the transparency gaps.&lt;/strong&gt; Where a user interacts with an AI system and it
is not obvious, make it obvious. This is usually a label and a line in the
documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do something about literacy and record it.&lt;/strong&gt; A short internal session on what
the tools are, what data must not go into them, and who to ask. Dated, with an
attendance list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Check the supplier side.&lt;/strong&gt; Your model provider is a supplier processing your
data, which makes this
&lt;a href=&quot;/notes/vendor-risk-review-small-company&quot;&gt;a supplier assessment&lt;/a&gt; and a data
processing question rather than a novel one.&lt;/p&gt;
&lt;h2&gt;What ISO 27001 already covers&lt;/h2&gt;
&lt;p&gt;If you hold ISO 27001, a good deal of this exists under different labels.&lt;/p&gt;
&lt;p&gt;Your asset register becomes the basis for the AI system inventory. Your supplier
assessments cover the model providers. Your risk register can take AI-specific
risks as new entries rather than needing a parallel process. Your change
management covers releasing a feature that calls a model. Your data flow
documentation covers what leaves your estate.&lt;/p&gt;
&lt;p&gt;What is genuinely new is the classification exercise and the transparency
obligations. Everything else is re-labelling, which is the useful thing to know
before somebody proposes buying an AI governance platform.&lt;/p&gt;
&lt;p&gt;If you do not hold ISO 27001, doing the inventory and the supplier assessments
now is not wasted work, because it is the same material
&lt;a href=&quot;/notes/iso-27001-on-your-own&quot;&gt;certification&lt;/a&gt; will ask for.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Does the AI Act apply to a UK company?&lt;/h3&gt;
&lt;p&gt;It can. The Act has extraterritorial reach where an AI system&#x27;s output is used
in the EU, so a UK SaaS company with EU customers may be in scope. This is a
question to take advice on rather than to settle from a blog post, and it turns
on specifics of who your users are and where.&lt;/p&gt;
&lt;h3&gt;We only use a third-party model through an API. Are we a provider?&lt;/h3&gt;
&lt;p&gt;Possibly. Putting an AI system on the market under your own name can make you a
provider even where the underlying model is somebody else&#x27;s, and the model
provider has its own separate obligations. This is the distinction most worth
getting right and most worth taking advice on if the answer is commercially
material.&lt;/p&gt;
&lt;h3&gt;Was the high-risk deadline really moved?&lt;/h3&gt;
&lt;p&gt;Yes. Annex III high-risk obligations moved from 2 August 2026 to 2 December
2027, and Annex I to 2 August 2028, by Regulation (EU) 2026/1744, in force since
27 July 2026. Since the timeline has already changed once by amendment, check
the Commission&#x27;s timeline page rather than relying on any secondary source.&lt;/p&gt;
&lt;h3&gt;Do we need an AI governance platform?&lt;/h3&gt;
&lt;p&gt;Almost certainly not at forty people. The obligations that apply to you today
are an inventory, a classification with reasoning, some transparency labels, a
literacy session and a supplier assessment. That is a spreadsheet and a day,
and the same argument applies as for
&lt;a href=&quot;/notes/compliance-automation-platforms-worth-it&quot;&gt;compliance automation platforms&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;What happens if we do nothing?&lt;/h3&gt;
&lt;p&gt;For a non-high-risk product the immediate exposure is commercial rather than
regulatory: customers are already asking, and an unanswerable questionnaire
costs you deals long before an authority takes an interest. The transparency
obligations are in force, so doing nothing is not a neutral position, but the
realistic pressure arrives through procurement first.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>PowerShell exit codes: scheduled scripts that fail loudly</title>
    <link href="https://acloud.solutions/notes/powershell-scripts-exit-codes-logging/"/>
    <id>https://acloud.solutions/notes/powershell-scripts-exit-codes-logging/</id>
    <updated>2026-05-19T09:00:00Z</updated>
    <published>2026-05-19T09:00:00Z</published>
    <category term="Automation"/>
    <summary>PowerShell exit codes decide whether your scheduler notices a failure. Why scripts print Done and exit 0 regardless, and the traps that cause it.</summary>
    <content type="html">&lt;p&gt;The nightly job has been green for eight months. Somebody finally opens the
output and it says &quot;Processed 0 records. Done.&quot; It has said that for eight
months, because the credential expired in the spring and the script treated an
authentication failure the same way it treats a quiet night.&lt;/p&gt;
&lt;p&gt;Powershell exit codes are the difference between monitoring and the appearance
of monitoring. A scheduler cannot read your output. It reads one integer, and if
that integer is always zero then every alerting rule built on top of it is
decoration.&lt;/p&gt;
&lt;h2&gt;Why powershell exit codes end up wrong&lt;/h2&gt;
&lt;p&gt;Three specific traps, all of which I have shipped.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;#Requires -Modules&lt;/code&gt; with &lt;code&gt;pwsh -File&lt;/code&gt;.&lt;/strong&gt; If the module is missing, the
requires statement stops the script before it runs. Reasonable. What is not
reasonable is that invoking the file this way returns exit code 0 in that
situation, so the scheduler sees a clean run of a script that never executed a
line. The fix is to check for the module in code and exit deliberately, keeping
&lt;code&gt;#Requires -Version&lt;/code&gt; for the things that behave correctly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A populated context that is not a valid session.&lt;/strong&gt; &lt;code&gt;Get-AzContext&lt;/code&gt; returns a
fully populated context object when the cached token behind it has expired. So
the obvious connection check passes, the enumeration returns nothing because
every call is failing, and the script reports no findings. The only reliable
test is to acquire a token and treat failure as fatal:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;function Assert-AzConnection {
    $ctx = Get-AzContext
    if (-not $ctx -or -not $ctx.Account) {
        Write-Error &#x27;Not connected. Run Connect-AzAccount.&#x27;
        exit 1
    }
    # A context object is not proof of a live token. Force an acquisition.
    try   { $null = Get-AzAccessToken -ErrorAction Stop -WarningAction SilentlyContinue }
    catch { Write-Error &amp;quot;Cannot acquire a token: $($_.Exception.Message)&amp;quot;; exit 1 }
    return $ctx
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Non-terminating errors, which are most of them.&lt;/strong&gt; Many cmdlets report failure
without throwing, so a &lt;code&gt;try&lt;/code&gt; block never triggers and &lt;code&gt;$?&lt;/code&gt; is the only sign
anything went wrong. Setting &lt;code&gt;$ErrorActionPreference = &#x27;Stop&#x27;&lt;/code&gt; at the top of a
script converts these to exceptions, which is almost always what you want in
something scheduled and unattended.&lt;/p&gt;
&lt;h2&gt;The distinction that matters&lt;/h2&gt;
&lt;p&gt;Every scheduled script needs to distinguish three outcomes, and most
distinguish two.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Did the work, found nothing.&lt;/strong&gt; Exit 0. This is a legitimate success and it is
what a healthy estate looks like.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Did the work, found things.&lt;/strong&gt; Exit 0, with the findings in the output. Findings
are not failures; a cost script that exits non-zero because it found orphaned
disks will be muted within a week.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Could not do the work.&lt;/strong&gt; Exit non-zero. Authentication failed, a module is
missing, an API returned 403, the subscription list came back empty when it
should not have.&lt;/p&gt;
&lt;p&gt;The third case is the one that gets collapsed into the first, and it is the
expensive one. A clean report from an empty search looks exactly like good news,
which is why it survives for eight months.&lt;/p&gt;
&lt;p&gt;Worth adding a fourth if the script covers multiple scopes: partial success.
Enumerated seven of nine subscriptions, failed on two. That is not a success and
it is not a total failure, and exiting non-zero with the two named in the output
is more useful than either extreme.&lt;/p&gt;
&lt;h2&gt;Logging that is worth having&lt;/h2&gt;
&lt;p&gt;Console output is not a log, because nobody kept it.&lt;/p&gt;
&lt;p&gt;Write structured records rather than sentences. A line per operation with a
timestamp, a level, the target, and the outcome. It does not need to be JSON,
though JSON costs nothing and makes the file greppable by field later.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;function Write-Log {
    param(
        [ValidateSet(&#x27;INFO&#x27;,&#x27;WARN&#x27;,&#x27;ERROR&#x27;)] [string] $Level,
        [string] $Message,
        [string] $Target = &#x27;&#x27;
    )
    $line = [pscustomobject]@{
        ts      = (Get-Date).ToUniversalTime().ToString(&#x27;o&#x27;)
        level   = $Level
        target  = $Target
        message = $Message
    }
    $line | ConvertTo-Json -Compress | Add-Content -Path $script:LogPath
    if ($Level -eq &#x27;ERROR&#x27;) { Write-Error $Message } else { Write-Verbose $Message }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Three things that make a log useful six months later. Timestamps in UTC with an
offset, because a scheduled job on a machine that observes daylight saving will
otherwise produce an hour you cannot reason about. The target of each operation,
so a failure names the resource rather than the step. And a record of what was
skipped and why, because &quot;skipped&quot; is the outcome that most often needs
explaining and least often gets recorded.&lt;/p&gt;
&lt;p&gt;Do not log secrets. Obvious, and it happens anyway when somebody logs a whole
request object for debugging and leaves it in.&lt;/p&gt;
&lt;h2&gt;Exit codes worth using&lt;/h2&gt;
&lt;p&gt;A single non-zero code is enough to be alerted. Distinct codes are enough to
know what happened without opening the log, which matters at 7am.&lt;/p&gt;
&lt;p&gt;The convention I use, and any consistent one beats none:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;0&lt;/strong&gt; ran, whatever it found&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1&lt;/strong&gt; could not authenticate, or the token was not usable&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2&lt;/strong&gt; a prerequisite was missing, such as a module or a parameter&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3&lt;/strong&gt; ran but could not cover everything asked of it, the partial case&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4&lt;/strong&gt; the target was not in the expected state, such as an account that was
  already deleted before an offboarding started&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep them under 125 and away from 0, and avoid the range above 128 on
Unix-like hosts, where those values carry signal meanings.&lt;/p&gt;
&lt;p&gt;The value of separating 1 from 2 is that they have different owners. An
authentication failure is usually a credential that expired, which is a person
to chase and often predictable from
&lt;a href=&quot;/notes/expiring-credentials-app-registrations&quot;&gt;the credential expiry note&lt;/a&gt;. A
missing prerequisite is a host that changed, which is a different fix. Getting
that from the exit code rather than from reading output saves the first five
minutes of every incident, and those five minutes are when you decide how
worried to be.&lt;/p&gt;
&lt;h2&gt;Making the scheduler act on it&lt;/h2&gt;
&lt;p&gt;Exit codes only matter if something reads them.&lt;/p&gt;
&lt;p&gt;In an Azure Automation runbook, a non-zero exit or an unhandled terminating
error marks the job Failed, and you can alert on job status. In a pipeline, the
step fails and the run goes red. In Task Scheduler, the last result code is
recorded and can trigger an action.&lt;/p&gt;
&lt;p&gt;The check worth doing on anything you already have scheduled: deliberately
break it. Revoke the credential, or point it at a subscription it cannot see,
and confirm the scheduler goes red. If it goes green, you have found a job whose
monitoring has always been decorative, and it will not be the only one.&lt;/p&gt;
&lt;p&gt;That test takes ten minutes and is more informative than reading the script.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;This is the property behind the read-only tooling in
&lt;a href=&quot;/notes/read-only-by-default&quot;&gt;the Azure notes&lt;/a&gt;: a check that cannot look must
not report a clean result. It applies identically to
&lt;a href=&quot;/notes/joiner-mover-leaver-automation-graph&quot;&gt;leaver automation&lt;/a&gt;, where a
partially completed offboarding reporting success is the worst available
outcome.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-exceptions&quot;&gt;documentation on PowerShell error handling&lt;/a&gt;
covers the terminating and non-terminating distinction properly, which is worth
reading once because it is the root of most of this.&lt;/p&gt;
&lt;p&gt;Automation handed over as part of &lt;a href=&quot;/consulting/&quot;&gt;consulting work&lt;/a&gt; is written to
this standard, because a script that lies is worse than no script and takes
longer to discover.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>An Azure tagging strategy people will actually follow</title>
    <link href="https://acloud.solutions/notes/azure-tagging-strategy-that-survives/"/>
    <id>https://acloud.solutions/notes/azure-tagging-strategy-that-survives/</id>
    <updated>2026-05-12T09:00:00Z</updated>
    <published>2026-05-12T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>Most tag policies die within a quarter. An Azure tagging strategy that survives has four tags, real enforcement, and a use nobody argues with.</summary>
    <content type="html">&lt;p&gt;The document is called something like &quot;Cloud Resource Tagging Standard v2.1&quot;. It
specifies eleven mandatory tags including &lt;code&gt;BusinessUnit&lt;/code&gt;, &lt;code&gt;DataClassification&lt;/code&gt;
and &lt;code&gt;CostCentreSubCode&lt;/code&gt;. It was approved in March. By June the newest resources
have three tags, two of which are misspelt, and the tag report is the thing
nobody opens.&lt;/p&gt;
&lt;p&gt;An azure tagging strategy fails for one of two reasons. Either it asks for
information the person creating the resource does not have, or it is not
enforced, which makes it a suggestion. Usually both.&lt;/p&gt;
&lt;h2&gt;An azure tagging strategy of four tags, and why these four&lt;/h2&gt;
&lt;p&gt;Every tag you require is a small tax on creating a resource. Charge as little as
possible, and only for things you will actually use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;owner&lt;/code&gt;.&lt;/strong&gt; An email address, not a team name. Teams reorganise and their names
change; a mailbox either resolves or it does not. This is the single most
valuable tag because it converts &quot;what is this&quot; into a question you can ask
somebody.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;cost-centre&lt;/code&gt;.&lt;/strong&gt; Whatever finance actually uses. Not a name you invented, and
not a hierarchy: a flat code that matches what appears on an internal recharge,
because a tag finance cannot map to their own system is a tag with no purpose.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;environment&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;prod&lt;/code&gt;, &lt;code&gt;nonprod&lt;/code&gt;, or whatever two or three values you really
distinguish. Resist five. The value of this tag is that it makes &quot;can I switch
this off&quot; answerable, and that question only has two interesting answers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;expires&lt;/code&gt;.&lt;/strong&gt; A date, on anything temporary. This is the one most standards
omit and the one that does the most work, because it turns
&lt;a href=&quot;/notes/azure-idle-vms&quot;&gt;the idle VM conversation&lt;/a&gt; from a negotiation into a
diary entry. A machine tagged &lt;code&gt;expires: 2026-03-31&lt;/code&gt; in a resource group called
&lt;code&gt;rg-poc&lt;/code&gt; needs no discussion in April.&lt;/p&gt;
&lt;p&gt;Four tags. Anything else you want, add later once these four are actually
present, which will take longer than you expect.&lt;/p&gt;
&lt;h2&gt;Enforcement rather than nagging&lt;/h2&gt;
&lt;p&gt;A tag policy enforced by reminders is not a policy, it is a recurring
disappointment. Azure Policy has three effects worth knowing here, and choosing
between them is the whole design.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Audit&lt;/strong&gt; flags non-compliant resources without stopping anything. Useful for
finding out how bad it is, useless for stopping it getting worse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Modify&lt;/strong&gt; adds or inherits a tag automatically. This is the underrated one.
Inheriting &lt;code&gt;cost-centre&lt;/code&gt; from the resource group means nobody has to type it,
which means nobody types it wrong. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-policies&quot;&gt;tag governance documentation&lt;/a&gt;
covers the built-in definitions for inheritance, and they cover most of what a
small estate needs without writing custom policy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deny&lt;/strong&gt; blocks creation of a resource without the tag. Correct for &lt;code&gt;owner&lt;/code&gt; on
anything expensive, and a good way to make yourself unpopular if applied to
everything at once.&lt;/p&gt;
&lt;p&gt;The sequence that works: Modify for anything inheritable, Deny for &lt;code&gt;owner&lt;/code&gt; on
new resource groups only, Audit for the rest, and revisit in a quarter. Deny on
day one across a live subscription breaks somebody&#x27;s deployment pipeline within
the hour, and the policy gets removed rather than fixed.&lt;/p&gt;
&lt;h2&gt;The retrofit problem&lt;/h2&gt;
&lt;p&gt;New resources are the easy half. The existing several hundred are the reason
most tagging efforts stall.&lt;/p&gt;
&lt;p&gt;Do not try to tag everything. Sort by cost, tag the top twenty resources by
hand, and accept that a long tail of cheap resources will stay untagged
indefinitely. Tagging a load balancer that costs nothing achieves nothing except
making a percentage look better.&lt;/p&gt;
&lt;p&gt;Where resources are grouped sensibly, tag the resource group and let inheritance
do the work. Where they are not, the fastest route is usually to fix the
grouping rather than the tags, which is a bigger job and worth knowing about
before you promise a deadline.&lt;/p&gt;
&lt;h2&gt;When the report says untagged 61 percent&lt;/h2&gt;
&lt;p&gt;At which point somebody will ask you to get it to 100, and that is the moment to
push back with a better metric.&lt;/p&gt;
&lt;p&gt;Percentage of resources tagged is a vanity number. It treats a 4 pence public IP
and a 900 pound SQL instance as equal, and it can be improved by tagging cheap
things, which is effort with no outcome. The number that matters is &lt;strong&gt;percentage
of monthly spend attributable&lt;/strong&gt;, which is the same query weighted by cost.&lt;/p&gt;
&lt;p&gt;Untagged 61 percent of resources but only 8 percent of spend is a well-run
estate with a long tail. Untagged 12 percent of resources but 40 percent of
spend means one large untagged thing, and you should go and find out what it is
right now.&lt;/p&gt;
&lt;p&gt;That reframing also gives you a finish line. Attributing 95 percent of spend is
achievable and useful. Tagging every object is neither.&lt;/p&gt;
&lt;h2&gt;Reporting spend by tag&lt;/h2&gt;
&lt;p&gt;Once &lt;code&gt;cost-centre&lt;/code&gt; is populated on the expensive things, the Cost Management
API will group by tag directly and you can produce the report finance keeps
asking for. Two practical notes learned the hard way.&lt;/p&gt;
&lt;p&gt;Tags are case-preserving but comparisons are not always case-insensitive
depending on the surface you query, so &lt;code&gt;Prod&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt; will bite you at some
point. Pick lower case, enforce it in policy, and normalise on the way in.&lt;/p&gt;
&lt;p&gt;And a tag applied today does not retroactively tag last month&#x27;s usage. Cost data
is stamped with the tags that were present when the usage occurred, so the first
month after a tagging push will still look mostly unattributed. That is not a
bug and it is worth warning people about before they see the report and conclude
the exercise failed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/tools/azclean-reporting/&quot;&gt;AzClean Reporting&lt;/a&gt; handles the spend-by-tag output
and the attribution percentage, which is the version worth showing somebody
rather than the raw compliance count.&lt;/p&gt;
&lt;h2&gt;The one rule&lt;/h2&gt;
&lt;p&gt;A tag nobody consumes will not survive, however well enforced. Before adding a
tag to the standard, name the query that reads it and the person who runs that
query. If you cannot, the tag is documentation of an intention rather than
infrastructure metadata, and it will be wrong within two quarters.&lt;/p&gt;
&lt;p&gt;That is why &lt;code&gt;owner&lt;/code&gt; and &lt;code&gt;expires&lt;/code&gt; outlast &lt;code&gt;DataClassification&lt;/code&gt; in practice.
Somebody uses them every month.&lt;/p&gt;
&lt;p&gt;If you are starting from nothing, the order that works is: run
&lt;a href=&quot;/notes/orphaned-azure-resources&quot;&gt;the orphan sweep&lt;/a&gt; first so you are not tagging
things you are about to delete, then tag the twenty most expensive survivors by
hand, then turn on inheritance. Tagging before deleting is how estates end up
with a tidy inventory of waste.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure RBAC review: finding the Owners who left in 2022</title>
    <link href="https://acloud.solutions/notes/azure-rbac-stale-assignments/"/>
    <id>https://acloud.solutions/notes/azure-rbac-stale-assignments/</id>
    <updated>2026-05-05T09:00:00Z</updated>
    <published>2026-05-05T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>An Azure RBAC review finds assignments to deleted identities, Owners at subscription scope, and guests with standing access. What to remove first.</summary>
    <content type="html">&lt;p&gt;Open the Access control blade on a subscription and sort by role. Somewhere near
the top there will be a row where the name is a greyed-out GUID and the portal
says &quot;Identity not found&quot;. That is a role assignment pointing at a security
principal that no longer exists, and it has been there since somebody was
offboarded without anyone thinking about Azure.&lt;/p&gt;
&lt;p&gt;An azure rbac review is mostly about three categories: assignments to things
that are gone, assignments broader than anyone intended, and assignments to
people outside the company.&lt;/p&gt;
&lt;h2&gt;What an azure rbac review turns up&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Orphaned assignments.&lt;/strong&gt; The &quot;Identity not found&quot; rows. A user, group or
service principal was deleted and the role assignment survived it. These are not
a live risk, because the principal cannot authenticate. They are worth removing
anyway for two reasons: they make the access list unreadable, and an
authorisation record referring to an unidentifiable subject is awkward to
explain to an auditor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Owner at subscription scope.&lt;/strong&gt; Almost always broader than the job requires.
Owner adds the ability to grant access to others, which is the part that matters:
a Contributor can break things, an Owner can hand out the ability to break
things. On a small estate you want one or two Owners, ideally not the same
accounts people use daily, and everyone else scoped to a resource group with
Contributor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Guests with standing access.&lt;/strong&gt; External accounts invited for a project that
ended. They still authenticate, they still have whatever was granted, and unlike
your own staff they do not appear in any leaver process. Nobody tells you when a
contractor&#x27;s engagement finishes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Direct assignments where a group would do.&lt;/strong&gt; Not a risk, a maintainability
problem. Twelve individual assignments will be reviewed twelve times and removed
never, whereas one group membership is a single thing to check.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Classic administrators&lt;/strong&gt;, if the subscription is old enough. Co-Administrator
and Service Administrator predate RBAC and are invisible in the modern access
list unless you go looking.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles&quot;&gt;built-in roles reference&lt;/a&gt;
is worth having open while you do this, because the useful move is usually
replacing a broad role with a narrow built-in one rather than writing a custom
definition. There is very often an existing role that covers exactly the job.&lt;/p&gt;
&lt;h2&gt;Reading it&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Get-AzRoleAssignment&lt;/code&gt; returns everything at and above the scope you ask for,
which is worth knowing because it means the same inherited assignment appears at
every child scope and inflates the list.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-AzSubscription | ForEach-Object {
    $null = Set-AzContext -SubscriptionId $_.Id
    Get-AzRoleAssignment | ForEach-Object {
        [pscustomobject]@{
            Sub         = $_.Scope.Split(&#x27;/&#x27;)[2]
            Principal   = if ($_.DisplayName) { $_.DisplayName } else { &#x27;ORPHANED&#x27; }
            Type        = $_.ObjectType
            SignInName  = $_.SignInName
            Role        = $_.RoleDefinitionName
            Scope       = $_.Scope
            # Assignments made at this exact scope, as opposed to inherited.
            Direct      = $_.Scope -eq &amp;quot;/subscriptions/$($_.Scope.Split(&#x27;/&#x27;)[2])&amp;quot;
        }
    }
} | Where-Object { $_.Principal -eq &#x27;ORPHANED&#x27; -or $_.Role -eq &#x27;Owner&#x27; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An empty &lt;code&gt;DisplayName&lt;/code&gt; is the orphan signal. The property is populated by
resolving the object ID against the directory, so a principal that no longer
exists comes back blank rather than raising an error.&lt;/p&gt;
&lt;p&gt;One caveat: resolving names requires directory read permission. Run this with
Reader on the subscription but nothing in Entra and every assignment looks
orphaned, which is a spectacular false positive and one I have generated. If
every row comes back blank, the problem is your permissions rather than their
access.&lt;/p&gt;
&lt;h2&gt;Removing things safely&lt;/h2&gt;
&lt;p&gt;Orphaned assignments are safe to remove. The principal does not exist, so
nothing can be using it. This is the only category where you can act without a
conversation.&lt;/p&gt;
&lt;p&gt;Owner reductions need care and a specific order. Confirm at least one other
Owner exists and can authenticate before removing anyone, because a subscription
with no Owner requires a support case to recover. Then reduce rather than
remove: Contributor at resource group scope covers most of what people actually
do, and the ones for whom it does not will tell you within a week.&lt;/p&gt;
&lt;p&gt;Guest removal needs a signal, and the obvious one is a trap worth naming. Do not
measure guest dormancy on last successful sign-in alone: a guest who uses your
resources through their own tenant may show no interactive sign-in against yours
while being entirely active. Check what they have access to and ask the person
who invited them, rather than deleting on a date field.&lt;/p&gt;
&lt;h2&gt;Cadence, and what an auditor wants&lt;/h2&gt;
&lt;p&gt;If you are heading for ISO 27001, this is Annex A 5.18 territory, and the
control asks for access rights to be reviewed at planned intervals. The word
doing the work is &lt;strong&gt;planned&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;An auditor is not checking whether your access list is perfect. They are
checking whether a review happened, on a stated schedule, and that something
came of it. That means three artefacts: the date, who did it, and the decisions,
including the ones where the decision was to leave access in place with a
reason.&lt;/p&gt;
&lt;p&gt;Quarterly for subscription-scope roles and guests is defensible at small scale.
Monthly if you are changing quickly, and the
&lt;a href=&quot;/notes/azure-security/&quot;&gt;azure security notes&lt;/a&gt; cover the other checks worth
folding into the same sitting so it becomes one recurring hour rather than five. The trap is a cadence you set ambitiously
and then miss, because a documented monthly review with three gaps in the year
is worse evidence than a documented quarterly one you actually did.&lt;/p&gt;
&lt;p&gt;Record the exceptions as decisions rather than leaving them undocumented. &quot;This
guest retains Contributor because they maintain the integration, reviewed
2026-10-16&quot; is evidence. Silently leaving it is a finding waiting to happen, and
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers what that evidence needs to look like in more detail.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Are orphaned role assignments a security risk?&lt;/h3&gt;
&lt;p&gt;Not directly, because the principal cannot authenticate. They are a hygiene and
evidence problem: they make the access list hard to read and hard to attest to.
Remove them, but do not treat them as urgent.&lt;/p&gt;
&lt;h3&gt;Why does everything show as orphaned when I run the script?&lt;/h3&gt;
&lt;p&gt;Almost certainly because the identity running it lacks directory read
permission. Name resolution needs Entra access, not just subscription Reader, and
without it every assignment returns a blank display name.&lt;/p&gt;
&lt;h3&gt;Should nobody have Owner?&lt;/h3&gt;
&lt;p&gt;Somebody has to, or nobody can grant access. The aim is a small number of Owners,
preferably on accounts that are not used for daily work, with everyone else
scoped down. Two is a common answer for a small estate.&lt;/p&gt;
&lt;h3&gt;How do I find guests who look inactive but are not?&lt;/h3&gt;
&lt;p&gt;Ask rather than infer. Sign-in data against your tenant can understate a guest&#x27;s
activity depending on how they access your resources, so treat it as a prompt to
investigate rather than as proof. Confirm with whoever invited them before
removing access.&lt;/p&gt;
&lt;h3&gt;Does removing Owner from someone break anything they run?&lt;/h3&gt;
&lt;p&gt;It can, if they have automation authenticating as themselves, which is its own
finding. Check for that before reducing anyone&#x27;s role, and move the automation to
a service principal or managed identity, which
&lt;a href=&quot;/notes/expiring-credentials-app-registrations&quot;&gt;the credentials note&lt;/a&gt; covers.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Cyber Essentials vs ISO 27001 vs SOC 2: which one the customer asked for</title>
    <link href="https://acloud.solutions/notes/cyber-essentials-vs-iso-27001/"/>
    <id>https://acloud.solutions/notes/cyber-essentials-vs-iso-27001/</id>
    <updated>2026-04-28T09:00:00Z</updated>
    <published>2026-04-28T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>Cyber Essentials vs ISO 27001 vs SOC 2: what each covers, which buyers ask for which, and why doing Cyber Essentials first is often right.</summary>
    <content type="html">&lt;p&gt;The email says &quot;please confirm your security certifications&quot;. Somebody senior
reads that as ISO 27001 and commits to a nine-month project. Two weeks in,
somebody finally asks the customer what they actually need, and the answer is
Cyber Essentials, because they are a UK public sector body and that is what
their procurement rules specify.&lt;/p&gt;
&lt;p&gt;Cyber Essentials vs ISO 27001 is not really a comparison of security standards.
It is a question about which buyer you are talking to, and getting it wrong in
either direction is expensive.&lt;/p&gt;
&lt;h2&gt;Cyber Essentials vs ISO 27001: what each one is&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Cyber Essentials&lt;/strong&gt; is a UK government-backed scheme covering five technical
control themes: firewalls, secure configuration, security update management,
user access control and malware protection. It is a self-assessment, verified by
a certifying body, and it is about whether specific technical basics are in
place.&lt;/p&gt;
&lt;p&gt;It is deliberately narrow. There is no management system, no risk assessment, no
policy set and no audit of how you operate. The &lt;a href=&quot;https://www.ncsc.gov.uk/cyberessentials/overview&quot;&gt;NCSC&#x27;s Cyber Essentials
overview&lt;/a&gt; sets out the
controls and the current requirements, and it is worth reading the actual
requirements document because the controls are specific about things like
supported software and account separation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cyber Essentials Plus&lt;/strong&gt; is the same five controls with technical verification:
an assessor tests a sample of your devices rather than taking your word for it.
Same scope, higher confidence, more work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ISO 27001&lt;/strong&gt; is an international standard for an information security
management system. Scope, risk assessment, policies, controls selected from
Annex A, internal audit, management review, continual improvement. It certifies
that you run a system for managing security, not that any particular technical
control exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOC 2&lt;/strong&gt; is a US attestation report produced by a CPA firm against the AICPA
trust services criteria. Type I covers design at a point in time. Type II covers
operating effectiveness over a period, typically three to twelve months, and
Type II is what buyers mean when they ask for SOC 2. It produces a report rather
than a certificate, and the report is long, confidential, and shared under NDA.&lt;/p&gt;
&lt;h2&gt;Which buyers ask for which&lt;/h2&gt;
&lt;p&gt;This is the practically useful part.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UK public sector&lt;/strong&gt; asks for Cyber Essentials, and for some contracts requires
it. It may also ask for ISO 27001 on larger engagements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UK SME and mid-market&lt;/strong&gt; asks for Cyber Essentials, or asks a questionnaire and
accepts either. Many will accept Cyber Essentials plus a well-answered
questionnaire.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UK and European enterprise&lt;/strong&gt; asks for ISO 27001. It is the recognised answer
in this market and a certificate ends the conversation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;US buyers, especially technology companies&lt;/strong&gt;, ask for SOC 2 Type II. Some will
accept ISO 27001, increasingly so, but the default expectation in US
procurement is SOC 2 and you may be asked to explain why you have the other
thing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regulated sectors&lt;/strong&gt; ask for whatever their regulator or their own framework
specifies, which may be none of the above.&lt;/p&gt;
&lt;p&gt;So the first action is not choosing a standard. It is asking the customer who
triggered this what their procurement actually requires, in writing. That
conversation takes a day and can save nine months of the wrong project.&lt;/p&gt;
&lt;h2&gt;Effort, honestly&lt;/h2&gt;
&lt;p&gt;Without inventing numbers, because certification fees vary by body and by
headcount and any figure here would be stale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cyber Essentials&lt;/strong&gt; is days to a few weeks of work for a company with
reasonable IT hygiene, and the fee is published by the scheme&#x27;s delivery partner
and tiered by organisation size. The work is mostly confirming and fixing
specific technical settings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cyber Essentials Plus&lt;/strong&gt; adds an assessor testing devices, so add the cost of
that assessment and the effort of getting a device sample genuinely compliant
rather than mostly compliant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ISO 27001&lt;/strong&gt; is six to nine months for one person part time, as covered in
&lt;a href=&quot;/notes/iso-27001-on-your-own&quot;&gt;the implementation note&lt;/a&gt;, plus certification body
fees quoted per engagement and an ongoing annual surveillance cost.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOC 2 Type II&lt;/strong&gt; requires an audit period during which controls operate, plus
a CPA firm&#x27;s fee, which is generally the most expensive of the four. It also
recurs annually, and the report has a useful life buyers will ask about.&lt;/p&gt;
&lt;p&gt;The ratio that matters: Cyber Essentials is roughly an order of magnitude less
effort than ISO 27001, and it satisfies a meaningful share of UK buyers.&lt;/p&gt;
&lt;h2&gt;Sequencing, which is the actual decision&lt;/h2&gt;
&lt;p&gt;Cyber Essentials first is usually right, and for reasons beyond cost.&lt;/p&gt;
&lt;p&gt;The five Cyber Essentials controls are things ISO 27001 will require anyway.
Patching, access control, malware protection and secure configuration all appear
in Annex A. So doing Cyber Essentials is not a detour, it is the first slice of
the same work with a certificate at the end of it.&lt;/p&gt;
&lt;p&gt;It also gives you something to say now. A deal waiting on assurance can proceed
on Cyber Essentials while ISO 27001 runs in the background, which converts a
blocked sales conversation into a delayed one.&lt;/p&gt;
&lt;p&gt;And it surfaces the technical gaps cheaply. If you cannot pass Cyber Essentials,
you are not close to ISO 27001, and finding that out in three weeks is better
than finding it out in month five.&lt;/p&gt;
&lt;p&gt;The exception: if the customer who triggered this is a European enterprise or
explicitly requires ISO 27001, Cyber Essentials will not satisfy them and doing
it first delays the thing they asked for. Ask first.&lt;/p&gt;
&lt;h2&gt;Doing more than one&lt;/h2&gt;
&lt;p&gt;ISO 27001 and SOC 2 overlap substantially in controls and not at all in
structure. If you genuinely need both, do ISO 27001 first and map to SOC 2
second: the management system, risk assessment and evidence discipline transfer,
whereas SOC 2 first leaves you without the clause 4 to 10 apparatus that ISO
requires and SOC 2 never asked for.&lt;/p&gt;
&lt;p&gt;Holding Cyber Essentials alongside ISO 27001 is common and cheap to maintain,
and it answers the UK public sector question without a conversation.&lt;/p&gt;
&lt;p&gt;What is not worth doing is holding a certification your customers never ask for
because it seemed thorough. Each one carries an annual cost and a recurring
evidence burden, and
&lt;a href=&quot;/notes/iso-27001-surveillance-audit&quot;&gt;the surveillance audit note&lt;/a&gt; covers what
that costs in year two when the enthusiasm has gone.&lt;/p&gt;
&lt;h2&gt;The question to ask this week&lt;/h2&gt;
&lt;p&gt;Send one email to the customer who started this: &quot;For our records, could you
confirm which specific certification or attestation your procurement process
requires, and whether alternatives are accepted.&quot;&lt;/p&gt;
&lt;p&gt;The answer determines a nine-month commitment, it takes them two minutes, and
almost nobody asks. &lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; covers the ISO 27001 route in detail if
that turns out to be the answer, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; covers either.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>IT team of one: what to do first when everything is priority one</title>
    <link href="https://acloud.solutions/notes/it-team-of-one-priorities/"/>
    <id>https://acloud.solutions/notes/it-team-of-one-priorities/</id>
    <updated>2026-04-21T09:00:00Z</updated>
    <published>2026-04-21T09:00:00Z</published>
    <category term="Running IT alone"/>
    <summary>An it team of one needs a triage order, not a longer list. Identity first, backups second, endpoints third, and how to report upwards to get budget.</summary>
    <content type="html">&lt;p&gt;There are forty items on the list. Eleven are security, nine are somebody&#x27;s
laptop, six are a project somebody promised a customer, and the rest arrived
this morning. All of them are legitimate. Several are from the managing
director.&lt;/p&gt;
&lt;p&gt;An it team of one does not need a better list. It needs an order that holds when
somebody senior is standing at your desk, because without one the order is
whoever asked most recently and loudest, which is how estates end up with
excellent printer availability and no tested backups.&lt;/p&gt;
&lt;h2&gt;The order for an it team of one&lt;/h2&gt;
&lt;p&gt;Four tiers. The reasoning is blast radius: what does the failure of this take
with it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Identity first.&lt;/strong&gt; If identity is compromised, everything is compromised, and
no other control survives it. MFA everywhere, no standing Global Administrator,
break-glass accounts that work and have been tested, legacy authentication
blocked. This is
&lt;a href=&quot;/notes/conditional-access-policies-small-business&quot;&gt;the Conditional Access set&lt;/a&gt;,
and it is first because it is the only category where one failure loses
everything at once.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Backups second, and specifically restores.&lt;/strong&gt; A backup job going green proves
the job succeeded. It does not prove a restore works, and those are different
claims. Ransomware is the scenario where this is the only control that matters,
and the test is not the report, it is having actually restored something.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Endpoints third.&lt;/strong&gt; Patching, disk encryption, malware protection, and knowing
which devices exist. Most incidents arrive here, and it is third rather than
first because a compromised laptop with good identity controls is contained,
while a compromised identity with perfect endpoints is not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Everything else fourth&lt;/strong&gt;, prioritised by whichever of cost, risk or noise is
currently loudest.&lt;/p&gt;
&lt;p&gt;It also broadly matches the sequence in the NCSC&#x27;s
&lt;a href=&quot;https://www.ncsc.gov.uk/collection/small-business-guide&quot;&gt;Small Business Guide&lt;/a&gt;,
which is worth having to hand precisely because it is external: a priority order
you can attribute to the national cyber security authority survives a
disagreement better than one you devised.&lt;/p&gt;
&lt;p&gt;That order is defensible to a board and it is stable under pressure, which is
its real value. When somebody asks why their request is behind something else,
&quot;identity failure loses everything, yours loses a morning&quot; is an answer.&lt;/p&gt;
&lt;h2&gt;What to automate&lt;/h2&gt;
&lt;p&gt;Only two properties make something worth automating at this size: it recurs, and
being inconsistent about it is expensive.&lt;/p&gt;
&lt;p&gt;That is a narrower filter than it sounds and it rules out most one-off tasks. It
rules in joiner, mover and leaver, evidence collection, access reviews,
credential expiry checks and anything that produces a report somebody asks for
quarterly. All of those are in
&lt;a href=&quot;/notes/automation/&quot;&gt;the automation notes&lt;/a&gt;, and all of them fail the same way if
you get it wrong, by reporting success having done nothing.&lt;/p&gt;
&lt;p&gt;What not to automate: anything you have done twice. Twice is a coincidence. By
the third time you understand the edge cases well enough to write something you
will not immediately rewrite.&lt;/p&gt;
&lt;h2&gt;What to outsource&lt;/h2&gt;
&lt;p&gt;The test is not difficulty, it is whether the constraint is your hours or
something structural.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Buy independence.&lt;/strong&gt; Internal audit needs somebody who is not you and no amount
of effort changes that, which is
&lt;a href=&quot;/notes/iso-27001-internal-audit-one-person&quot;&gt;the independence problem&lt;/a&gt;. Same for
a genuine second opinion on an architecture you designed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Buy a deadline you cannot move.&lt;/strong&gt; A migration weekend, a certification date. A
fixed external deadline with one person is a risk concentrated in whether that
person is well that week.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Buy specialist depth used rarely.&lt;/strong&gt; A penetration test. A particular
platform&#x27;s quirks you meet once every two years.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do not buy the everyday queue.&lt;/strong&gt; Handing over the helpdesk removes the
information you use to know what is actually breaking. It is also the cheapest
part of the job in hours.&lt;/p&gt;
&lt;h2&gt;Saying no in a way that sticks&lt;/h2&gt;
&lt;p&gt;The hardest part, and it is a communication problem rather than a technical one.&lt;/p&gt;
&lt;p&gt;Silence is not refusal. An unanswered request stays open in the requester&#x27;s
mind and arrives again with more urgency and a director attached. Refusing
explicitly ends it.&lt;/p&gt;
&lt;p&gt;What works: refuse against the order rather than against the request. &quot;That is
category four, and categories one to three currently have items outstanding.
I can do it after those, or now if somebody wants to move it up the list and
accept what drops.&quot; That converts a refusal into a prioritisation decision owned
by somebody else, which is where it belongs.&lt;/p&gt;
&lt;p&gt;The version that does not work is &quot;I do not have time&quot;, because it invites an
argument about your time management rather than about priorities.&lt;/p&gt;
&lt;h2&gt;Reporting upwards to get budget&lt;/h2&gt;
&lt;p&gt;The mistake is reporting activity. Tickets closed, patches applied, uptime.
These prove you are busy, and being busy is not an argument for money.&lt;/p&gt;
&lt;p&gt;Report exposure and trend instead. Three or four numbers, the same ones every
time, moving in a direction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accounts with privileged access, and how many are permanent&lt;/li&gt;
&lt;li&gt;Devices out of compliance, as a proportion&lt;/li&gt;
&lt;li&gt;Last successful restore test, as a date&lt;/li&gt;
&lt;li&gt;Whichever recurring control is furthest overdue&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last one is the useful one, because an overdue control with a date attached
is a decision somebody else is now aware of. Silence about it makes the risk
yours alone; reporting it makes it the company&#x27;s.&lt;/p&gt;
&lt;p&gt;Then attach one ask per report. Not five. One, with what it costs and what it
reduces. A single specific ask succeeds far more often than a list, and a list
invites selection of the cheapest item.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Should identity really come before backups?&lt;/h3&gt;
&lt;p&gt;Yes, because an identity compromise can reach the backups. Backup systems are
authenticated, and an attacker with sufficient privilege deletes or encrypts
them. Immutable or separately-credentialled backups narrow that gap, which is a
good reason to have them, and the ordering still holds.&lt;/p&gt;
&lt;h3&gt;What if the business will not fund any of it?&lt;/h3&gt;
&lt;p&gt;Report the exposure in writing, with dates, and keep reporting it. That is not
cynicism, it is the correct action: an accepted risk that somebody senior has
been told about is a business decision, and an accepted risk nobody was told
about is yours. Documenting it is also the only version of this that protects
you.&lt;/p&gt;
&lt;h3&gt;How do I get out of firefighting?&lt;/h3&gt;
&lt;p&gt;Automate one recurring thing properly, then use the time it frees to automate
the next. Not a project to fix everything, which will be interrupted. One thing,
finished, that never comes back.&lt;/p&gt;
&lt;h3&gt;Is a managed service provider worth it at forty people?&lt;/h3&gt;
&lt;p&gt;For round-the-clock cover, yes, because one person cannot provide it and
pretending otherwise is the actual risk. For the day queue at this size, usually
not: it costs more than it saves and it removes your visibility of what is
breaking.&lt;/p&gt;
&lt;h3&gt;When is one person genuinely not enough?&lt;/h3&gt;
&lt;p&gt;When two of these are true at once: a fixed external deadline, an estate you did
not build, and no independent review available. That combination is where
&lt;a href=&quot;/notes/when-to-hire-a-consultant&quot;&gt;bringing somebody in&lt;/a&gt; pays, and it is worth
recognising before rather than during.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Privileged identity management small business tenants can actually run</title>
    <link href="https://acloud.solutions/notes/privileged-identity-management-small-tenant/"/>
    <id>https://acloud.solutions/notes/privileged-identity-management-small-tenant/</id>
    <updated>2026-04-14T09:00:00Z</updated>
    <published>2026-04-14T09:00:00Z</published>
    <category term="Microsoft 365, Entra and Intune"/>
    <summary>Privileged identity management small business tenants can run: eligible instead of standing admin, approval that is not theatre, and the P2 gate.</summary>
    <content type="html">&lt;p&gt;There are four administrators. Two of them are you, counting the account you use
daily and the one you use for administrative work. The other two are the
managing director, who has Global Administrator because they set the tenant up
in 2019, and a developer who needed it once.&lt;/p&gt;
&lt;p&gt;The instinct is that privileged identity management small business tenants run
is overkill at this scale. Four people is not an access control problem, it is a
conversation. That instinct is half right, and the half that is wrong is the
half that matters.&lt;/p&gt;
&lt;h2&gt;Privileged identity management small business tenants need, and why&lt;/h2&gt;
&lt;p&gt;Standing privilege is not primarily about trusting your colleagues. It is about
what a compromised session can do.&lt;/p&gt;
&lt;p&gt;An account holding Global Administrator permanently is one successful phishing
attempt, one stolen session token, or one compromised personal device away from
being a full tenant compromise. There is no additional step for the attacker
after they have the credential, because the privilege is already active. Nothing
has to be requested, nothing gets logged as an escalation, and nothing alerts.&lt;/p&gt;
&lt;p&gt;The same account with the role eligible rather than active means the attacker
has to activate it, which produces an audit event, can require approval, and can
require MFA at activation. None of that stops a determined attacker who already
holds the credential. All of it produces a signal where there was none, and a
signal is what a one-person team is short of.&lt;/p&gt;
&lt;p&gt;That reasoning holds at four administrators exactly as much as at four hundred.
What changes with scale is the workflow, not the risk.&lt;/p&gt;
&lt;h2&gt;The licence gate, stated plainly&lt;/h2&gt;
&lt;p&gt;Entra Privileged Identity Management requires Entra ID P2. It is not in Business
Premium, and it is not in E3. It comes with E5, or as an add-on.&lt;/p&gt;
&lt;p&gt;This is worth being blunt about because a great deal of advice recommends PIM
without mentioning it, and discovering the gap after designing a process around
it wastes a week. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/subscription-requirements&quot;&gt;PIM licensing requirements&lt;/a&gt;
sets out what is needed.&lt;/p&gt;
&lt;p&gt;Two practical consequences. Check whether you already have P2 through a bundle
before buying anything, because tenants frequently hold licences nobody has
assigned. And check the service plan rather than the licence name, because the
plan is what actually gates the feature and the naming is not obvious.&lt;/p&gt;
&lt;p&gt;If you do not have P2, the fallback is not nothing. Separate administrative
accounts from daily-use accounts, keep the number of standing administrators to
two, alert on role assignment changes, and review quarterly. That is most of the
benefit without the mechanism, and it is what
&lt;a href=&quot;/notes/azure-rbac-stale-assignments&quot;&gt;the RBAC review note&lt;/a&gt; describes for the
Azure side.&lt;/p&gt;
&lt;h2&gt;Eligible versus active&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Active&lt;/strong&gt; means the role applies now. &lt;strong&gt;Eligible&lt;/strong&gt; means the person can
activate it, for a limited window, subject to whatever conditions you set.&lt;/p&gt;
&lt;p&gt;The conditions worth setting for a small tenant:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Maximum activation duration of a few hours&lt;/strong&gt;, not the default eight. Most
administrative tasks take minutes. A window that outlives the task is standing
privilege with extra steps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MFA on activation&lt;/strong&gt;, always. This is the cheapest control here and the one
most likely to matter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Justification required.&lt;/strong&gt; The text somebody types is rarely useful in itself.
The value is that activation becomes a deliberate act with a record, and the
record is what you read six months later when working out how often a role is
genuinely needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Notification on activation&lt;/strong&gt;, to you, even when you are the person
activating. It reads as noise for a fortnight and then one day it is not you.&lt;/p&gt;
&lt;h2&gt;Approval when the approver is the requester&lt;/h2&gt;
&lt;p&gt;This is the small-tenant problem that reference architectures do not address. If
you are the only administrator, requiring approval means approving your own
requests, which is theatre.&lt;/p&gt;
&lt;p&gt;Three honest options.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do not require approval, require everything else.&lt;/strong&gt; MFA, short window,
justification, notification. The audit trail is intact and there is no fiction
about oversight. For most one-person tenants this is the right answer, and it is
defensible to an auditor if you say so plainly rather than pretending a control
exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Make a non-technical director the approver&lt;/strong&gt; for the highest roles only,
typically Global Administrator. This sounds like a bottleneck and works better
than expected, because the number of genuine Global Administrator activations
per month is small. It also creates a real second pair of eyes on the one role
that matters most. The prerequisite is that they can approve from a phone within
minutes, and that they know what they are approving.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reciprocal approval with a peer.&lt;/strong&gt; If you have a relationship with someone in
a similar role at another company, guest accounts as mutual approvers can work.
It is unusual and it is genuine independence.&lt;/p&gt;
&lt;p&gt;What does not work is configuring approval and then approving your own requests
while describing it as segregation of duties. An auditor will ask who approves,
and the answer will be visible in the logs.&lt;/p&gt;
&lt;h2&gt;What it looks like to an auditor&lt;/h2&gt;
&lt;p&gt;PIM produces exactly the artefacts an access control audit asks for, which is a
side benefit worth harvesting.&lt;/p&gt;
&lt;p&gt;The activation history answers &quot;who had privileged access, when, and why&quot; with
timestamps rather than assertions. The eligible assignment list answers &quot;who
could have privileged access&quot;. Access reviews inside PIM produce a dated record
of somebody having checked.&lt;/p&gt;
&lt;p&gt;That combination covers a good deal of what
&lt;a href=&quot;/notes/microsoft-365/&quot;&gt;a security questionnaire&lt;/a&gt; asks about privileged access,
and it is the difference between answering &quot;we limit administrative access&quot; and
being able to show it. &lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; covers how this maps to the relevant
Annex A controls if you are heading that way.&lt;/p&gt;
&lt;h2&gt;Where to start&lt;/h2&gt;
&lt;p&gt;Two hours of work, in this order.&lt;/p&gt;
&lt;p&gt;Find out whether you have P2 and how many. Then reduce standing Global
Administrators to two, one of which is a break-glass account that
&lt;a href=&quot;/notes/break-glass-accounts&quot;&gt;stays permanently assigned on purpose&lt;/a&gt;. Then make
everything else eligible, with MFA and a short window. Then set a quarterly
reminder to read the activation history, because the log nobody reads is the same
as no log.&lt;/p&gt;
&lt;p&gt;The developer who needed Global Administrator once will not notice. The managing
director will need to be told, and the framing that works is that it protects
them personally rather than that they are not trusted.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Joiner mover leaver automation with Graph: the script that never forgets</title>
    <link href="https://acloud.solutions/notes/joiner-mover-leaver-automation-graph/"/>
    <id>https://acloud.solutions/notes/joiner-mover-leaver-automation-graph/</id>
    <updated>2026-04-07T09:00:00Z</updated>
    <published>2026-04-07T09:00:00Z</published>
    <category term="Automation"/>
    <summary>Joiner mover leaver automation that never forgets step fourteen. What a leaver script must do, in what order, and why the report matters as much.</summary>
    <content type="html">&lt;p&gt;The email says the developer&#x27;s last day was Friday. It is Tuesday. Somewhere
there is a nineteen-step checklist, and the honest answer to &quot;has it been done&quot;
is that four steps have, the ones in the portal you had open at the time.&lt;/p&gt;
&lt;p&gt;Joiner mover leaver automation is the process most worth automating in a small
company, for a reason that is not efficiency. It is that a partially completed
offboarding is invisible. Nothing alerts. The account still works, which is the
whole problem, and nobody will notice until either an audit or an incident.&lt;/p&gt;
&lt;h2&gt;What joiner mover leaver automation has to do for a leaver&lt;/h2&gt;
&lt;p&gt;Nine things, and the order matters more than the list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disable the account&lt;/strong&gt; and reset the password to something random nobody holds.
Disabling alone does not invalidate an existing session.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Revoke refresh tokens.&lt;/strong&gt; This is the step people miss and it is the one that
matters most on the day. A disabled account with a live refresh token can
continue accessing resources until the token expires, which can be hours. Graph
exposes this directly and it takes one call.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove from all groups&lt;/strong&gt;, recording which ones first. The record is what lets
you reverse a mistake and is also the evidence of what access existed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reassign ownership&lt;/strong&gt; of anything they solely owned: groups, Teams,
applications, subscriptions. An orphaned group with no owner cannot be
administered without elevation later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Convert the mailbox to shared&lt;/strong&gt;, if somebody needs continued access to it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove licences&lt;/strong&gt;, and here is the trap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove devices&lt;/strong&gt; or mark them for wipe or retirement depending on ownership.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove from distribution lists and external systems&lt;/strong&gt; your directory does not
cover.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Produce a report&lt;/strong&gt; of every step, with timestamps and outcomes including
failures.&lt;/p&gt;
&lt;h2&gt;The order trap that costs you a mailbox&lt;/h2&gt;
&lt;p&gt;Convert the mailbox before removing the licence. Not after.&lt;/p&gt;
&lt;p&gt;Remove the licence first and the mailbox enters a disconnected state. It is
still there, for a limited window measured in weeks, and it is no longer
visible to the cmdlets you would use to convert it. So the script reports the
licence removal as a success, the conversion step fails or silently does
nothing, and the mailbox quietly ages out. By the time somebody asks for access
to the leaver&#x27;s email, the window has closed.&lt;/p&gt;
&lt;p&gt;The same class of problem appears elsewhere in this process. Deleting the
account before running the offboarding produces a cascade of not-found errors,
each of which a naive script may treat as &quot;nothing to do&quot; rather than &quot;the
subject of this operation is gone&quot;. A leaver script should verify the account
exists and is in the expected state before it starts, and refuse to run if it
does not, rather than reporting a successful offboarding of an object that was
already deleted.&lt;/p&gt;
&lt;p&gt;Order the operations so that each one&#x27;s precondition is still true when it runs,
and assert the precondition rather than assuming it.&lt;/p&gt;
&lt;h2&gt;Idempotency, because it will be run twice&lt;/h2&gt;
&lt;p&gt;Somebody will run it again. Either because the first run failed halfway, or
because two people were asked to do the same offboarding, or because the
scheduled job retried.&lt;/p&gt;
&lt;p&gt;So every step needs to be safe to repeat. Removing a group membership that is
already removed is a no-op, not an error. Disabling a disabled account is fine.
Converting an already-shared mailbox should be recognised and skipped rather
than attempted and reported as a failure.&lt;/p&gt;
&lt;p&gt;The distinction that makes this workable is between &quot;already in the desired
state&quot;, which is a success, and &quot;could not determine the state&quot;, which is a
failure. Collapsing those two is how a script ends up reporting green on a run
that achieved nothing.&lt;/p&gt;
&lt;h2&gt;The report is the deliverable&lt;/h2&gt;
&lt;p&gt;The temptation is to treat the report as logging. It is not, it is the output.&lt;/p&gt;
&lt;p&gt;For an auditor, a dated report showing that nine specific access removals
occurred, with timestamps and the identity that performed them, is evidence that
the leaver process operated. A ticket saying &quot;offboarded as per checklist&quot; is an
assertion. The difference matters at Stage 2 of a certification audit, where the
question is not whether you have a process but whether it ran, and
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers what that evidence needs to look like.&lt;/p&gt;
&lt;p&gt;So the report should record what was attempted, what succeeded, what was skipped
and why, and what failed. Especially what failed. A report that only lists
successes is a report somebody has to cross-reference against the checklist to
trust.&lt;/p&gt;
&lt;p&gt;Write it somewhere immutable enough to be evidence, with the leaver&#x27;s name, the
date, and the operator. A file in a document library with a retention policy is
adequate and better than a console transcript nobody kept.&lt;/p&gt;
&lt;h2&gt;Running it from a runbook&lt;/h2&gt;
&lt;p&gt;An Automation account runbook or a scheduled pipeline beats a laptop, for the
handover reason. A script that only runs from your machine, authenticating as
you, stops working the day you are unavailable, which is precisely the day
somebody else needs it.&lt;/p&gt;
&lt;p&gt;That means a service principal or managed identity with the specific permissions
required, which is
&lt;a href=&quot;/notes/graph-api-permissions-least-privilege&quot;&gt;the least-privilege question&lt;/a&gt;,
and it means the job has to fail loudly, which is
&lt;a href=&quot;/notes/powershell-scripts-exit-codes-logging&quot;&gt;the exit code question&lt;/a&gt;. Both are
separate notes because both apply to everything else here too.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/graph/api/resources/users&quot;&gt;Graph user management documentation&lt;/a&gt;
covers the calls; the sequencing above is the part that is not in any reference.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Should the script delete the account or just disable it?&lt;/h3&gt;
&lt;p&gt;Disable, and leave deletion as a separate decision after a retention period.
Deleting immediately destroys the object the mailbox and the group memberships
hang off, and recovering a deleted account is a narrower window than people
expect. Disable, strip access, keep the object.&lt;/p&gt;
&lt;h3&gt;Why revoke tokens if the account is disabled?&lt;/h3&gt;
&lt;p&gt;Because disabling prevents new sign-ins and does not necessarily invalidate an
existing session immediately. Revoking refresh tokens closes that gap. It is one
Graph call and it is the difference between access ending now and access ending
whenever the token happens to expire.&lt;/p&gt;
&lt;h3&gt;What permissions does this need?&lt;/h3&gt;
&lt;p&gt;More than a reporting script, because it writes. &lt;code&gt;User.ReadWrite.All&lt;/code&gt;,
&lt;code&gt;Group.ReadWrite.All&lt;/code&gt;, &lt;code&gt;Directory.AccessAsUser.All&lt;/code&gt; for some operations, and
Exchange permissions for the mailbox work. This is a case where the write access
is genuinely required, which makes it more important than usual to know what
holds it and to have an expiry date on the credential.&lt;/p&gt;
&lt;h3&gt;How do I handle the systems Graph does not cover?&lt;/h3&gt;
&lt;p&gt;List them explicitly in the script output as manual steps, with the owner of
each. A script that silently covers eleven of fourteen systems is worse than one
that covers eleven and tells you about the other three, because the first
creates false confidence.&lt;/p&gt;
&lt;h3&gt;Is a mover the same as a leaver with extra steps?&lt;/h3&gt;
&lt;p&gt;Mostly the reverse: a mover is a leaver from one set of groups and a joiner to
another, with nothing removed from the identity itself. The part people get
wrong is the removal half, because adding new access is prompted by the person
needing it and removing old access is prompted by nothing at all.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure snapshot cost: a museum of disks nobody visits</title>
    <link href="https://acloud.solutions/notes/azure-snapshots-cost/"/>
    <id>https://acloud.solutions/notes/azure-snapshots-cost/</id>
    <updated>2026-03-31T09:00:00Z</updated>
    <published>2026-03-31T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>Azure snapshot cost depends on whether the snapshot is incremental or full, and on nobody deleting it. How the billing works and what accumulates.</summary>
    <content type="html">&lt;p&gt;Every snapshot in your subscription was created by somebody being careful. That
is what makes them awkward to delete. Nobody snapshots a disk out of
carelessness; they do it before a change that might go wrong, and then the
change goes fine, and the snapshot becomes a small monthly charge attached to a
decision that turned out not to matter.&lt;/p&gt;
&lt;p&gt;Azure snapshot cost is therefore mostly a retention problem rather than a
pricing problem. The rates are modest. The accumulation is not.&lt;/p&gt;
&lt;h2&gt;How azure snapshot cost is calculated&lt;/h2&gt;
&lt;p&gt;There are two kinds of snapshot and the difference matters more than the rate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Full snapshots&lt;/strong&gt; bill for the used size of the source disk at the time the
snapshot was taken, at a standard storage rate. Take a full snapshot of a disk
with 60 GB of data on it and you are billed for roughly 60 GB, every month, until
you delete it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Incremental snapshots&lt;/strong&gt; bill only for the changes since the previous snapshot
of that disk. The first one is effectively a full copy of the used data. The
second is the delta. The tenth is the delta from the ninth. A chain of ten
incremental snapshots on a disk that barely changes can cost less than a single
full snapshot of the same disk.&lt;/p&gt;
&lt;p&gt;Two consequences follow. Incremental is almost always the right choice for
anything recurring, and Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/virtual-machines/disks-incremental-snapshots&quot;&gt;incremental snapshot documentation&lt;/a&gt;
covers the mechanics and the regional caveats. And deleting one snapshot from
the middle of an incremental chain does not free what you might expect, because
the data another snapshot depends on has to stay.&lt;/p&gt;
&lt;p&gt;That second point is why &quot;delete everything older than 90 days&quot; produces
disappointing savings on an incremental chain and dramatic savings on a pile of
full snapshots.&lt;/p&gt;
&lt;h2&gt;Where they come from&lt;/h2&gt;
&lt;p&gt;Four sources, roughly in order of how many they produce.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Backup tooling.&lt;/strong&gt; Some third-party backup products snapshot before copying and
tidy up afterwards, and some tidy up only when the job succeeds. A failed job at
2am leaves a snapshot behind, and a job that has been failing quietly for eight
months leaves 240 of them. This is the single biggest producer I have found in
small estates, and it is invisible because each individual snapshot is cheap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finished migrations.&lt;/strong&gt; A migration takes a safety copy of everything before
it moves. Eighteen months later the safety copy is still there, named something
like &lt;code&gt;snap-migration-final&lt;/code&gt;, and deleting it feels like tempting fate even
though the source disk no longer exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cautious engineers, including me.&lt;/strong&gt; Before a patch, before a schema change,
before a resize. Entirely correct behaviour, followed by no cleanup step because
the change worked and attention moved on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Image builds.&lt;/strong&gt; Custom image pipelines produce snapshots as intermediate
artefacts. Whether they get cleaned up depends on whether the pipeline finished.&lt;/p&gt;
&lt;h2&gt;Finding the ones that have outlived their reason&lt;/h2&gt;
&lt;p&gt;The query is simple. The judgement is not.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;kusto&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-kusto&quot;&gt;resources
| where type =~ &#x27;microsoft.compute/snapshots&#x27;
| extend created = todatetime(properties.timeCreated),
         sizeGB = toint(properties.diskSizeGB),
         incremental = tobool(properties.incremental),
         sourceId = tostring(properties.creationData.sourceResourceId)
| extend ageDays = datetime_diff(&#x27;day&#x27;, now(), created)
| where ageDays &amp;gt; 180
| project subscriptionId, resourceGroup, name, sizeGB, incremental, ageDays, sourceId
| order by ageDays desc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;sourceId&lt;/code&gt; column is the interesting one, because it lets you answer the
question that actually decides things: does the disk this was taken from still
exist? A snapshot of a live disk is a rollback point somebody might want. A
snapshot whose source disk was deleted two years ago is a museum piece, and it
is often the only remaining copy of something, which is either the reason to
keep it or the reason nobody can approve deleting it.&lt;/p&gt;
&lt;p&gt;Cross-reference against
&lt;a href=&quot;/notes/orphaned-azure-resources&quot;&gt;the unattached disks from the orphan sweep&lt;/a&gt;
and a pattern usually appears: a decommissioned server, its disk, and three
snapshots, all left behind by the same unfinished piece of work.&lt;/p&gt;
&lt;h2&gt;What deleting one actually saves&lt;/h2&gt;
&lt;p&gt;This is where snapshot work disappoints people who have promised a number.&lt;/p&gt;
&lt;p&gt;On full snapshots the arithmetic is honest: delete a 60 GB snapshot and you stop
paying for 60 GB. On incremental chains it is not, because the billed size of
each snapshot is the delta it holds, and deleting a snapshot from the middle of
a chain leaves its data in place if a later snapshot still needs it. Azure
handles the consolidation for you, which is the right behaviour and also the
reason the saving is smaller than the sum of the sizes you deleted.&lt;/p&gt;
&lt;p&gt;So report snapshot findings as a range or as the total for the ones you are
confident about, and separate the full snapshots from the incremental ones in
the output. A finance conversation that starts with &quot;we deleted 340 GB of
snapshots and saved less than you would expect, here is why&quot; goes better than
one where the projected saving quietly fails to appear on the next invoice.&lt;/p&gt;
&lt;h2&gt;Retention as a decision&lt;/h2&gt;
&lt;p&gt;The reason snapshots accumulate is that nobody ever decided how long to keep
them. Not &quot;nobody decided correctly&quot;, nobody decided at all, because each
snapshot was created as an individual act of caution rather than under a policy.&lt;/p&gt;
&lt;p&gt;A retention rule does not need to be sophisticated to fix that. Something like:
pre-change snapshots go after 30 days, migration snapshots go 90 days after the
migration signs off, backup tool snapshots are the backup tool&#x27;s problem and
anything it leaves behind after 7 days is a fault to investigate rather than a
snapshot to keep.&lt;/p&gt;
&lt;p&gt;Write it down, tag snapshots with their reason at creation, and the monthly
review becomes a query rather than an archaeology exercise. That is the same
argument as
&lt;a href=&quot;/notes/azure-tagging-strategy-that-survives&quot;&gt;the tagging note&lt;/a&gt;, and snapshots
are the strongest case for it because the metadata you need at deletion time is
the reason it was taken, which is exactly what nobody records.&lt;/p&gt;
&lt;h2&gt;The one that is genuinely load-bearing&lt;/h2&gt;
&lt;p&gt;Worth saying, because a cost note that only argues for deletion is a bad
influence.&lt;/p&gt;
&lt;p&gt;Sometimes the old snapshot is the only copy of something that was never backed
up properly. A departed developer&#x27;s environment. A database from before a
migration that changed the schema. A configuration nobody has documented. That
snapshot is not waste, it is an accidental archive, and its monthly cost is
cheap insurance.&lt;/p&gt;
&lt;p&gt;The correct action there is not to delete it. It is to notice that you are
relying on a snapshot as a backup, and to either make it a real backup or accept
the arrangement deliberately. Cost work that turns an accidental dependency into
a conscious one has done something useful even when it saves nothing.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt; reports snapshot age, size,
incremental status and whether the source disk still exists, which is the
combination that lets you sort the museum from the archive.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure storage account public access: how to find the one you forgot about</title>
    <link href="https://acloud.solutions/notes/azure-public-storage-accounts/"/>
    <id>https://acloud.solutions/notes/azure-public-storage-accounts/</id>
    <updated>2026-03-24T09:00:00Z</updated>
    <published>2026-03-24T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>Azure storage account public access has two separate switches, and a container can be readable even when the account looks locked down. How to check both.</summary>
    <content type="html">&lt;p&gt;Someone needed to share a file with a supplier. The supplier&#x27;s mail gateway
rejected the attachment. So the container was made public for an afternoon, the
link was sent, the supplier got the file, and everybody moved on. That was two
years ago and the container is called &lt;code&gt;exports&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Azure storage account public access is one of the few security findings where
the impact is immediate and requires no attacker skill whatsoever. If anonymous
read is enabled on a container, its contents are available to anyone who knows
or guesses the URL, and blob URLs are guessable in the way that predictable
things are.&lt;/p&gt;
&lt;h2&gt;Azure storage account public access has two switches, not one&lt;/h2&gt;
&lt;p&gt;The detail that makes this survive audits: there are two independent settings
and both have to be permissive for anonymous access to work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The account setting&lt;/strong&gt;, &lt;code&gt;allowBlobPublicAccess&lt;/code&gt;. This is the master switch. If
it is false, no container in that account can be anonymously readable no matter
what the container says.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The container setting&lt;/strong&gt;, &lt;code&gt;publicAccess&lt;/code&gt;. Per container, with three values.
&lt;code&gt;None&lt;/code&gt; means no anonymous access. &lt;code&gt;Blob&lt;/code&gt; means anonymous read of blobs if you
know the URL. &lt;code&gt;Container&lt;/code&gt; means anonymous read plus the ability to list every
blob in it, which is considerably worse because it removes the guessing.&lt;/p&gt;
&lt;p&gt;The trap is checking only one. An account with &lt;code&gt;allowBlobPublicAccess&lt;/code&gt; set to
true is not necessarily exposing anything, because every container may be
&lt;code&gt;None&lt;/code&gt;. And a container set to &lt;code&gt;Container&lt;/code&gt; is harmless while the account switch
is false, right up until somebody flips the account switch for an unrelated
reason and silently exposes it.&lt;/p&gt;
&lt;p&gt;So a real audit reads both, and reports the combination. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure&quot;&gt;anonymous read access documentation&lt;/a&gt;
covers the precedence and how to disable it at the account level.&lt;/p&gt;
&lt;h2&gt;Checking every subscription&lt;/h2&gt;
&lt;p&gt;Resource Graph finds the accounts, but the container setting is not in Resource
Graph, so this is a two-stage job:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;# Stage one: accounts where the master switch permits it.
Get-AzSubscription | ForEach-Object {
    $null = Set-AzContext -SubscriptionId $_.Id
    Get-AzStorageAccount | Where-Object { $_.AllowBlobPublicAccess -ne $false } |
        Select-Object @{n=&#x27;Sub&#x27;;e={$_.Context.Subscription}},
                      ResourceGroupName, StorageAccountName,
                      AllowBlobPublicAccess, EnableHttpsTrafficOnly
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note &lt;code&gt;-ne $false&lt;/code&gt; rather than &lt;code&gt;-eq $true&lt;/code&gt;. The property can be null on accounts
created before the setting existed, and null behaves as permissive on older
accounts. Checking for &lt;code&gt;$true&lt;/code&gt; misses exactly the oldest accounts, which are the
ones most likely to have been configured casually.&lt;/p&gt;
&lt;p&gt;Then for each account that passes, enumerate containers and read &lt;code&gt;PublicAccess&lt;/code&gt;.
That needs a data-plane call rather than a management-plane one, which means the
identity running the audit needs a data role such as Storage Blob Data Reader
and not merely Reader. This surprises people: an account with Reader across the
subscription can list storage accounts and cannot see whether their containers
are public.&lt;/p&gt;
&lt;h2&gt;SAS tokens expiring in 2099&lt;/h2&gt;
&lt;p&gt;The other half of this, and the half nobody audits.&lt;/p&gt;
&lt;p&gt;A shared access signature grants access without an identity. It is a URL with a
signature in the query string, and anyone holding it has whatever it grants
until it expires. Which means a SAS with a distant expiry is a permanent
credential pasted into whatever channel it was shared through: an email, a Teams
message, a ticket, a config file in a repository.&lt;/p&gt;
&lt;p&gt;Expiry dates ten or twenty years out are common because the person creating one
did not want to be called about it again, which is understandable and also
creates a credential nobody can revoke without rotating the account key.&lt;/p&gt;
&lt;p&gt;Two things worth knowing. Account-key-signed SAS tokens cannot be revoked
individually; you rotate the key, which invalidates every SAS signed with it,
including the ones something in production depends on. And stored access
policies exist precisely to fix this, because a SAS tied to a policy can be
revoked by changing the policy. Almost nobody uses them.&lt;/p&gt;
&lt;p&gt;You cannot enumerate issued SAS tokens, which is the uncomfortable part. What
you can do is check whether diagnostic logging records SAS-authenticated
requests, and set a maximum SAS expiry at the account level so new ones cannot be
created with absurd lifetimes.&lt;/p&gt;
&lt;h2&gt;The one that is public on purpose&lt;/h2&gt;
&lt;p&gt;Before switching anything off, work out which of these is deliberate, because
some of them will be.&lt;/p&gt;
&lt;p&gt;Static website hosting on a storage account uses a container called &lt;code&gt;$web&lt;/code&gt; and it
is supposed to be readable. Reporting it as a finding every month is how an audit
loses credibility.&lt;/p&gt;
&lt;p&gt;Public datasets, product downloads and documentation assets are all legitimate
uses. So are container registries for public images and any container fronted by
a CDN endpoint, where the origin being readable is the design.&lt;/p&gt;
&lt;p&gt;The way to tell is not the setting, it is whether anything references the URL.
Check the CDN profiles, check the DNS records, and check whether the container
name looks like infrastructure or like somebody&#x27;s afternoon. &lt;code&gt;assets&lt;/code&gt;, &lt;code&gt;static&lt;/code&gt;
and &lt;code&gt;$web&lt;/code&gt; are usually intentional. &lt;code&gt;exports&lt;/code&gt;, &lt;code&gt;temp&lt;/code&gt;, &lt;code&gt;share&lt;/code&gt; and anything with
a year in the name usually are not.&lt;/p&gt;
&lt;p&gt;Then record the intentional ones somewhere the next audit will read, so the
finding stops recurring. An exception with a reason and a date is a decision. An
exception nobody wrote down is a finding you will rediscover quarterly and
dismiss from memory, which is indistinguishable from not checking.&lt;/p&gt;
&lt;h2&gt;What to fix, in what order&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Containers set to &lt;code&gt;Container&lt;/code&gt; on an account that permits public access.&lt;/strong&gt;
Immediate. That combination allows listing, so the contents are enumerable
rather than merely reachable. Find out what is in it before changing anything,
because you need to know what was exposed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Containers set to &lt;code&gt;Blob&lt;/code&gt; on a permissive account.&lt;/strong&gt; Same day. Reachable if the
URL is known, and URLs leak through referrer headers, browser history and
shared links.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Accounts permitting public access with no public containers.&lt;/strong&gt; This week. Set
&lt;code&gt;allowBlobPublicAccess&lt;/code&gt; to false and the whole class of accident goes away. This
is the highest-value change in the whole note because it is preventive rather
than corrective.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SAS expiry policy.&lt;/strong&gt; This month. Set a maximum, then work out what would break.&lt;/p&gt;
&lt;p&gt;Do not simply switch things off before checking what uses them. A public
container is sometimes deliberate: a website&#x27;s static assets, a public dataset, a
download somebody&#x27;s product depends on. The finding is not &quot;this is public&quot;, it
is &quot;is this public on purpose and does anybody know&quot;.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;Public storage is one of the ten checks in the
&lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt;, and it reports the account and
container settings together rather than separately, for the reasons above.&lt;/p&gt;
&lt;p&gt;It pairs with &lt;a href=&quot;/notes/azure-nsg-rules-audit&quot;&gt;the NSG note&lt;/a&gt; because both findings
come from the same habit of opening something temporarily, and with
&lt;a href=&quot;/notes/azure-rbac-stale-assignments&quot;&gt;the RBAC note&lt;/a&gt; because the question &quot;who
could make this public again&quot; is usually more interesting than the current
setting.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>How to answer security questionnaires: 240 questions, no lying</title>
    <link href="https://acloud.solutions/notes/security-questionnaires-how-to-answer/"/>
    <id>https://acloud.solutions/notes/security-questionnaires-how-to-answer/</id>
    <updated>2026-03-17T09:00:00Z</updated>
    <published>2026-03-17T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>How to answer security questionnaires at speed: an answer library mapped to controls, not applicable as a real answer, and the data residency question.</summary>
    <content type="html">&lt;p&gt;The spreadsheet has 240 rows across eleven tabs. Question 118 asks whether you
have a documented process for secure disposal of physical media. Question 119
asks the same thing in different words. Question 174 asks about your SOC 2 Type
II report, which you do not have, and the deal is waiting on this.&lt;/p&gt;
&lt;p&gt;Learning how to answer security questionnaires quickly is the highest-return
administrative skill in a small B2B software company, because the questionnaires
never stop and the first one takes three days.&lt;/p&gt;
&lt;h2&gt;How to answer security questionnaires: the library is the technique&lt;/h2&gt;
&lt;p&gt;The second questionnaire should take a fraction of the first. That only happens
if you build an answer library while doing the first one, which feels like
overhead precisely when you have least patience for it.&lt;/p&gt;
&lt;p&gt;Structure it by topic rather than by questionnaire: access control,
encryption, secure development, incident response, business continuity, supplier
management, data protection, physical security, personnel security, logging and
monitoring.&lt;/p&gt;
&lt;p&gt;For each answer store four things. The &lt;strong&gt;answer text&lt;/strong&gt;, written to be reusable
rather than tailored. The &lt;strong&gt;control reference&lt;/strong&gt; it maps to, so a similar question
finds it. The &lt;strong&gt;evidence&lt;/strong&gt; that supports it and where that lives. And the &lt;strong&gt;last
reviewed date&lt;/strong&gt;, because a stale answer library is how you end up asserting
something that stopped being true.&lt;/p&gt;
&lt;p&gt;Two hundred and forty questions collapse to perhaps sixty distinct topics.
Questionnaires overlap heavily because they descend from the same handful of
industry templates, so the second one is largely a lookup and the fifth is
mostly copy and paste with a check.&lt;/p&gt;
&lt;h2&gt;Mapping questions to controls and evidence&lt;/h2&gt;
&lt;p&gt;The reason to store the control reference is that it converts a wording problem
into a lookup.&lt;/p&gt;
&lt;p&gt;A question about &quot;least privilege&quot; and a question about &quot;role-based access
provisioning&quot; and a question about &quot;periodic entitlement review&quot; are three
phrasings of access control. Tag all three against the same control, and the
library answers all three from one maintained entry.&lt;/p&gt;
&lt;p&gt;If you hold ISO 27001, this mapping is already done: your
&lt;a href=&quot;/notes/iso-27001-statement-of-applicability&quot;&gt;Statement of Applicability&lt;/a&gt;
records each control, the implementation, and where the evidence is. The
questionnaire becomes a translation exercise from their wording to your control
numbers, which is why certification pays for itself in sales cycle time
independently of whether anyone asked for the certificate.&lt;/p&gt;
&lt;h2&gt;Not applicable, with a reason&lt;/h2&gt;
&lt;p&gt;&quot;Not applicable&quot; is a legitimate answer and most people are afraid of it, so they
write something vague instead, which is worse.&lt;/p&gt;
&lt;p&gt;A bare &quot;N/A&quot; reads as evasion. A justified one reads as competence, and it is the
same pattern as
&lt;a href=&quot;/notes/iso-27001-statement-of-applicability&quot;&gt;justifying an SoA exclusion&lt;/a&gt;:
state the factual circumstance, then say where the underlying risk is addressed.&lt;/p&gt;
&lt;p&gt;&quot;Not applicable. The company operates entirely remotely with no offices or data
centres; all infrastructure is cloud-hosted. Physical security of the hosting
environment is addressed through supplier assurance, and our provider&#x27;s
certifications are available on request.&quot;&lt;/p&gt;
&lt;p&gt;That answer is better than describing a visitor sign-in book you do not have,
and infinitely better than leaving it blank for somebody to chase.&lt;/p&gt;
&lt;p&gt;The same applies to the honest negative. If you do not have a SOC 2 report, say
so and say what you have instead. &quot;We are certified to ISO/IEC 27001:2022,
certificate available on request. We do not currently hold a SOC 2 Type II
report.&quot; Procurement teams accept that far more often than people expect,
because what they need is a documented basis for assurance rather than one
specific document.&lt;/p&gt;
&lt;h2&gt;Certificate or Statement of Applicability&lt;/h2&gt;
&lt;p&gt;A judgement people get wrong in both directions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Send the certificate&lt;/strong&gt; by default. It is short, it is verifiable with the
certification body, and it states the scope. Almost every questionnaire asking
for evidence of certification is satisfied by it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Send the Statement of Applicability&lt;/strong&gt; when they ask specifically, or when your
answer to a control question needs supporting. It is a much more revealing
document: it shows what you excluded and why, and a thorough procurement analyst
will read the exclusions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do not send the risk register.&lt;/strong&gt; It is an internal document listing your
weaknesses. Nobody needs it for assurance, and requests for it are usually a
misunderstanding of what the standard produces. Offer the SoA instead.&lt;/p&gt;
&lt;p&gt;The other thing to check on the certificate is that the scope matches what they
are buying. A certificate whose
&lt;a href=&quot;/notes/iso-27001-scope-statement&quot;&gt;scope&lt;/a&gt; excludes the product under discussion
raises a harder question than not having one.&lt;/p&gt;
&lt;h2&gt;The question that always trips people up&lt;/h2&gt;
&lt;p&gt;Data residency, and specifically the difference between where data is stored and
where it can be accessed from.&lt;/p&gt;
&lt;p&gt;Most people answer the storage half correctly and stop. The follow-up, which
arrives when the first answer is incomplete, is about access: does support
personnel outside the region access production data, do sub-processors, is there
onward transfer, and what safeguards apply.&lt;/p&gt;
&lt;p&gt;For a UK company with EU customers, or vice versa, that is a real question with
a real answer involving your transfer mechanism. The ICO&#x27;s
&lt;a href=&quot;https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/international-transfers/&quot;&gt;guidance on international transfers&lt;/a&gt;
sets out what applies, and it is worth having a settled answer in the library
because it comes up every time and improvising it is how you commit to something
inaccurate.&lt;/p&gt;
&lt;p&gt;Answer both halves unprompted. It saves a round trip and it signals that you
understood the question.&lt;/p&gt;
&lt;h2&gt;Working through one at speed&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Read every question first.&lt;/strong&gt; Twenty minutes, and it stops you writing a long
answer to question 40 that question 180 asks properly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Answer from the library.&lt;/strong&gt; Fill everything that matches, flag the rest.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Batch the genuine gaps&lt;/strong&gt; and answer them by topic rather than in row order,
because they cluster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Never guess.&lt;/strong&gt; An inaccurate questionnaire answer is a contractual
representation. If you do not know, find out or say you will confirm. &quot;Not
currently, planned for Q3&quot; is a survivable answer; a yes that turns out to be no
is a different category of problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Add every new answer to the library&lt;/strong&gt; before sending, while the reasoning is
fresh.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;How long should the first one take?&lt;/h3&gt;
&lt;p&gt;Two to three days for 240 questions if you are building the library at the same
time. Half a day for the second. If the fifth still takes days, the library is
not being maintained.&lt;/p&gt;
&lt;h3&gt;Should I use an AI tool to draft answers?&lt;/h3&gt;
&lt;p&gt;For rephrasing an answer you already have, yes. For generating answers about
your own environment, no: it will produce plausible statements about controls
you may not have, and you are the one signing them. The
&lt;a href=&quot;/notes/ai-in-the-security-team-of-one&quot;&gt;note on AI in a one-person security team&lt;/a&gt;
covers where that line sits.&lt;/p&gt;
&lt;h3&gt;What if the questionnaire is clearly for a much larger company?&lt;/h3&gt;
&lt;p&gt;Say so politely and answer what applies. Questions about a dedicated SOC, a CISO
or segregated development teams have honest answers at forty people, and
compensating controls described plainly land better than pretending.&lt;/p&gt;
&lt;h3&gt;Can I refuse to complete one?&lt;/h3&gt;
&lt;p&gt;You can push back on scope, particularly on a questionnaire disproportionate to
the contract value, and offering your certificate plus SoA in place of 240
questions sometimes works. Refusing entirely usually costs the deal.&lt;/p&gt;
&lt;h3&gt;Who should sign it off?&lt;/h3&gt;
&lt;p&gt;Whoever can commit the company, because the answers are representations. In
practice you write it and a director reviews and sends it, which is also the
&lt;a href=&quot;/consulting/&quot;&gt;leadership involvement&lt;/a&gt; an auditor expects to see around
external commitments.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Intune configuration as code: export it, commit it, know what changed</title>
    <link href="https://acloud.solutions/notes/intune-configuration-as-code-drift/"/>
    <id>https://acloud.solutions/notes/intune-configuration-as-code-drift/</id>
    <updated>2026-03-10T09:00:00Z</updated>
    <published>2026-03-10T09:00:00Z</published>
    <category term="Microsoft 365, Entra and Intune"/>
    <summary>Intune configuration as code means exporting policy to JSON and committing it, so you know which property drifted and when. Evidence as a side effect.</summary>
    <content type="html">&lt;p&gt;Somebody changed a setting. Compliance went from 96 percent to 71 percent
overnight. The portal will happily show you the current state of every policy,
and it will not tell you which of two hundred settings moved, when, or who moved
it.&lt;/p&gt;
&lt;p&gt;Intune configuration as code fixes that in about an afternoon, and the fix is
unglamorous: export the policies to JSON, commit them to a repository, and diff
the live state against what is committed.&lt;/p&gt;
&lt;h2&gt;What intune configuration as code actually gets you&lt;/h2&gt;
&lt;p&gt;Three things, and the third is the one people did not expect to want.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A named property rather than a changed policy.&lt;/strong&gt; A diff that says
&lt;code&gt;passwordMinimumLength: 12 -&amp;gt; 8&lt;/code&gt; is actionable. &quot;This policy differs&quot; is not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A timestamp and an author.&lt;/strong&gt; Not from Intune, from git. The commit history is
the record the portal does not keep.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configuration management evidence.&lt;/strong&gt; If anyone is asking you for proof that
device configuration is controlled, a repository of timestamped policy states
with a diff history is materially better evidence than a screenshot taken the
week before an audit. That applies whether or not you are chasing a
certificate, and &lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers what auditors actually accept here.&lt;/p&gt;
&lt;h2&gt;Exporting&lt;/h2&gt;
&lt;p&gt;Graph returns policies as JSON already, so the export is mostly plumbing. The
part worth getting right is which endpoints to hit, because Intune policy lives
in several places.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;Connect-MgGraph -Scopes &#x27;DeviceManagementConfiguration.Read.All&#x27;

$sets = @{
    deviceConfiguration    = &#x27;deviceManagement/deviceConfigurations&#x27;
    settingsCatalog        = &#x27;deviceManagement/configurationPolicies&#x27;
    compliance             = &#x27;deviceManagement/deviceCompliancePolicies&#x27;
    endpointSecurity       = &#x27;deviceManagement/intents&#x27;
}

foreach ($name in $sets.Keys) {
    $uri = &amp;quot;https://graph.microsoft.com/beta/$($sets[$name])&amp;quot;
    $all = @()
    do {
        $page = Invoke-MgGraphRequest -Method GET -Uri $uri
        $all += $page.value
        # Paging is not optional here. configurationPolicies returns 25 at a
        # time and ignores $top, so a naive call silently reports a fraction
        # of your policies as your entire estate.
        $uri = $page.&#x27;@odata.nextLink&#x27;
    } while ($uri)

    $all | ForEach-Object {
        $safe = ($_.name ?? $_.displayName) -replace &#x27;[^\w\- ]&#x27;, &#x27;_&#x27;
        $_ | ConvertTo-Json -Depth 20 |
            Set-Content &amp;quot;baselines/$name/$safe.json&amp;quot; -Encoding utf8
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two traps worth naming, both of which have cost me time.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;configurationPolicies&lt;/code&gt; pages at 25 and ignores &lt;code&gt;$top&lt;/code&gt;. If you have 44 settings
catalog policies and no paging loop, you export 25 and your diff reports the
other 19 as deleted. The absence of an error makes this worse than a failure.&lt;/p&gt;
&lt;p&gt;And under &lt;code&gt;Set-StrictMode&lt;/code&gt;, referencing &lt;code&gt;@odata.nextLink&lt;/code&gt; on the final page
throws rather than returning null, so the loop needs the property access to be
safe. I have written a version that looped forever on the last page.&lt;/p&gt;
&lt;p&gt;Export assignments too. A policy that is correct and assigned to nobody is a
different problem from one that is wrong, and the assignment is not in the
policy object.&lt;/p&gt;
&lt;h2&gt;Diffing, and why whole-blob comparison is not enough&lt;/h2&gt;
&lt;p&gt;Comparing two JSON files with a text diff works for legacy device configuration
profiles, where the structure is flat and a changed value appears on its own
line.&lt;/p&gt;
&lt;p&gt;Settings catalog policies are the reason this needs more care. Their settings
are nested several levels deep inside &lt;code&gt;settingsDelta&lt;/code&gt; structures, values are
wrapped in typed objects, and array ordering is not guaranteed between exports.
A text diff on those produces either an enormous unreadable change or nothing at
all, depending on how the export serialised that day.&lt;/p&gt;
&lt;p&gt;So the comparison has to walk the object and normalise as it goes: sort arrays
by a stable key, ignore read-only metadata such as &lt;code&gt;lastModifiedDateTime&lt;/code&gt; and
&lt;code&gt;version&lt;/code&gt;, and report leaf properties by path. The output you want looks like
this:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;POLICY  Win10 Baseline  (deviceConfiguration)
  ~ firewallRules[2].localPortRanges   &amp;quot;3389&amp;quot;  -&amp;gt;  &amp;quot;3389,5985&amp;quot;
  ~ passwordMinimumLength              12      -&amp;gt;  8
  + smartScreenBlockOverrideForFiles   (added) true

POLICY  MacOS Platform SSO  (settingsCatalog)
  ~ authenticationMethod               &amp;quot;Password&amp;quot;  -&amp;gt;  &amp;quot;SmartCard&amp;quot;

2 policies drifted, 4 properties changed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That is a diff somebody can act on without opening the portal.&lt;/p&gt;
&lt;h2&gt;The change that looks harmless&lt;/h2&gt;
&lt;p&gt;One warning that generalises beyond Intune. Editing a policy is not always a
narrow operation.&lt;/p&gt;
&lt;p&gt;Some compliance and configuration settings trigger behaviour on every assigned
device when the policy is updated, regardless of which field you edited. A
change to an unrelated property on a policy that enforces a password
requirement can cause a password change prompt across the whole assigned fleet,
because the platform re-evaluates and re-applies rather than diffing.&lt;/p&gt;
&lt;p&gt;The practical consequences: read what a policy enforces before editing any field
on it, prefer creating a new policy and moving assignments over editing a live
one that touches credentials, and test on a filtered pilot group rather than on
All Devices. A committed baseline helps here too, because it tells you exactly
what the policy enforced before you touched it.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/mem/intune/configuration/device-profiles&quot;&gt;device configuration documentation&lt;/a&gt;
covers the policy types; the re-application behaviour is the sort of thing you
learn from a fleet-wide prompt rather than from documentation.&lt;/p&gt;
&lt;h2&gt;What to commit, and what to leave out&lt;/h2&gt;
&lt;p&gt;An export that includes everything Graph returns produces a repository where
every run looks like a change, which trains you to ignore the diff.&lt;/p&gt;
&lt;p&gt;Strip the fields the platform owns. &lt;code&gt;lastModifiedDateTime&lt;/code&gt; moves whenever
anything touches the policy, &lt;code&gt;version&lt;/code&gt; increments, and the various &lt;code&gt;@odata&lt;/code&gt;
annotations vary between API versions. None of them tell you anything about
configuration, and all of them create noise on every single run.&lt;/p&gt;
&lt;p&gt;Keep the identifiers. Policy &lt;code&gt;id&lt;/code&gt; values are stable and are how you match a
policy across exports when somebody renames it, which they will. Matching on
display name alone means a rename reads as a deletion plus an addition, and you
lose the history of the thing you actually care about.&lt;/p&gt;
&lt;p&gt;And commit the assignment separately from the policy body. Assignments change
for different reasons and on a different schedule, usually as groups are
restructured rather than as settings are tuned, so mixing them means every
group change looks like a configuration change.&lt;/p&gt;
&lt;p&gt;The repository layout that has worked for me is one directory per policy type,
one file per policy named by display name for readability, with the id inside.
That way a diff is browsable by a human and survives a rename.&lt;/p&gt;
&lt;h2&gt;Running it on a schedule&lt;/h2&gt;
&lt;p&gt;Export, commit, compare, and report only when something moved. Weekly is enough
for most estates.&lt;/p&gt;
&lt;p&gt;It has to fail loudly. A drift check that cannot reach Graph and reports no
drift has produced a clean result from an empty comparison, which is the same
silent-success problem as everywhere else in
&lt;a href=&quot;/notes/microsoft-365/&quot;&gt;these notes&lt;/a&gt;. Exit non-zero when the export fails, so a
scheduled run that could not look does not look like a run that found nothing.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Does this let me push configuration back into Intune?&lt;/h3&gt;
&lt;p&gt;Deliberately not, in the version I run. A tool that can overwrite device policy
across a fleet is a different risk category from one that reads, and the value
here is knowing what changed rather than automating the change.&lt;/p&gt;
&lt;h3&gt;What permissions does the export need?&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;DeviceManagementConfiguration.Read.All&lt;/code&gt; for policies, plus directory read to
resolve assignment group names. Certificate authentication on an app
registration is preferable to a client secret, for the reasons in
&lt;a href=&quot;/notes/expiring-credentials-app-registrations&quot;&gt;the credential expiry note&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Will a text diff not do?&lt;/h3&gt;
&lt;p&gt;For legacy device configuration profiles, usually. For settings catalog
policies, no: nesting depth and non-deterministic array ordering mean a text
diff reports either everything or nothing. Property-path comparison is the part
that makes this useful.&lt;/p&gt;
&lt;h3&gt;How do I handle policies that legitimately change often?&lt;/h3&gt;
&lt;p&gt;Commit the change with a message saying why. The point is not that nothing
changes, it is that every change has a record. A repository where every commit
has a reason is the evidence; a repository with no commits is just a snapshot.&lt;/p&gt;
&lt;h3&gt;Does the beta Graph endpoint matter?&lt;/h3&gt;
&lt;p&gt;Settings catalog policies are more complete on beta, which is why the export
above uses it. Beta can change without notice, so pin your tooling and re-test
after Intune releases. That is a real cost of using it and worth accepting
deliberately.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 compliance automation platform: what it replaces and what it does not</title>
    <link href="https://acloud.solutions/notes/compliance-automation-platforms-worth-it/"/>
    <id>https://acloud.solutions/notes/compliance-automation-platforms-worth-it/</id>
    <updated>2026-03-03T09:00:00Z</updated>
    <published>2026-03-03T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>An ISO 27001 compliance automation platform collects evidence well and cannot do your risk assessment. What they replace, and how to evaluate one.</summary>
    <content type="html">&lt;p&gt;The demo is good. A dashboard turns from red to green as integrations connect,
controls tick themselves off, and a salesperson says the word &quot;audit-ready&quot; in a
sentence about weeks rather than months. The annual price is roughly what a
contractor would cost for a month.&lt;/p&gt;
&lt;p&gt;An iso 27001 compliance automation platform is genuinely useful for one specific
thing and oversold for two others, and knowing which is which before you buy
determines whether the money was well spent.&lt;/p&gt;
&lt;h2&gt;What an iso 27001 compliance automation platform actually does well&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Evidence collection through integrations.&lt;/strong&gt; This is the real product. Connect
your identity provider, cloud accounts, device management and code repository,
and the platform pulls MFA coverage, device compliance, access lists, branch
protection and similar on a schedule, timestamps them, and keeps them.&lt;/p&gt;
&lt;p&gt;That is the part of the job that is tedious, recurring and easy to skip, and
which produces most of the anxiety before an audit. Buying it is a reasonable
trade for money, and it is the same argument as
&lt;a href=&quot;/notes/audit-evidence-automation&quot;&gt;scheduled evidence collection&lt;/a&gt; with somebody
else maintaining the scripts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Continuous monitoring against control checks.&lt;/strong&gt; The platform notices when
something drifts: a user without MFA, a machine that fell out of compliance, a
repository without required reviews. Useful, and closer to operational
monitoring than to compliance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Policy templates and acknowledgement tracking.&lt;/strong&gt; The templates are a starting
point of variable quality. The acknowledgement tracking is genuinely handy,
because chasing forty people is a job nobody wants.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auditor collaboration.&lt;/strong&gt; Some platforms give the auditor read access to the
evidence, which removes a scramble. Worth more than it sounds.&lt;/p&gt;
&lt;h2&gt;What it does not do&lt;/h2&gt;
&lt;p&gt;Three things, and each is a substantial part of the project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your risk assessment.&lt;/strong&gt; A platform can hold a risk register and offer a
starter set of risks. It cannot assess your risks, because your risks depend on
what your business does, which customers you have, what your contracts commit
you to and what you have decided to accept. A generic register imported from a
template is exactly the 214-row spreadsheet
&lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;the risk assessment note&lt;/a&gt; warns about, with
better styling.&lt;/p&gt;
&lt;p&gt;An auditor will ask how you arrived at your criteria and who owns a specific
risk. &quot;The platform suggested it&quot; is not an answer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your internal audit.&lt;/strong&gt; Clause 9.2 requires impartial auditors. A platform is
not an auditor, and the independence problem in
&lt;a href=&quot;/notes/iso-27001-internal-audit-one-person&quot;&gt;the internal audit note&lt;/a&gt; is
untouched by any amount of tooling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your management review.&lt;/strong&gt; Clause 9.3 requires management to review the ISMS
and make decisions. A dashboard is an input to that meeting, not the meeting.&lt;/p&gt;
&lt;p&gt;There is a fourth, softer thing. A platform will not give you an understanding
of your own ISMS. If it configures your controls and collects your evidence, you
may reach certification without being able to explain your own system, and Stage
2 involves being asked to explain your own system.&lt;/p&gt;
&lt;h2&gt;The scoring trap&lt;/h2&gt;
&lt;p&gt;Every platform has a readiness percentage, and it is the most persuasive and
least meaningful number in the product.&lt;/p&gt;
&lt;p&gt;It measures the platform&#x27;s own checks passing, weighted however the vendor chose.
It does not measure whether your ISMS satisfies the standard, because most of
the clauses are not automatable. So 98 percent readiness with no internal audit
and no management review is a company that will not certify, and the number will
not tell you that.&lt;/p&gt;
&lt;p&gt;Treat it as a monitoring dashboard rather than as a compliance status. Green
means the automated checks pass, which is a real and useful thing, and it is not
the same as ready.&lt;/p&gt;
&lt;h2&gt;Evaluating one, without the demo doing the work&lt;/h2&gt;
&lt;p&gt;A scorecard that produces a decision rather than an impression. Score each out
of five and weight to taste.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Integration coverage for your actual stack.&lt;/strong&gt; Not the logo wall, your systems.
If your identity is Entra, your devices are Intune, your cloud is Azure and your
code is in Azure DevOps, check every one specifically. Coverage of the
AWS-and-Okta combination is common and irrelevant to you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Evidence quality.&lt;/strong&gt; Ask to see a real evidence artefact for a control you care
about. Some platforms produce a timestamped export; some produce a green tick
whose underlying data you cannot retrieve. The tick is worthless at audit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Export and exit.&lt;/strong&gt; Can you take your evidence, policies and register out in a
usable form when you leave. A platform holding two years of evidence you cannot
export has you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework fit.&lt;/strong&gt; Many were built for SOC 2 first and added ISO 27001 later.
The mapping is usually fine and occasionally loose, particularly around clauses
4 to 10 which have no SOC 2 equivalent. Ask specifically how they handle clause
9.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auditor familiarity.&lt;/strong&gt; Ask your certification body which platforms they see
regularly. An auditor who knows the interface spends less time being shown
around.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total cost with growth.&lt;/strong&gt; Pricing is usually per employee with tiers. Model it
at your headcount in three years, not today, and check whether the price of a
second framework is incremental or another full licence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What it costs you in learning.&lt;/strong&gt; Genuine and rarely discussed. If you intend
to keep this in-house for years, a platform that does the thinking for you
leaves you less able to defend it.&lt;/p&gt;
&lt;h2&gt;The honest answer&lt;/h2&gt;
&lt;p&gt;For a company of forty with one person on this, a platform is a reasonable
purchase if you are paying for evidence collection and monitoring, and a poor
one if you are paying to avoid understanding the standard.&lt;/p&gt;
&lt;p&gt;The cheaper path is real: scheduled exports, a spreadsheet register, a document
library, and a contractor for internal audit. That is what
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; describes, and it costs less and teaches you more. It also
takes more of your time, which may be the scarcer resource.&lt;/p&gt;
&lt;p&gt;What does not work is buying a platform and treating the dashboard as the
project. The clauses it cannot automate are the ones certification turns on.&lt;/p&gt;
&lt;p&gt;No vendor is recommended here, and any comparison of specific products would go
stale before you read it. Get two trials, run the scorecard above on your own
stack, and ask each vendor to show you a real evidence artefact rather than a
dashboard. The &lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO 27001 standard&lt;/a&gt; is the
thing you are being certified against, and no tool changes what it requires.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Idle Azure VMs: the servers that have been thinking about it since 2021</title>
    <link href="https://acloud.solutions/notes/azure-idle-vms/"/>
    <id>https://acloud.solutions/notes/azure-idle-vms/</id>
    <updated>2026-02-24T09:00:00Z</updated>
    <published>2026-02-24T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>Finding idle Azure VMs with metrics rather than instinct, why a stopped VM still bills, and what to check before switching anything off.</summary>
    <content type="html">&lt;p&gt;Somewhere in your estate is a virtual machine called something like
&lt;code&gt;vm-demo-prospect&lt;/code&gt; in a resource group called &lt;code&gt;rg-poc-2022&lt;/code&gt;. It was built for a
customer presentation. The presentation happened. The customer did not sign. The
VM has been running for three and a half years at roughly the price of a
streaming subscription per week, and nobody has switched it off because nobody
is certain what it does.&lt;/p&gt;
&lt;p&gt;Idle azure vms are harder than orphaned disks for exactly that reason. An
unattached disk has no user. A quiet VM might have one person who runs one thing
on it once a quarter, and that person will find you.&lt;/p&gt;
&lt;h2&gt;Defining idle azure vms with metrics rather than instinct&lt;/h2&gt;
&lt;p&gt;&quot;Nobody uses it&quot; is not a finding, it is a hunch. Three metrics over a window of
14 to 30 days will turn it into something you can put in a ticket.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CPU percentage.&lt;/strong&gt; The obvious one, and the least reliable on its own. A busy
idle machine is a real thing: antivirus scans, patch agents and monitoring
consume CPU on a box doing nothing useful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Network in and out.&lt;/strong&gt; More telling. A server nobody connects to has a
characteristic profile: small, regular blips from agents phoning home, and
nothing else. If network traffic never exceeds a few kilobytes outside a
five-minute window each hour, the only thing talking to that machine is your own
monitoring.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disk operations per second.&lt;/strong&gt; The tiebreaker. A machine running a real
workload writes something. Logs, temporary files, a database checkpoint. A
machine at genuinely zero write IOPS for a fortnight is not doing work.&lt;/p&gt;
&lt;p&gt;Take all three together and the picture is usually unambiguous. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-monitor/vm/monitor-virtual-machine&quot;&gt;monitoring documentation for virtual machines&lt;/a&gt;
covers which metrics are available without an agent, which matters because half
the candidates will not have one installed.&lt;/p&gt;
&lt;p&gt;A 14 day window catches weekly patterns. A 30 day window catches monthly ones,
which is what you want before touching anything that might be a month-end job.&lt;/p&gt;
&lt;h2&gt;Stopped is not the same as deallocated&lt;/h2&gt;
&lt;p&gt;This one costs people real money, and the portal does not help.&lt;/p&gt;
&lt;p&gt;A VM in the &lt;strong&gt;Stopped&lt;/strong&gt; state has been shut down from inside the guest operating
system. Azure is still holding the compute reservation for it, and you are still
paying for it. From the guest&#x27;s point of view it is off. From the bill&#x27;s point of
view very little has changed.&lt;/p&gt;
&lt;p&gt;A VM in the &lt;strong&gt;Stopped (deallocated)&lt;/strong&gt; state has released its compute. You stop
paying for the compute. You carry on paying for the disks, because the disks
still exist and managed disks bill from creation to deletion regardless of what
is attached.&lt;/p&gt;
&lt;p&gt;So &quot;we turned that server off last year&quot; and &quot;that server costs nothing&quot; are
different statements, and the gap between them is the entire compute charge.
Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/virtual-machines/states-billing&quot;&gt;VM power states documentation&lt;/a&gt;
sets out which states bill and which do not, and it is worth reading once
properly.&lt;/p&gt;
&lt;p&gt;The practical consequence: when you audit for idle machines, check power state
as well as metrics. A machine sitting in Stopped rather than deallocated is
free money, because somebody already decided they did not need it and the saving
was never realised.&lt;/p&gt;
&lt;h2&gt;Auto-shutdown, and why it gets removed&lt;/h2&gt;
&lt;p&gt;Dev/test boxes should not run overnight. Azure has a built-in auto-shutdown
schedule on the VM blade, and DevTest Labs has a richer version, and both work.&lt;/p&gt;
&lt;p&gt;The reason they end up disabled is always the same. Somebody was working late,
the machine shut down under them, they lost what they were doing, and they
turned the schedule off rather than turning it back on the next morning. If you
are introducing auto-shutdown to machines other people use, the notification
webhook and the grace period matter more than the schedule.&lt;/p&gt;
&lt;p&gt;Start with the boxes nobody is emotionally attached to: build agents, scratch
environments, anything with &lt;code&gt;poc&lt;/code&gt; or &lt;code&gt;demo&lt;/code&gt; in the name.&lt;/p&gt;
&lt;h2&gt;What to check before switching anything off&lt;/h2&gt;
&lt;p&gt;Deallocating a machine that turns out to matter is a worse afternoon than
leaving it running for another month. Five checks, in order of how often they
save me.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who created it.&lt;/strong&gt; The activity log holds creation events for 90 days. Beyond
that, tags if you have them, which is the argument for
&lt;a href=&quot;/notes/azure-tagging-strategy-that-survives&quot;&gt;a tagging strategy that survives&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What talks to it.&lt;/strong&gt; NSG flow logs if enabled, or just the network metrics. An
inbound connection from one internal address at 03:00 on the first of the month
is a scheduled job, not noise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Whether it is in a backup or replication policy.&lt;/strong&gt; A machine somebody set up
Site Recovery for was important to somebody.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Whether anything references its name.&lt;/strong&gt; A DNS record, a connection string in
App Configuration, a hardcoded hostname in a script. This is the one that
catches people.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What it would cost to be wrong.&lt;/strong&gt; Deallocate rather than delete, leave it for
a fortnight, and see who shouts. Deallocated machines can be started again in
minutes and cost only their disks in the meantime.&lt;/p&gt;
&lt;p&gt;That last one is the whole technique. Deallocation is a reversible experiment
with a measurable saving, and it converts an argument about whether a machine is
needed into an observation.&lt;/p&gt;
&lt;p&gt;There is a variant worth knowing for the machines nobody will authorise you to
touch. Deallocate on a Friday evening and start it again on Monday morning, on a
schedule, for a month. If nothing breaks and nobody notices, you have a month of
evidence rather than an opinion, and the saving is already banked while the
conversation happens. If something does break, it broke on a weekend with a
five minute fix, which is the cheapest possible way to learn that a machine
matters.&lt;/p&gt;
&lt;h2&gt;Where this fits&lt;/h2&gt;
&lt;p&gt;Idle machines are the second thing to look at after
&lt;a href=&quot;/notes/orphaned-azure-resources&quot;&gt;orphaned resources&lt;/a&gt;, and in that order for a
reason. Orphans have no owner to consult, so they are pure administrative work.
Idle machines need a conversation, and conversations are easier once you have
already saved the company something.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt; includes the idle VM check
alongside the orphan sweep, with the metric window as a parameter so you can run
14 days for a quick look and 30 for the version you act on.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>The ISO 27001 surveillance audit nobody warns you about</title>
    <link href="https://acloud.solutions/notes/iso-27001-surveillance-audit/"/>
    <id>https://acloud.solutions/notes/iso-27001-surveillance-audit/</id>
    <updated>2026-02-17T09:00:00Z</updated>
    <published>2026-02-17T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>The ISO 27001 surveillance audit samples the year you stopped paying attention. Which controls lapse first, and the calendar that prevents it.</summary>
    <content type="html">&lt;p&gt;The certificate arrived, the deal closed, and the ISMS went quiet. Not
neglected exactly. It is just that the risk register was last opened in
November, the supplier reviews were a certification-week activity nobody
repeated, and the training records cover the people who were here a year ago.&lt;/p&gt;
&lt;p&gt;Then the iso 27001 surveillance audit is booked for six weeks&#x27; time, and it
samples precisely the twelve months you were not thinking about it.&lt;/p&gt;
&lt;h2&gt;What the iso 27001 surveillance audit actually samples&lt;/h2&gt;
&lt;p&gt;Certification runs on a three-year cycle. Year one is the initial audit, Stage 1
and Stage 2. Years two and three are surveillance audits, shorter than the
original and narrower in scope. Year four is recertification, which is a full
audit again.&lt;/p&gt;
&lt;p&gt;Surveillance is not a lighter version of Stage 2 across the whole system. It
samples, and the sampling is not random. Expect four things every time:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anything the previous audit raised.&lt;/strong&gt; Findings and observations from last time
are checked first. A minor you closed with a corrective action plan will be
tested to see whether the preventive part worked, not just whether the
correction happened.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The mandatory annual activities.&lt;/strong&gt; Internal audit, management review, risk
register review. These have to have happened in the intervening year, on the
schedule you documented. This is the most common source of year two findings and
the easiest to avoid.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A sample of controls&lt;/strong&gt;, weighted toward whatever is highest risk in your own
register and whatever changed in your business.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes.&lt;/strong&gt; New systems, new suppliers, headcount growth, a scope change. The
auditor reads your own change records and asks whether the ISMS kept up.&lt;/p&gt;
&lt;p&gt;Recertification in year four differs by being comprehensive again, and by
looking at the whole three-year arc: has the system improved, have findings
recurred, has the risk assessment evolved as the business did.&lt;/p&gt;
&lt;h2&gt;The controls that lapse first&lt;/h2&gt;
&lt;p&gt;There is a pattern, and it is entirely predictable, because the controls that
lapse are the ones with an annual or quarterly cadence and no operational
trigger.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Access reviews.&lt;/strong&gt; Quarterly in your documented process, performed twice in the
year, both times in the fortnight before something. Nothing breaks when a review
is missed, so nothing prompts it.
&lt;a href=&quot;/notes/azure-rbac-stale-assignments&quot;&gt;The RBAC review note&lt;/a&gt; covers the mechanics;
the failure here is diary rather than method.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Supplier reviews.&lt;/strong&gt; Done thoroughly during certification because the auditor
was going to ask, then not again. Meanwhile you onboarded three new SaaS tools
on somebody&#x27;s company card, which is
&lt;a href=&quot;/notes/vendor-risk-review-small-company&quot;&gt;the supplier review problem&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Training and awareness records.&lt;/strong&gt; The gap is joiners. Everyone who was here at
certification was trained. The four people who joined since may not have been,
and joiner training is exactly what an auditor samples because it is easy to
check against a starter list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Internal audit.&lt;/strong&gt; The single most common year two major, because it requires
scheduling somebody who is not you and nothing prompts it until it is too late.
&lt;a href=&quot;/notes/iso-27001-internal-audit-one-person&quot;&gt;The internal audit note&lt;/a&gt; says book
it early, and that applies to year two on the day you finish year one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Management review.&lt;/strong&gt; Frequently happens as a conversation without minutes, so
it did happen and cannot be evidenced. Decisions with owners and dates, or it
did not occur.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Business continuity testing.&lt;/strong&gt; An annual commitment in most plans, and an
easy one to defer indefinitely.
&lt;a href=&quot;/notes/bcdr-tabletop-exercise-small-company&quot;&gt;A two-hour tabletop&lt;/a&gt; satisfies it
and takes less effort than the deferral costs.&lt;/p&gt;
&lt;p&gt;Notice what these have in common. None of them are technical controls, and none
of them fail visibly. The technical controls mostly keep working because
something breaks when they do not.&lt;/p&gt;
&lt;h2&gt;A calendar instead of heroics&lt;/h2&gt;
&lt;p&gt;The fix is not effort, it is a recurring calendar with owners, set up in the
week after certification while you still remember what you committed to.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Monthly    Evidence exports: access lists, MFA coverage,
           device compliance, backup outcomes, credential expiry
Quarterly  Access review, with the four-line decision record
           Risk register review, recorded even when nothing changed
Half year  Supplier review for tier one suppliers
Annually   Internal audit (book 6 months ahead)
           Management review, minuted with decisions
           Policy review cycle
           BC/DR exercise
           Full supplier register review
           Training refresh, plus joiner training on start
Per event  New supplier assessment, scope change,
           incident post-mortem, leaver process
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two properties make this work. Every line has a named owner, which for most of
them is you and for management review is not. And every line produces an
artefact with a date, because the calendar entry is not the evidence.&lt;/p&gt;
&lt;p&gt;The monthly line is the one worth automating rather than remembering, per
&lt;a href=&quot;/notes/audit-evidence-automation&quot;&gt;scheduled evidence collection&lt;/a&gt;. If those
exports run themselves, the quarterly and annual activities become five-minute
reviews of data that already exists rather than half-day collection exercises,
and that difference is what determines whether they happen.&lt;/p&gt;
&lt;h2&gt;Carried-over findings&lt;/h2&gt;
&lt;p&gt;A finding that recurs is treated very differently from a new one.&lt;/p&gt;
&lt;p&gt;The same lapse in consecutive years suggests the corrective action was cosmetic,
which raises a question about the management system rather than about the
control. That can escalate a minor into a major, and it is the mechanism by
which a certificate gets genuinely threatened.&lt;/p&gt;
&lt;p&gt;So when closing a finding, the preventive action has to be structural. Not &quot;the
review has now been done&quot;, but &quot;the review had no owner and no calendar entry,
both are now assigned to a named role with a recurring reminder, and the
management review agenda includes a check that it happened&quot;. That is what stops
it recurring, and it is also what the auditor is looking for in the wording.&lt;/p&gt;
&lt;h2&gt;The honest version of year two&lt;/h2&gt;
&lt;p&gt;Certification is a project with a deadline and adrenaline. Maintenance is
neither, and it competes with everything else on your list against a deadline
eleven months away.&lt;/p&gt;
&lt;p&gt;The companies that find surveillance uneventful are not the ones with better
documentation. They are the ones where the recurring activities have owners and
calendar entries, and where the monthly evidence collection happens without
anybody deciding to do it.&lt;/p&gt;
&lt;p&gt;Setting that up takes an afternoon in the month after certification. Not doing
it costs a fortnight next year, at a time you will not have chosen.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; has a chapter on year two specifically, because it was the
part that surprised me most, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; covers maintenance as well as
implementation, which is generally the less glamorous and more useful half. The
&lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO 27001 standard&lt;/a&gt; sets out the clause 9
and 10 requirements the surveillance audit is testing.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure NSG rules audit: the any-any that was definitely temporary</title>
    <link href="https://acloud.solutions/notes/azure-nsg-rules-audit/"/>
    <id>https://acloud.solutions/notes/azure-nsg-rules-audit/</id>
    <updated>2026-02-10T09:00:00Z</updated>
    <published>2026-02-10T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>An Azure NSG rules audit finds the any-any nobody removed, rules with no description, and priority collisions where the rule is not what flows.</summary>
    <content type="html">&lt;p&gt;The rule is at priority 100. It is called &lt;code&gt;temp-allow-rdp&lt;/code&gt;. Source is &lt;code&gt;*&lt;/code&gt;,
destination port is 3389, action is Allow, and it was created on a Friday
afternoon in 2022 by somebody who needed to get onto a box quickly and fully
intended to remove it.&lt;/p&gt;
&lt;p&gt;An azure nsg rules audit is mostly an exercise in finding that rule, and its
several cousins, and then working out which of them is load-bearing.&lt;/p&gt;
&lt;h2&gt;What an azure nsg rules audit should look for&lt;/h2&gt;
&lt;p&gt;Four things, in descending order of how much they matter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inbound Allow from any source on a management port.&lt;/strong&gt; RDP on 3389, SSH on 22,
WinRM on 5985 and 5986, SQL on 1433, and the database ports for whatever else you
run. Source of &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;0.0.0.0/0&lt;/code&gt;, &lt;code&gt;Internet&lt;/code&gt; or &lt;code&gt;Any&lt;/code&gt; are all the same finding
written four ways, which is one reason this is easy to miss when reading the
portal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rules with no description.&lt;/strong&gt; Not a vulnerability. A finding about
maintainability, and the single best predictor of whether anyone will dare to
remove a rule later. A rule with no description and a name like &lt;code&gt;Rule_1&lt;/code&gt; is one
nobody will ever safely delete, so it will outlive the thing it was for.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overly broad port ranges.&lt;/strong&gt; &lt;code&gt;0-65535&lt;/code&gt; on an inbound Allow, or a range that
was written to cover two services and now covers three hundred. Also worth
checking for ranges specified as a list, because a rule permitting &lt;code&gt;22,3389,1433&lt;/code&gt;
reads as one rule and behaves as three.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Priority collisions and shadowing.&lt;/strong&gt; Two rules that overlap, where the lower
priority number wins and the other one is decoration. Harmless until somebody
edits the wrong one and nothing changes, at which point an afternoon disappears.&lt;/p&gt;
&lt;h2&gt;The rule list is not what flows&lt;/h2&gt;
&lt;p&gt;This is the part that catches experienced people, and it is worth being precise
about.&lt;/p&gt;
&lt;p&gt;An NSG rule list tells you what is permitted at that NSG. It does not tell you
what actually reaches a machine, because several things sit between the two.&lt;/p&gt;
&lt;p&gt;NSGs apply at both subnet and network interface level, and traffic has to be
permitted by both. So a permissive subnet rule may be irrelevant because the NIC
NSG blocks it, and an audit that reads only one level will report a finding that
is not real.&lt;/p&gt;
&lt;p&gt;Application Security Groups make the source or destination a membership rather
than an address range, so reading the rule alone tells you nothing about scope
until you resolve the group.&lt;/p&gt;
&lt;p&gt;Service tags such as &lt;code&gt;Internet&lt;/code&gt;, &lt;code&gt;AzureCloud&lt;/code&gt; and &lt;code&gt;Storage&lt;/code&gt; expand to address
ranges Microsoft maintains and changes. &lt;code&gt;Internet&lt;/code&gt; is not a subtle tag, but
&lt;code&gt;AzureCloud&lt;/code&gt; is broader than most people assume and includes other tenants&#x27;
resources.&lt;/p&gt;
&lt;p&gt;And a machine with no public IP address and no inbound NAT is not reachable from
the internet regardless of what its NSG permits. An NSG allowing 3389 from &lt;code&gt;*&lt;/code&gt; on
a machine with only a private address is untidy rather than urgent.&lt;/p&gt;
&lt;p&gt;So the audit produces candidates. Confirming them means checking whether the
machine is reachable at all, which is why the useful output pairs each rule with
whether the resources behind it have a public address.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview&quot;&gt;network security group documentation&lt;/a&gt;
covers the evaluation order and the default rules, and the default rules are
worth knowing because &lt;code&gt;AllowVnetInBound&lt;/code&gt; explains a lot of traffic people expect
to be blocked.&lt;/p&gt;
&lt;h2&gt;Reading the rules&lt;/h2&gt;
&lt;p&gt;The shape that works, with the parsing that matters:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-AzNetworkSecurityGroup | ForEach-Object {
    $nsg = $_
    $nsg.SecurityRules | Where-Object {
        $_.Direction -eq &#x27;Inbound&#x27; -and $_.Access -eq &#x27;Allow&#x27;
    } | ForEach-Object {
        # Prefixes and ports are collections, not strings. A rule with several
        # of either looks like one rule and behaves like several.
        $prefixes = @($_.SourceAddressPrefix) + @($_.SourceAddressPrefixes)
        $ports    = @($_.DestinationPortRange) + @($_.DestinationPortRanges)
        [pscustomobject]@{
            NSG         = $nsg.Name
            Rule        = $_.Name
            Priority    = $_.Priority
            Sources     = ($prefixes | Where-Object { $_ }) -join &#x27;,&#x27;
            Ports       = ($ports | Where-Object { $_ }) -join &#x27;,&#x27;
            Description = $_.Description
        }
    }
} | Sort-Object NSG, Priority
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The detail worth stealing there is treating the prefix and port fields as
collections. &lt;code&gt;SourceAddressPrefix&lt;/code&gt; holds a single value and
&lt;code&gt;SourceAddressPrefixes&lt;/code&gt; holds a list, and a rule uses one or the other. Code that
only reads the singular field silently misses every multi-value rule, which are
usually the interesting ones. I have written that bug and it reported a clean
estate.&lt;/p&gt;
&lt;h2&gt;What to do with the findings&lt;/h2&gt;
&lt;p&gt;Not &quot;delete the any-any&quot;, at least not first.&lt;/p&gt;
&lt;p&gt;Narrow it. Replace &lt;code&gt;*&lt;/code&gt; with the office address range, or the VPN range, or a
specific address. A rule scoped to something is defensible in a way a rule
scoped to everything is not, and narrowing rarely breaks anything because the
people using it are coming from somewhere identifiable.&lt;/p&gt;
&lt;p&gt;Where a management port genuinely needs to be open to arbitrary sources, that is
an argument for Bastion or just-in-time access rather than a better NSG rule.
Both remove the standing rule entirely, which is the only version of this that
stays fixed.&lt;/p&gt;
&lt;p&gt;And write a description on every rule you touch, including the ones you decide to
keep. The description is what lets the next person, quite possibly you, tell the
difference between a rule that matters and a rule from a Friday afternoon.&lt;/p&gt;
&lt;h2&gt;The rules that are fine and look alarming&lt;/h2&gt;
&lt;p&gt;An audit that reports everything permissive as a finding trains people to ignore
it, so it is worth knowing which patterns are usually correct.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;AllowVnetInBound&lt;/code&gt; at priority 65000 permits everything within the virtual
network. It is a default rule, it is present on every NSG, and removing it
breaks more than it fixes. Report it once as context, not as a finding.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;AzureLoadBalancer&lt;/code&gt; as a source on a health probe port is how load balancer
probes reach a backend. Blocking it takes the pool offline, which is a
memorable way to learn this.&lt;/p&gt;
&lt;p&gt;Broad rules on a subnet that contains only a Bastion host are the intended
design, because Bastion needs specific inbound ranges from Microsoft to work at
all.&lt;/p&gt;
&lt;p&gt;And a permissive rule on a machine with no public address is untidy rather than
exposed, which is the distinction the reachability check exists to make. Sorting
findings by whether the resource has a public IP address puts the ones that
matter at the top and keeps the rest as a tidying backlog rather than an
incident.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;NSG rules are one of the ten checks in the
&lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt;, and it reads rather than writes for
the obvious reason: a script that edits firewall rules across an estate is a
different risk category from one that lists them.&lt;/p&gt;
&lt;p&gt;Pair it with &lt;a href=&quot;/notes/azure-public-storage-accounts&quot;&gt;the public storage note&lt;/a&gt;,
because the two findings tend to come from the same original decision. Somebody
opened something up temporarily to get a job done, and the job finished. The
rest of the &lt;a href=&quot;/notes/azure-security/&quot;&gt;azure security notes&lt;/a&gt; cover the access and
credential side of the same habit.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 stage 1 and stage 2 audit: what the certification audit really tests</title>
    <link href="https://acloud.solutions/notes/iso-27001-stage-1-stage-2/"/>
    <id>https://acloud.solutions/notes/iso-27001-stage-1-stage-2/</id>
    <updated>2026-02-03T09:00:00Z</updated>
    <published>2026-02-03T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>The ISO 27001 stage 1 and stage 2 audit test different things. Documentation and readiness, then operation and evidence. What each looks like in practice.</summary>
    <content type="html">&lt;p&gt;Certification is two audits with a gap between them, and people prepare for the
wrong one. The effort goes into documentation, which is Stage 1, and the thing
that decides the outcome is whether controls demonstrably operated over a
period, which is Stage 2.&lt;/p&gt;
&lt;p&gt;The iso 27001 stage 1 and stage 2 audit sequence exists precisely to separate
those questions. Stage 1 asks whether you have built a management system. Stage
2 asks whether it runs.&lt;/p&gt;
&lt;h2&gt;What the iso 27001 stage 1 and stage 2 audit each examine&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Stage 1&lt;/strong&gt; is documentation and readiness, usually half a day to a day for a
small company, often remote. The auditor reads your ISMS and forms a view on
whether Stage 2 is worth scheduling.&lt;/p&gt;
&lt;p&gt;They will want the scope statement, the risk assessment method and register, the
Statement of Applicability, the risk treatment plan, the policy set, the
internal audit report and the management review minutes. They will check
internal consistency between those, which is why
&lt;a href=&quot;/notes/iso-27001-statement-of-applicability&quot;&gt;traceability between the register and the SoA&lt;/a&gt;
matters more than the quality of any single document.&lt;/p&gt;
&lt;p&gt;The output is a report, and typically some findings to close before Stage 2. That
is normal. Stage 1 producing no findings at all is unusual enough to be
surprising.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stage 2&lt;/strong&gt; is operation and evidence. Longer, usually on site or over several
sessions, and it samples. The auditor picks controls, asks how they work, and
asks to see that they did work across the period. Not that they could work.
That they did.&lt;/p&gt;
&lt;h2&gt;What evidence means in practice&lt;/h2&gt;
&lt;p&gt;This is the distinction that decides Stage 2, and it is worth being concrete
because &quot;evidence&quot; sounds vaguer than it is.&lt;/p&gt;
&lt;p&gt;A screenshot of a Conditional Access policy shows the control exists. It does
not show it operated. What operated looks like: the policy, plus the sign-in
logs demonstrating enforcement across the period, plus the record of the change
that created it, plus the review that confirmed it still fits.&lt;/p&gt;
&lt;p&gt;For access reviews, the evidence is not the access list. It is a dated record
saying who reviewed it, what they decided, what was removed, and what was
retained with a justification. Four lines and a date, as covered in
&lt;a href=&quot;/notes/audit-evidence-automation&quot;&gt;the evidence automation note&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The pattern generalises. Evidence has a date, a person, and an outcome. Anything
missing one of the three is a document rather than evidence, and the auditor
will say so.&lt;/p&gt;
&lt;p&gt;The corollary that catches people: evidence cannot be produced retrospectively.
An access review you performed in February without recording it did not happen
as far as Stage 2 is concerned, and the honest answer is to say so rather than
to write it up now and date it February.&lt;/p&gt;
&lt;h2&gt;The period being sampled&lt;/h2&gt;
&lt;p&gt;Stage 2 samples the period since the ISMS started operating, which for a first
certification is usually the preceding three to six months.&lt;/p&gt;
&lt;p&gt;That has a scheduling consequence people miss. If your ISMS started operating in
March and Stage 2 is in June, the auditor samples March to June, which includes
the months when you were still implementing. So the controls need to have been
running, and generating records, before you felt ready.&lt;/p&gt;
&lt;p&gt;The practical instruction: start capturing evidence in month one of the project,
not in the month before the audit. Monthly exports beginning early cost nothing
and are the difference between a sample that shows a system operating and a
sample that shows a system switched on last week.&lt;/p&gt;
&lt;h2&gt;The interviews&lt;/h2&gt;
&lt;p&gt;Stage 2 includes talking to people who are not you, and this is where small
companies are strongest and most nervous.&lt;/p&gt;
&lt;p&gt;The auditor asks a developer what they would do if they lost a laptop, or how
they get access to production, or who they report a suspicious email to. They
are testing whether the control operates rather than whether the person has read
the policy. Roughly right and confident passes. &quot;I think there is a policy
somewhere&quot; does not, and that is why
&lt;a href=&quot;/notes/iso-27001-policies-people-read&quot;&gt;policies people actually read&lt;/a&gt; matter
more than comprehensive ones.&lt;/p&gt;
&lt;p&gt;Where you run the ISMS alone, expect to be interviewed at length yourself, and
expect questions designed to test whether the system depends entirely on you. It
does, and saying so plainly is better than pretending otherwise. Key person
dependency belongs in your risk register as an honest entry, and having it there
turns an awkward question into evidence that you assessed your own situation
accurately.&lt;/p&gt;
&lt;h2&gt;Minor and major nonconformity&lt;/h2&gt;
&lt;p&gt;Two classifications, and the difference is consequence.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;minor nonconformity&lt;/strong&gt; is a single lapse in an otherwise functioning
control. One review missed in a year of reviews. A record incomplete. You submit
a corrective action plan with root cause, correction and preventive action, and
certification proceeds once accepted. Minors are ordinary.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;major nonconformity&lt;/strong&gt; is a control absent, a systemic failure, or a lapse
significant enough to cast doubt on the management system. No internal audit at
all. A required document missing. A control described in the SoA that has never
operated. A major blocks certification until it is closed and verified, which
usually means another visit.&lt;/p&gt;
&lt;p&gt;There is also an &lt;strong&gt;observation&lt;/strong&gt; or opportunity for improvement, which is not a
nonconformity and does not require action, though ignoring the same observation
two years running invites a finding.&lt;/p&gt;
&lt;p&gt;The useful thing to know: a corrective action plan is judged on root cause. &quot;We
forgot&quot; is not a root cause, and &quot;we have now done it&quot; is not preventive action.
&quot;The review had no owner and no calendar entry; both are now assigned to a named
role with a recurring reminder&quot; is what closes a finding first time.&lt;/p&gt;
&lt;h2&gt;Getting through it&lt;/h2&gt;
&lt;p&gt;Three things that help more than extra documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;An evidence index.&lt;/strong&gt; One page mapping each applicable control to where its
evidence lives. Auditors work faster with it, and faster audits go better
because there is more time for the substantive questions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Honesty about gaps.&lt;/strong&gt; If a control started operating in April rather than
January, say so and show April onward. An auditor who finds a gap you did not
mention starts checking everything else.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do not over-answer.&lt;/strong&gt; Answer the question asked. Volunteering adjacent detail
opens sampling in areas nobody was going to look at, which is a self-inflicted
extension of the audit.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO 27001 standard&lt;/a&gt; sets out the
requirements the auditor is testing against, and
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers the two audits in detail including the questions that
came up.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;How long is the gap between Stage 1 and Stage 2?&lt;/h3&gt;
&lt;p&gt;Typically a few weeks to a few months, depending on what Stage 1 found and how
long the operating period needs to be. The certification body proposes it. If
Stage 1 raised findings, the gap has to be long enough to close them and
generate evidence that the correction is working.&lt;/p&gt;
&lt;h3&gt;Can I fail Stage 2?&lt;/h3&gt;
&lt;p&gt;You can be issued a major nonconformity that blocks certification until closed,
which is not the same as failing permanently. The more common outcome is
certification with some minors and a corrective action plan.&lt;/p&gt;
&lt;h3&gt;What if a control has only been operating for a month?&lt;/h3&gt;
&lt;p&gt;Say so. A short operating period may produce a minor rather than a major,
depending on the control and the reason. Concealing it produces a worse outcome
than declaring it, because a discovered omission changes how the rest of the
audit is conducted.&lt;/p&gt;
&lt;h3&gt;Does the auditor need access to our systems?&lt;/h3&gt;
&lt;p&gt;Usually they ask you to demonstrate on screen rather than being granted access.
Expect to share your screen and navigate to the evidence while they watch, which
is why knowing where everything is matters more than having it all printed.&lt;/p&gt;
&lt;h3&gt;Who should be available on the day?&lt;/h3&gt;
&lt;p&gt;Whoever owns risks, whoever approves policies, and a sample of ordinary staff.
For a company of forty that is typically a director, whoever leads engineering,
and two or three others. Warn them in advance what to expect, without coaching
them on answers, because coached answers are recognisable and counterproductive.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Break glass account Entra setup: the fire extinguisher you never test</title>
    <link href="https://acloud.solutions/notes/break-glass-accounts/"/>
    <id>https://acloud.solutions/notes/break-glass-accounts/</id>
    <updated>2026-01-27T09:00:00Z</updated>
    <published>2026-01-27T09:00:00Z</published>
    <category term="Microsoft 365, Entra and Intune"/>
    <summary>A break glass account Entra setup that works: two cloud-only accounts, excluded from policy, alerted on any use, and tested before you need them.</summary>
    <content type="html">&lt;p&gt;The password is in a Teams message from 2023. The message is in a chat with
somebody who has left. Nobody has signed into the account since it was created,
so nobody knows whether it still works, and the one circumstance in which
anybody will find out is the circumstance where nothing else does.&lt;/p&gt;
&lt;p&gt;A break glass account entra tenants need is not complicated to create. What
makes it useful is the four things around it that nobody does: the exclusions,
the storage, the monitoring, and the test.&lt;/p&gt;
&lt;h2&gt;Why a break glass account entra setup matters more when you are alone&lt;/h2&gt;
&lt;p&gt;In a tenant with six administrators, a Conditional Access policy that locks
everybody out is embarrassing. Somebody else fixes it.&lt;/p&gt;
&lt;p&gt;In a tenant with one, it is an outage with no internal resolution path. Your
options are a Microsoft support case, which means proving you are who you say
you are while unable to log in, or waiting. Both take hours, during which nobody
in the company can access email.&lt;/p&gt;
&lt;p&gt;That asymmetry is the entire argument. The break-glass account is not protection
against an attacker. It is protection against yourself, on an afternoon when you
were confident about a policy change.&lt;/p&gt;
&lt;h2&gt;What the accounts look like&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Two of them.&lt;/strong&gt; One is a single point of failure, and the failure mode you are
guarding against includes &quot;this specific account has a problem&quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloud-only.&lt;/strong&gt; No synchronisation from on-premises Active Directory, because a
break-glass account that depends on a sync running is not a break-glass account.
No dependency on anything that could be part of the failure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Named so their purpose is obvious.&lt;/strong&gt; Something like
&lt;code&gt;emergency-access-01@yourdomain.com&lt;/code&gt;. Not a name that looks like a person,
because in six months somebody reviewing accounts needs to not delete it, and
&quot;who is emergency.access&quot; is a conversation that ends badly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No licences.&lt;/strong&gt; They need no mailbox and no Teams. A licence is an attack
surface and a cost with no purpose here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Permanently assigned Global Administrator.&lt;/strong&gt; This is the one place where
standing privilege is correct, and it is worth being explicit about because it
contradicts everything in
&lt;a href=&quot;/notes/privileged-identity-management-small-tenant&quot;&gt;the PIM note&lt;/a&gt;. An eligible
role you have to activate is no use if the thing that is broken is the mechanism
that activates it.&lt;/p&gt;
&lt;h2&gt;Excluded from everything&lt;/h2&gt;
&lt;p&gt;Every Conditional Access policy excludes these accounts. Not most. Every one,
including the ones you add later, which is why the exclusion should be a group
rather than two named accounts.&lt;/p&gt;
&lt;p&gt;Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/security-emergency-access&quot;&gt;emergency access account guidance&lt;/a&gt;
sets this out, and the reasoning is worth internalising rather than just
following: the account has to work when the policy engine is the thing that is
wrong. A break-glass account subject to a policy is protected by the system it
exists to rescue you from.&lt;/p&gt;
&lt;p&gt;That does mean these accounts are not protected by MFA policy. The protection
comes from somewhere else, and it has to be real.&lt;/p&gt;
&lt;h2&gt;Where the password lives&lt;/h2&gt;
&lt;p&gt;Not in Teams. Not in email. Not in the password manager you sign into with the
account that is currently locked out, which is the circular dependency people
build without noticing.&lt;/p&gt;
&lt;p&gt;The options that work, roughly in order of practicality for a small company:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Split the credential between two people.&lt;/strong&gt; Half each, sealed, written down. Two
people have to be present to use it, which is also an access control. This
sounds antiquated and it works, because paper does not have a
dependency on your identity provider.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A physical safe&lt;/strong&gt;, with the sealed envelope and a log of when it was opened.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A separate password manager&lt;/strong&gt;, on a different identity provider entirely, with
its own MFA on a device that is not the one you are trying to recover.&lt;/p&gt;
&lt;p&gt;The test for any of these: if Entra ID is completely unavailable, can you still
get the password. If the answer involves signing into anything in the tenant,
start again.&lt;/p&gt;
&lt;p&gt;Store the recovery method for the second factor alongside it. A password you can
retrieve and a hardware key you cannot find is not a working credential.&lt;/p&gt;
&lt;h2&gt;Monitoring for any use&lt;/h2&gt;
&lt;p&gt;These accounts should never sign in. So any sign-in is either an emergency or an
incident, and both want you to know within minutes.&lt;/p&gt;
&lt;p&gt;That is one of the easiest high-value detections to write, because the baseline
is zero:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;kusto&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-kusto&quot;&gt;SigninLogs
| where TimeGenerated &amp;gt; ago(1h)
| where UserPrincipalName has &amp;quot;emergency-access&amp;quot;
| project TimeGenerated, UserPrincipalName, IPAddress, Location,
          AppDisplayName, ResultType, ResultDescription
| order by TimeGenerated desc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Set it to alert at High severity with no threshold. There is no acceptable
number of sign-ins per day, so there is no rate to tune, which makes this one of
the few rules that will never need adjusting. Validate that it can run, for the
reasons in
&lt;a href=&quot;/notes/sentinel-analytics-rules-validation&quot;&gt;the detection validation note&lt;/a&gt;,
because a rule watching your last resort is a poor choice of rule to leave
untested.&lt;/p&gt;
&lt;p&gt;If you do not run Sentinel, an Entra sign-in alert or a scheduled Graph query
emailing you is adequate. The mechanism matters less than the fact that
something is watching.&lt;/p&gt;
&lt;h2&gt;Testing, which is the part everyone skips&lt;/h2&gt;
&lt;p&gt;A fire extinguisher nobody has checked is a red cylinder.&lt;/p&gt;
&lt;p&gt;Quarterly, sign in with one of them. Confirm the credential works, confirm the
alert fires, confirm the account still holds Global Administrator, and write
down the date. Fifteen minutes.&lt;/p&gt;
&lt;p&gt;The two failures this catches are both common. The credential has drifted,
because somebody rotated it and updated one copy. And the alert never worked,
usually because the rule was written against a table that is not being
ingested, which you would otherwise discover during the outage.&lt;/p&gt;
&lt;p&gt;Rotate the credentials annually and when anybody who had access to them leaves.
The record of those tests is also the evidence an auditor will ask for, because
this sits under access control and business continuity at once, and
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers what that evidence needs to look like.&lt;/p&gt;
&lt;h2&gt;The thing to do this week&lt;/h2&gt;
&lt;p&gt;If you take one action from this: check whether your break-glass account is
excluded from your Conditional Access policies, and check whether you can
actually retrieve its password right now, without signing into anything.&lt;/p&gt;
&lt;p&gt;Most people discover one of those two answers is no, and it takes twenty minutes
to fix on a quiet afternoon rather than during the incident where it matters.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 internal audit small company independence, without a second employee</title>
    <link href="https://acloud.solutions/notes/iso-27001-internal-audit-one-person/"/>
    <id>https://acloud.solutions/notes/iso-27001-internal-audit-one-person/</id>
    <updated>2026-01-20T09:00:00Z</updated>
    <published>2026-01-20T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>ISO 27001 internal audit small company problem: you cannot audit your own work. Four routes to real independence, and the programme expected.</summary>
    <content type="html">&lt;p&gt;You built the ISMS. You wrote the policies, ran the risk assessment, implemented
the controls and collected the evidence. Clause 9.2 now requires an internal
audit of all of it, conducted objectively and impartially.&lt;/p&gt;
&lt;p&gt;The iso 27001 internal audit small company problem is that there is nobody else.
Auditing your own work is not impartial by any definition, and an auditor who
sees your name on both the implementation and the audit will treat the audit as
not having happened. This is the single hardest structural constraint in a
one-person ISMS, and it has no elegant answer, only four workable ones.&lt;/p&gt;
&lt;h2&gt;What clause 9.2 asks for&lt;/h2&gt;
&lt;p&gt;More than a checklist exercise, and the specifics matter because people
under-deliver on the parts that are easy.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;audit programme&lt;/strong&gt; covering frequency, methods, responsibilities, planning
and reporting, which takes account of the importance of the processes and the
results of previous audits. That last phrase means the programme is expected to
change based on what previous audits found.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Defined criteria and scope&lt;/strong&gt; for each audit. What you are auditing against and
which parts of the ISMS this audit covers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auditors selected to ensure objectivity and impartiality.&lt;/strong&gt; The wording of the
constraint, and the whole difficulty.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Results reported to relevant management&lt;/strong&gt;, and retained as documented
information.&lt;/p&gt;
&lt;p&gt;Note what it does not say. It does not require an external auditor, a
qualification, or a full audit of everything every year. A programme that
audits a third of the controls annually on a three-year cycle, weighted by
importance, is compliant and is what most small companies do.&lt;/p&gt;
&lt;h2&gt;Four routes to iso 27001 internal audit small company independence&lt;/h2&gt;
&lt;p&gt;In rough order of how well they work at this scale.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A trained colleague from another function.&lt;/strong&gt; Somebody in finance, operations
or engineering who did not build the ISMS. They need enough understanding to
audit, which is a day of training and a good checklist, not a qualification.
This is the cheapest option and the one auditors are most used to seeing. It
works because impartiality is about not having done the work, not about
expertise.&lt;/p&gt;
&lt;p&gt;The limitation is that they cannot meaningfully audit deeply technical controls,
because they lack the knowledge to know when an answer is evasive. Split the
programme: they audit the management system clauses and the organisational and
people controls, and buy in the technical half.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A contractor.&lt;/strong&gt; Half a day to two days depending on scope. Genuine
independence, genuine expertise, and a report that reads like an auditor wrote
it. The cost is real but it is the cheapest line in the certification budget and
the easiest to justify.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A reciprocal arrangement with a peer.&lt;/strong&gt; Somebody in a similar role at another
company audits yours and you audit theirs. Free, genuinely independent, and
mutually educational because you both see how somebody else solved the same
problems. The practical obstacles are confidentiality, which needs an agreement
in place, and finding the person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Your certification body&#x27;s own consulting arm, or a member of the group
company.&lt;/strong&gt; Be careful here. A certification body cannot both consult on and
certify the same ISMS, and using an entity connected to your certification body
for internal audit invites questions about the independence of the whole
arrangement. Ask first.&lt;/p&gt;
&lt;p&gt;What does not work: auditing your own work and describing it as a self
assessment, then hoping the wording covers it. It does not, and it is the sort of
finding that raises questions about everything else.&lt;/p&gt;
&lt;h2&gt;Book it early, because availability is the constraint&lt;/h2&gt;
&lt;p&gt;The practical failure is not choosing the wrong option, it is choosing late.&lt;/p&gt;
&lt;p&gt;Internal audit has to happen before the certification audit, because Stage 1
will ask whether it has. Contractors and peers have diaries. Somebody leaving
mid-arrangement, or a rebooked date that slips past your Stage 1, turns a solved
problem back into an open one, and by then there is no slack.&lt;/p&gt;
&lt;p&gt;Book it in the first fortnight of the project, for a date about two months
before your target Stage 1. That leaves time to fix what it finds, which is the
entire purpose.&lt;/p&gt;
&lt;p&gt;Give the auditor the documents a week ahead: scope statement, risk register,
&lt;a href=&quot;/notes/iso-27001-statement-of-applicability&quot;&gt;Statement of Applicability&lt;/a&gt; and
the evidence index. An auditor reading those beforehand spends the day testing
rather than orienting, which roughly doubles what half a day buys you.&lt;/p&gt;
&lt;h2&gt;The programme, on one page&lt;/h2&gt;
&lt;p&gt;An audit programme does not need to be long. It needs to exist and to be
followed.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Cycle: three years, all clauses and applicable controls covered
Frequency: annually, or after significant change
Auditor: [named contractor or colleague], not involved in ISMS operation

Year 1: Clauses 4-6, 9-10. Controls 5.1-5.23 (organisational),
        6.1-6.8 (people)
Year 2: Clauses 7-8. Controls 8.1-8.16 (technological, first half)
Year 3: Controls 8.17-8.34, 7.1-7.14 (physical). Full clause review

Weighting: access control, supplier management and incident response
  audited every year regardless of cycle position, on the basis of
  risk register scores R-01, R-04, R-09.
Inputs: previous audit findings, risk register, nonconformity log.
Reporting: written report to management review within 4 weeks.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The weighting line is what makes it a programme rather than a rota, and it is
the part that satisfies &quot;taking account of the importance of the processes&quot;.&lt;/p&gt;
&lt;h2&gt;The report, and what it must contain&lt;/h2&gt;
&lt;p&gt;Auditors read internal audit reports carefully, because a good one is evidence
that the system examines itself.&lt;/p&gt;
&lt;p&gt;It needs the scope and criteria, the dates, who conducted it, what was examined
including which records were sampled, the findings classified consistently, and
the agreed actions with owners and dates.&lt;/p&gt;
&lt;p&gt;The most important property: it must contain findings. An internal audit report
concluding that everything is satisfactory is not reassuring, it is implausible,
and it suggests the audit was not searching. Every ISMS at this stage has
something wrong with it. Finding three or four things and fixing them before
Stage 2 is precisely the value, and it is also the story you want to tell the
external auditor.&lt;/p&gt;
&lt;p&gt;Then the findings have to go somewhere. Into a nonconformity and corrective
action log, with dates, owners and evidence of closure. A finding raised and
never closed is worse than not having found it, because you documented knowing
about it.&lt;/p&gt;
&lt;h2&gt;Feeding management review&lt;/h2&gt;
&lt;p&gt;Clause 9.3 requires management review to consider internal audit results, so the
two are connected by design and the sequence matters: audit, then review, then
certification audit.&lt;/p&gt;
&lt;p&gt;Management review is its own record, and the useful framing is that it produces
decisions rather than a discussion. Decisions about resources, about risks
accepted, about actions arising from the audit. Minutes with decisions and owners
are the evidence; a calendar invite is not.&lt;/p&gt;
&lt;p&gt;If you are running both alone, the review still needs actual managers in the
room making actual decisions. That is the other place where a one-person ISMS
cannot substitute effort for authority, and
&lt;a href=&quot;/book/&quot;&gt;the book&lt;/a&gt; covers how to run a review that produces something an auditor
recognises.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO 27001 standard&lt;/a&gt; is worth reading
directly for clause 9, which is short and precise, and which people routinely
under-implement on the strength of a summary.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;/consulting/&quot;&gt;security and compliance work&lt;/a&gt; includes internal audit as an
independent party, which is the contractor option above, and is frequently the
least painful way to satisfy a clause that has no good in-house answer at this
size.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Orphaned Azure resources: an inventory of the things nobody remembers to delete</title>
    <link href="https://acloud.solutions/notes/orphaned-azure-resources/"/>
    <id>https://acloud.solutions/notes/orphaned-azure-resources/</id>
    <updated>2026-01-13T09:00:00Z</updated>
    <published>2026-01-13T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>Orphaned Azure resources are not just disks. Unassociated public IPs, empty load balancers and stale snapshots all bill quietly. How to find them.</summary>
    <content type="html">&lt;p&gt;Deleting a virtual machine in the portal does not delete the things attached to
it. It deletes the VM. The disk stays unless you ticked the box. The network
interface stays. The public IP stays, and if it is a Standard SKU address it
carries on billing at the same rate it did when something was actually
listening on it.&lt;/p&gt;
&lt;p&gt;That is the shape of most orphaned azure resources: not mistakes, but deletions
that stopped one object short. Someone removed the VM, the alert went quiet, the
ticket closed, and four objects carried on existing in a resource group nobody
opens.&lt;/p&gt;
&lt;h2&gt;What counts as orphaned azure resources&lt;/h2&gt;
&lt;p&gt;Six categories turn up repeatedly. They differ in how much they cost, which
matters when you are deciding what to look at first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unattached managed disks.&lt;/strong&gt; The expensive ones. Billed by provisioned tier
rather than by the data on them, so a 128 GB Premium SSD holding 12 GB still
bills as a P10. There is a
&lt;a href=&quot;/notes/azure-managed-disk-pricing-provisioned-tier/&quot;&gt;separate note on why disk pricing works that way&lt;/a&gt;,
and it is the single most common source of wrong cost estimates.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unassociated public IP addresses.&lt;/strong&gt; Standard SKU addresses bill whether or not
anything is behind them. This catches people out because Basic SKU addresses
behaved differently, and Microsoft has been retiring Basic, so estates that were
free of this problem have been acquiring it. The
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/public-ip-addresses&quot;&gt;public IP address documentation&lt;/a&gt;
covers the SKU differences.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Load balancers with an empty backend pool.&lt;/strong&gt; Basic Load Balancer was free.
Standard is not, and it bills on rules and processed data regardless of whether
the backend pool contains anything. A Standard load balancer pointing at nothing
is a rule set with a monthly charge.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Network interfaces with no VM.&lt;/strong&gt; These genuinely cost nothing. They are worth
listing anyway, because a NIC with no VM is evidence that a deletion did not
finish, and where you find one you usually find the disk and the IP as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stale snapshots.&lt;/strong&gt; Cheaper per gigabyte than disks and easier to accumulate,
because every backup tool and every cautious engineer creates them. Covered
properly in &lt;a href=&quot;/notes/azure-snapshots-cost&quot;&gt;the note on snapshot cost&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;App Service plans with no apps.&lt;/strong&gt; An empty plan on anything above the Free
tier bills for the compute it reserved. This happens when someone deletes a web
app and leaves the plan, which the portal does not warn about.&lt;/p&gt;
&lt;h2&gt;Sample output&lt;/h2&gt;
&lt;p&gt;Eight findings from a small estate, ranked by monthly cost, which is the order
that matters when you have an afternoon:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Type                        Name                  USD/month
Managed Disk (unattached)   disk-sqlbackup-temp       88.59
Managed Disk (unattached)   disk-web01-old            23.85
Managed Disk (unattached)   disk-scratch-2021          9.86
Public IP (unassociated)    pip-legacy-vpn             3.65
Public IP (unassociated)    pip-buildagent-old         3.65
Network Interface (no VM)   nic-web01-old              0.00
Load Balancer (no backend)  lb-internal-basic          0.00
Snapshot (&amp;gt;365 days)        snap-migration-final       7.66
--------------------------------------------------------------
8 findings                                           137.26
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Two things about that output are deliberate. The zero-cost rows are still listed,
because they are the trail of breadcrumbs that leads to the expensive ones. And
the total sits at the bottom with a caveat rather than being presented as a
saving, for reasons covered in
&lt;a href=&quot;/notes/azure-cost-report-for-finance&quot;&gt;the note on reporting findings to finance&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Finding them&lt;/h2&gt;
&lt;p&gt;The queries are not difficult. Resource Graph will do most of it across every
subscription you can see, which beats iterating with the management cmdlets:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;kusto&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-kusto&quot;&gt;resources
| where type =~ &#x27;microsoft.compute/disks&#x27;
| where properties.diskState == &#x27;Unattached&#x27;
| project subscriptionId, resourceGroup, name,
          sku = sku.name,
          sizeGB = properties.diskSizeGB,
          created = properties.timeCreated
| order by sizeGB desc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And for addresses, where the absence of a configuration is the signal:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;kusto&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-kusto&quot;&gt;resources
| where type =~ &#x27;microsoft.network/publicipaddresses&#x27;
| where isnull(properties.ipConfiguration)
| project subscriptionId, resourceGroup, name, sku = sku.name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The harder part is pricing them, because that means mapping a SKU to a regional
rate rather than counting objects. A count tells you there are fourteen
unattached disks. A cost tells you which three are worth the conversation.&lt;/p&gt;
&lt;h2&gt;Read-only, and loud about failure&lt;/h2&gt;
&lt;p&gt;Two rules matter more than the queries.&lt;/p&gt;
&lt;p&gt;The first is that a cleanup tool should not clean up. It should tell you what it
found and let you decide. Deletion is a separate, deliberate act, ideally after
a snapshot, and the value of the tool is the inventory rather than the removal.
The &lt;a href=&quot;/free&quot;&gt;free Orphaned Resource Finder&lt;/a&gt; works this way, as does everything in
the &lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The second is that it must fail loudly. A script that loses its token and prints
&quot;no orphaned resources found&quot; has produced a clean report from an empty search,
and that looks exactly like good news. It should exit non-zero so whatever
scheduled it goes red rather than green. &quot;Found nothing&quot; and &quot;could not look&quot;
are different answers and only one of them is reassuring.&lt;/p&gt;
&lt;h2&gt;Before you delete anything&lt;/h2&gt;
&lt;p&gt;Three checks, in this order, learned by getting the order wrong.&lt;/p&gt;
&lt;p&gt;Snapshot first if the disk might hold something. A snapshot of a 128 GB disk
costs a fraction of the disk and buys you a month of being able to change your
mind.&lt;/p&gt;
&lt;p&gt;Check the creation date and any tags. A disk created last Tuesday is a different
proposition from one created in 2021, and an &lt;code&gt;owner&lt;/code&gt; tag turns a guess into an
email.&lt;/p&gt;
&lt;p&gt;Look for the pattern rather than the object. Three orphans in the same resource
group usually means one incomplete deletion, and finding the fourth is easier
than finding the first.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Do unassociated public IP addresses really cost money?&lt;/h3&gt;
&lt;p&gt;Standard SKU addresses do, whether or not anything is associated with them.
Basic SKU addresses behaved differently, which is why this surprises people who
learned Azure a few years ago.&lt;/p&gt;
&lt;h3&gt;Does an empty load balancer cost anything?&lt;/h3&gt;
&lt;p&gt;A Basic Load Balancer does not. A Standard one does, and it bills on its rules
regardless of whether the backend pool has any members. An internal Standard
load balancer pointing at nothing is a common leftover from a rebuild.&lt;/p&gt;
&lt;h3&gt;Why list resources that cost nothing?&lt;/h3&gt;
&lt;p&gt;Because they are evidence. A network interface with no VM costs nothing and
tells you a deletion stopped halfway, which means the disk and the address from
that same VM are probably still there too.&lt;/p&gt;
&lt;h3&gt;Is it safe to delete an unattached disk?&lt;/h3&gt;
&lt;p&gt;It is safe in the sense that nothing is using it. Whether it is wise depends on
what is on it, which is why snapshotting first is worth the small cost. The
disk state itself will not tell you whether the data matters.&lt;/p&gt;
&lt;h3&gt;How often should I run this?&lt;/h3&gt;
&lt;p&gt;Monthly is enough for a small estate, and after any decommissioning work. The
useful trigger is not the calendar, it is the week after somebody deletes a
handful of VMs.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 policies list: shorter than the standard, longer than a tweet</title>
    <link href="https://acloud.solutions/notes/iso-27001-policies-people-read/"/>
    <id>https://acloud.solutions/notes/iso-27001-policies-people-read/</id>
    <updated>2026-01-06T09:00:00Z</updated>
    <published>2026-01-06T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>An ISO 27001 policies list for a small company, why 40-page policies fail at Stage 2 interviews, and the approval and review evidence that matters.</summary>
    <content type="html">&lt;p&gt;The Acceptable Use Policy is forty-one pages. It was adapted from a template
that was adapted from a template, it covers the use of fax machines, and every
member of staff has clicked to acknowledge it. At Stage 2 the auditor will ask
one of them what it says.&lt;/p&gt;
&lt;p&gt;That interview is the reason an iso 27001 policies list should be shorter than
instinct suggests. Not because the standard asks for brevity, but because a
policy nobody has read is a control that does not operate, and the auditor finds
that out by asking rather than by reading.&lt;/p&gt;
&lt;h2&gt;The iso 27001 policies list you actually need&lt;/h2&gt;
&lt;p&gt;Grouped by what they do, which is more useful than the order they appear in the
standard.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Governance.&lt;/strong&gt; Information Security Policy, the ISMS scope statement, and a
roles and responsibilities document. The Information Security Policy is the only
one the standard names explicitly as a requirement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Risk.&lt;/strong&gt; Risk assessment methodology, the risk register, the Statement of
Applicability, the risk treatment plan. These are the four
&lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;risk documents&lt;/a&gt; and they are documents rather
than policies, which matters because they change more often.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;People.&lt;/strong&gt; Acceptable Use Policy, a screening procedure, a disciplinary
reference which can point at existing HR material rather than duplicating it,
and a remote or home working policy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Access.&lt;/strong&gt; Access Control Policy and a password or authentication standard.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Operations.&lt;/strong&gt; Backup Policy, change management procedure, vulnerability
management procedure, logging and monitoring procedure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Incident and continuity.&lt;/strong&gt; Incident Response Plan and a business continuity
plan scaled to the size of the company.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Third party.&lt;/strong&gt; Supplier Security Policy and a supplier risk assessment
procedure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Physical.&lt;/strong&gt; Physical Security Policy, which can be brief for a remote-first
company and should still exist to explain why.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ongoing governance.&lt;/strong&gt; Internal audit procedure and management review
procedure.&lt;/p&gt;
&lt;p&gt;That is around twenty documents. Fewer than most templates sell you and more
than most people expect, because the procedures are where the work is and
templates tend to supply policies without them.&lt;/p&gt;
&lt;h2&gt;Why long policies fail&lt;/h2&gt;
&lt;p&gt;Three reasons, and the third is the one that actually costs you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nobody reads them&lt;/strong&gt;, so the awareness control does not operate. Clause 7.3
requires personnel to be aware of the policy and its implications. Awareness is
tested by asking somebody, not by checking an acknowledgement log.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;They contain claims you cannot evidence.&lt;/strong&gt; A forty-page policy adapted from a
template will state that you do things you do not do. Every such sentence is a
finding waiting for somebody to sample it, and you wrote it yourself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;They are never reviewed properly.&lt;/strong&gt; Reviewing a one-page policy annually takes
ten minutes. Reviewing forty pages takes an afternoon nobody has, so the review
becomes a date change in the version history, which an auditor can see.&lt;/p&gt;
&lt;h2&gt;One page plus a linked procedure&lt;/h2&gt;
&lt;p&gt;The structure that survives.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;policy&lt;/strong&gt; states intent, scope, who it applies to, the principles, and who
owns it. It is deliberately free of specifics that change, so it can go a year
without amendment. One page, occasionally two.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;procedure&lt;/strong&gt; states how, and can be as long as it needs to be. It carries
the specifics: the tool names, the thresholds, the step-by-step. It changes
whenever the implementation changes, without triggering a policy re-approval and
re-acknowledgement cycle.&lt;/p&gt;
&lt;p&gt;So the Access Control Policy says access is granted on the principle of least
privilege, reviewed quarterly, approved by the system owner, and removed on
leaving. The joiner, mover and leaver procedure says which portal, which
sequence, and which script, and it is
&lt;a href=&quot;/notes/joiner-mover-leaver-automation-graph&quot;&gt;the automation note&lt;/a&gt; made
official.&lt;/p&gt;
&lt;p&gt;That split means staff read one page, the auditor reads both, and you amend the
procedure without asking forty people to re-acknowledge anything.&lt;/p&gt;
&lt;h2&gt;The evidence that makes a policy real&lt;/h2&gt;
&lt;p&gt;A policy on its own is a Word document. Three things turn it into a control that
operated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Approval by the right person, dated.&lt;/strong&gt; Not &quot;approved by management&quot;. A named
individual with the authority, on a date, recorded somewhere other than inside
the document itself. Minutes of a management meeting work well because they
double as clause 5 evidence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Acknowledgement by staff, dated.&lt;/strong&gt; Whatever mechanism you use, the output has
to be a list of names and dates you can produce on request, including for
joiners since the last review.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Review on a stated cycle.&lt;/strong&gt; Annually is the usual answer. The evidence is a
record that a review happened and what came of it, including &quot;no changes
required&quot;, which is a legitimate outcome that many people fail to record and
therefore fail to evidence.&lt;/p&gt;
&lt;p&gt;One small thing worth getting right: keep the approval status in a register
rather than only on the document&#x27;s face. A file whose cover page says DRAFT
while it is the version everyone follows creates an argument at audit that takes
longer to resolve than it should.&lt;/p&gt;
&lt;h2&gt;The awareness question&lt;/h2&gt;
&lt;p&gt;At Stage 2 the auditor may ask a member of staff what the acceptable use policy
requires, or what they would do if they lost a laptop, or who to tell about a
suspected phishing email.&lt;/p&gt;
&lt;p&gt;They are not testing recall of the document. They are testing whether the
control operates, and the answer they want is roughly right and confident. &quot;I
would tell [name] straight away and there is a form&quot; passes. &quot;I think there is a
policy somewhere&quot; does not, and no amount of policy quality fixes it.&lt;/p&gt;
&lt;p&gt;That is an argument for short policies and for a brief induction conversation
rather than for a longer document. Ten minutes explaining three things people
must do beats forty pages nobody opens, and the ten minutes is also easier to
evidence.&lt;/p&gt;
&lt;h2&gt;Getting the first draft&lt;/h2&gt;
&lt;p&gt;Templates are a reasonable starting point and a poor finishing point. The
failure mode is adopting one wholesale, because you inherit claims about
practices you do not have and language that does not match how your company
works.&lt;/p&gt;
&lt;p&gt;Two rules that make templates safe. Delete anything you cannot evidence today
or commit to a date for. And rewrite every sentence that describes a practice,
in your own words, because a policy written in somebody else&#x27;s voice reads as
borrowed and prompts sampling.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; includes two complete policies, the Information Security
Policy and the Acceptable Use Policy, written for a company of this size, along
with the document control conventions that make the set auditable. The
&lt;a href=&quot;https://www.ncsc.gov.uk/collection/board-toolkit&quot;&gt;NCSC&#x27;s guidance on policy and process&lt;/a&gt;
is a useful sanity check on whether yours says anything a board would recognise.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Microsoft Sentinel cost: why the bill is bigger than the thing it protects</title>
    <link href="https://acloud.solutions/notes/sentinel-cost-control/"/>
    <id>https://acloud.solutions/notes/sentinel-cost-control/</id>
    <updated>2025-12-30T09:00:00Z</updated>
    <published>2025-12-30T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>Microsoft Sentinel cost is ingestion, not rules. Which tables earn their place on a small tenant, basic versus analytics tiers, and commitment tiers.</summary>
    <content type="html">&lt;p&gt;Somebody enabled every data connector on the list. It seemed like the
responsible thing to do. Six weeks later the Log Analytics bill for a
forty-person company is larger than the Microsoft 365 licensing, and the
conversation about security monitoring has become a conversation about whether to
keep security monitoring.&lt;/p&gt;
&lt;p&gt;Microsoft sentinel cost is almost entirely ingestion. The analytics rules are
free. The workbooks are free. The thing you pay for is every gigabyte that
arrives, and the decision about what arrives is made once, casually, by whoever
clicked through the connector gallery.&lt;/p&gt;
&lt;h2&gt;What drives microsoft sentinel cost&lt;/h2&gt;
&lt;p&gt;Two meters, and people usually only think about one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ingestion&lt;/strong&gt;, charged per gigabyte as data lands. This is the large number.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Retention&lt;/strong&gt;, charged per gigabyte per month beyond the included period. This
is the number that creeps, because it compounds: a table ingesting steadily for
two years at extended retention is paying for the same data repeatedly.&lt;/p&gt;
&lt;p&gt;Rules, incidents, hunting queries and notebooks do not bill per use. So the
lever is not &quot;run fewer detections&quot;, it is &quot;ingest less, and keep it for less
time&quot;. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/sentinel/billing&quot;&gt;Sentinel costs and billing documentation&lt;/a&gt;
sets out the meters and the included retention, which is worth reading before
choosing a plan rather than after.&lt;/p&gt;
&lt;h2&gt;Which tables earn their place on a small tenant&lt;/h2&gt;
&lt;p&gt;For a company of a few dozen people with no on-premises server estate, the
useful set is small.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;SigninLogs&lt;/code&gt;.&lt;/strong&gt; Worth it, always. This is how you answer &quot;who logged in, from
where, and did MFA happen&quot;. Almost every investigation on a small estate starts
here. Volume is proportional to headcount, so it stays affordable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;AuditLogs&lt;/code&gt;.&lt;/strong&gt; Worth it. Directory changes, Conditional Access modifications,
role assignments, app registrations. This is the table behind most of the
configuration drift and privilege escalation detections in
&lt;a href=&quot;/notes/sentinel-analytics-rules-validation&quot;&gt;the validation note&lt;/a&gt;, and it is low
volume because it records changes rather than activity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;AzureActivity&lt;/code&gt;.&lt;/strong&gt; Worth it. Control-plane operations on subscriptions. Who
deleted the resource group, who changed the NSG rule. Low volume, high value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;OfficeActivity&lt;/code&gt;.&lt;/strong&gt; Depends. Exchange and SharePoint activity is genuinely
useful for investigating data access, and it is also the table most likely to
surprise you on volume. Enable it if you have a reason, watch it for a fortnight,
and check the number before you settle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;SecurityEvent&lt;/code&gt; from Windows machines.&lt;/strong&gt; Usually not, at small scale, unless
you filter hard. Unfiltered Windows security event collection from even a handful
of servers can exceed everything else combined. If you need it, use a data
collection rule to take specific event IDs rather than a whole level.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Network and firewall logs.&lt;/strong&gt; Rarely worth it here. High volume, and the
questions they answer are usually not the questions a one-person team is asking.&lt;/p&gt;
&lt;p&gt;The general shape: tables that record &lt;strong&gt;changes&lt;/strong&gt; are cheap and valuable. Tables
that record &lt;strong&gt;traffic&lt;/strong&gt; are expensive and only valuable if somebody is going to
look.&lt;/p&gt;
&lt;h2&gt;Basic logs, and what you give up&lt;/h2&gt;
&lt;p&gt;Some tables can be set to a cheaper Basic tier. The saving is real and so are
the restrictions, and the restrictions are the point.&lt;/p&gt;
&lt;p&gt;Basic logs have short retention, a reduced query surface, and cannot be used in
scheduled analytics rules. That last one matters most: if a table is on Basic,
it is available for investigation after the fact but cannot drive a detection.&lt;/p&gt;
&lt;p&gt;So the decision is not about the data&#x27;s value, it is about its role. A table you
will search when investigating an incident can be Basic. A table a rule depends
on cannot. Putting &lt;code&gt;AuditLogs&lt;/code&gt; on Basic to save money quietly disables every
detection built on it, which is the same silent-failure problem as an unvalidated
rule, arrived at from a different direction.&lt;/p&gt;
&lt;h2&gt;Commitment tiers&lt;/h2&gt;
&lt;p&gt;Once daily ingestion is predictable, a commitment tier prices a fixed daily
volume below the pay-as-you-go rate. The mechanics are simple and the trap is
not.&lt;/p&gt;
&lt;p&gt;You pay for the committed volume whether you use it or not. On a small estate
mid-tuning, ingestion is not stable: you are enabling and disabling connectors,
which is exactly when a commitment is wrong. Commit after you have run steadily
for a month or two, not before.&lt;/p&gt;
&lt;p&gt;The other trap is worse and worth naming. If you are near a cap or a commitment
and your daily total goes flat at exactly that number, that is not a measurement,
it is data loss. A perfectly level line at the limit means ingestion was
throttled or dropped, and the days that look tidiest on the graph are the days
you cannot investigate.&lt;/p&gt;
&lt;h2&gt;Checking before the invoice&lt;/h2&gt;
&lt;p&gt;The query that answers &quot;what is this costing&quot; takes a minute and nobody runs it
until the bill arrives:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;kusto&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-kusto&quot;&gt;Usage
| where TimeGenerated &amp;gt; ago(30d)
| where IsBillable == true
| summarize GB = round(sum(Quantity) / 1000, 2) by DataType
| order by GB desc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run it monthly. The output is usually one table you did not expect at the top,
and the fix is a data collection rule rather than turning the connector off
entirely.&lt;/p&gt;
&lt;p&gt;For the trend rather than the total, group by day as well and look for a step
change. A step means somebody enabled something, and knowing which day narrows
it to a change you can find in &lt;code&gt;AzureActivity&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Two things are worth setting up while you are in there. A daily cap, so a
misconfigured connector cannot produce a surprise invoice, set high enough that
normal days never touch it. And an alert on the cap being reached, because the
cap silently discarding data is exactly the failure you would not otherwise
notice.&lt;/p&gt;
&lt;h2&gt;The framing that survives a budget conversation&lt;/h2&gt;
&lt;p&gt;Security monitoring you cannot afford is not a security control, it is a
liability with a monthly cost, because it will be switched off in a hurry at the
worst possible moment and probably by someone who does not know which tables
matter.&lt;/p&gt;
&lt;p&gt;Choosing three tables deliberately, writing down why, and keeping the bill
boring is a defensible position. Ingesting everything and hoping nobody looks at
the invoice is not, and it ends with the whole workspace being questioned rather
than one connector.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/tools/azclean-detections/&quot;&gt;AzClean Detections&lt;/a&gt; is built around that
constraint: twelve rules that run on the three tables above, so the detection
surface does not require an ingestion budget you have to defend. The
&lt;a href=&quot;/notes/azure-cost/&quot;&gt;Azure cost notes&lt;/a&gt; cover the same argument for the rest of
the estate.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>The ISO 27001 Statement of Applicability: 93 controls and justified exclusions</title>
    <link href="https://acloud.solutions/notes/iso-27001-statement-of-applicability/"/>
    <id>https://acloud.solutions/notes/iso-27001-statement-of-applicability/</id>
    <updated>2025-12-23T09:00:00Z</updated>
    <published>2025-12-23T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>The ISO 27001 Statement of Applicability covers 93 controls. How to justify not applicable without a finding, and keep it matching reality.</summary>
    <content type="html">&lt;p&gt;The spreadsheet has 93 rows, one per Annex A control, and a column headed
&quot;Applicable?&quot;. Somebody has filled in 91 of them with Yes, because saying no felt
like admitting a gap, and the two No answers have justifications reading &quot;not
relevant to our business&quot;.&lt;/p&gt;
&lt;p&gt;Both halves of that are wrong, and the second is the one that produces a
finding. An iso 27001 statement of applicability is not a compliance
declaration. It is a record of decisions, and a decision without a reason is
indistinguishable from not having decided.&lt;/p&gt;
&lt;h2&gt;What the iso 27001 statement of applicability is for&lt;/h2&gt;
&lt;p&gt;Three jobs, and it is the only document that does all three.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It records which controls apply.&lt;/strong&gt; Which is a consequence of your risk
assessment, not an independent judgement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It justifies the exclusions.&lt;/strong&gt; This is the part the standard specifically
asks for and the part done worst.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It maps controls to implementation.&lt;/strong&gt; So an auditor can go from &quot;control 8.12
applies&quot; to &quot;here is how, and here is the evidence&quot; without asking you.&lt;/p&gt;
&lt;p&gt;The document that does all three is a table with six columns: control reference,
control name, applicable yes or no, justification, how it is implemented, and
where the evidence lives. Anything less and you will be answering questions
verbally at Stage 2 that the document should have answered.&lt;/p&gt;
&lt;h2&gt;Excluding a control without getting a finding&lt;/h2&gt;
&lt;p&gt;An exclusion needs a reason that refers to something factual about your
organisation. Compare these.&lt;/p&gt;
&lt;p&gt;Bad: &quot;Not relevant to our business.&quot; This states a conclusion with no premise.
An auditor cannot verify it and will ask, at which point you are improvising.&lt;/p&gt;
&lt;p&gt;Bad: &quot;We are too small for this.&quot; Size is not a justification. Plenty of
controls apply to a company of three.&lt;/p&gt;
&lt;p&gt;Good: &quot;No control applies because the ISMS scope excludes physical premises. All
personnel work remotely and no company location stores or processes in-scope
information. See scope statement section 2.&quot; That is checkable, it refers to
another document, and it is consistent with the rest of your ISMS.&lt;/p&gt;
&lt;p&gt;Good: &quot;No software is developed for sale or distribution outside the
organisation; the platform is operated as a service. Development controls are
addressed under 8.25 to 8.31 for the platform itself.&quot;&lt;/p&gt;
&lt;p&gt;The pattern: name the factual circumstance, refer to the document that
establishes it, and where a related control does cover the risk, say which.&lt;/p&gt;
&lt;p&gt;The exclusions that are usually genuine for a small remote-first SaaS company
involve physical and environmental controls, physical media handling, and
sometimes controls about development environments if you have a single one. The
ones people wrongly try to exclude are supplier controls, because they feel like
someone else&#x27;s problem, and they are not.&lt;/p&gt;
&lt;h2&gt;Where the numbers come from&lt;/h2&gt;
&lt;p&gt;Annex A in the 2022 revision has 93 controls across four themes: organisational,
people, physical and technological. That structure changed from the 2013
version&#x27;s fourteen domains, and a template you find online may still be on the
old structure, which will confuse an auditor and cost you an explanation.&lt;/p&gt;
&lt;p&gt;Check the revision. The
&lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO 27001 standard&lt;/a&gt; is the authority, and
the control text is copyright, which is why this note describes what controls are
about rather than reproducing them. Your SoA should reference the control by
number and name and describe your implementation in your own words, not paste
the standard&#x27;s text.&lt;/p&gt;
&lt;h2&gt;Keeping it in sync&lt;/h2&gt;
&lt;p&gt;The SoA is a document people write once and never update, which is exactly how
it becomes a liability.&lt;/p&gt;
&lt;p&gt;Three things have to stay consistent, and drift between them is what an auditor
finds.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The risk register and the SoA.&lt;/strong&gt; Every applicable control should trace to a
risk that requires it, per
&lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;the risk assessment note&lt;/a&gt;. A control marked
applicable with no corresponding risk raises the question of why you selected
it. A risk with no control is either accepted or untreated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The SoA and reality.&lt;/strong&gt; If the SoA says access reviews happen quarterly and
they happen when somebody remembers, the SoA is now the document that proves you
knew what you should be doing. That is worse than a gap: it converts an
operational shortfall into a documented one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The SoA and the evidence location.&lt;/strong&gt; The sixth column should point somewhere
that exists. A reference to a folder that was reorganised is the kind of small
failure that consumes twenty minutes of an audit and undermines confidence in
the rest.&lt;/p&gt;
&lt;p&gt;Review it whenever the risk register changes materially, and formally at
management review. Record the review date on the document itself.&lt;/p&gt;
&lt;h2&gt;The version that survives an audit&lt;/h2&gt;
&lt;p&gt;What works, and it is duller than most templates:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;5.7  Threat intelligence                                    Applicable
     Justification: Risk R-04 (unpatched vulnerability exploited)
       and R-11 (targeted phishing) require awareness of current threats.
     Implementation: Vendor advisories and NCSC alerts monitored;
       vulnerability data from Defender reviewed weekly.
     Evidence: A-5-7_threat-review_YYYY-MM.md, weekly, in ISMS library.

7.1  Physical security perimeters                       Not applicable
     Justification: ISMS scope excludes physical premises (scope
       statement s.2). All personnel work remotely; no company location
       stores or processes in-scope information. Cloud data centre
       physical security is a provider responsibility, covered under
       5.19 to 5.22 supplier controls and evidenced by the provider&#x27;s
       own certification.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The second one is doing real work. It excludes the control, states the factual
basis, points at the document establishing it, and explains where the underlying
risk is addressed instead. An auditor reading that has no follow-up question,
which is the entire objective.&lt;/p&gt;
&lt;h2&gt;Partially applicable, and how to say it&lt;/h2&gt;
&lt;p&gt;Some controls apply to part of your scope and not the rest, and the binary
column forces a choice that misrepresents the position.&lt;/p&gt;
&lt;p&gt;The honest treatment is Applicable, with the boundary stated in the
implementation column. For a control about secure development, if you build the
platform but buy the corporate tooling, the control applies to what you build
and the bought-in part is covered by supplier assurance. Writing that down is
better than either a Yes that overclaims or a No that is wrong.&lt;/p&gt;
&lt;p&gt;The same applies to controls you are part way through implementing at the time
of Stage 1. Marking one Applicable while its evidence stream starts next month
is fine, provided the treatment plan carries a date and an owner. What produces
a finding is an SoA describing a control as implemented when Stage 2 samples it
and finds three months of nothing.&lt;/p&gt;
&lt;p&gt;So the practical rule: the SoA describes the intended state with dates, and the
treatment plan carries anything not yet operating. Auditors are used to seeing a
system mid-implementation at Stage 1. They are unforgiving about a document
that claims a state the evidence contradicts, because that is a question about
honesty rather than about maturity.&lt;/p&gt;
&lt;h2&gt;The mistake of marking everything applicable&lt;/h2&gt;
&lt;p&gt;Marking all 93 applicable feels safe and is the opposite.&lt;/p&gt;
&lt;p&gt;Every applicable control is a control the auditor may sample, and for which you
need an implementation and evidence. Ninety-three applicable controls means
ninety-three things to evidence, forever, including the ones about physical
media you do not have.&lt;/p&gt;
&lt;p&gt;A well-justified exclusion reduces permanent workload and demonstrates that you
understood the control rather than defaulting. Auditors read a thoughtful
exclusion as competence. They read 93 out of 93 as a template nobody engaged
with, and then they start sampling to find out which is true.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; works through the SoA control by control, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; is the alternative if you would
rather the first draft came from somebody who has defended one.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Conditional Access policies small business tenants need, and nothing more</title>
    <link href="https://acloud.solutions/notes/conditional-access-policies-small-business/"/>
    <id>https://acloud.solutions/notes/conditional-access-policies-small-business/</id>
    <updated>2025-12-16T09:00:00Z</updated>
    <published>2025-12-16T09:00:00Z</published>
    <category term="Microsoft 365, Entra and Intune"/>
    <summary>Seven Conditional Access policies that cover a small company, in report-only first, with the break-glass exclusion that keeps you out of a support case.</summary>
    <content type="html">&lt;p&gt;There is a policy in your tenant called &lt;code&gt;TEST DO NOT ENABLE&lt;/code&gt;. It is enabled. It
has been enabled since somebody switched it on to check whether it worked, at
which point it did work, and the name stopped being something anyone read.&lt;/p&gt;
&lt;p&gt;Conditional access policies small business tenants actually need come to about
seven. Not the forty in a reference architecture written for an enterprise with
a change board, and not the two that Security Defaults gives you. Seven, each
with a job you can state in a sentence.&lt;/p&gt;
&lt;h2&gt;The conditional access policies small business tenants need&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Require MFA for all users.&lt;/strong&gt; The one that matters most. Every user, every
cloud app, with your break-glass accounts excluded. If you only ever deploy one
policy, this is it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Block legacy authentication.&lt;/strong&gt; Legacy protocols cannot present an MFA
challenge, so without this the policy above has a hole in it. This is the policy
most likely to break something, because something in your estate is probably
still using basic auth on IMAP or SMTP, and finding out which is the entire
value of report-only mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Require MFA for administrators&lt;/strong&gt;, separately from the all-users policy, with
no exclusions beyond break-glass and with session controls that do not permit
&quot;remember this device&quot;. Administrative sessions should be short and
re-authenticated.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Require a compliant device for administrators.&lt;/strong&gt; Once Intune is enrolling your
machines, this is the policy that stops an administrator signing in from an
unmanaged personal laptop. Deploy it after device compliance is actually
working, not before.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Block sign-in risk, or require MFA on it.&lt;/strong&gt; Needs Entra ID P2 for risk-based
conditions. If you do not have P2, skip it rather than pretending: this is one
of the places where the licence genuinely gates the control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Restrict guest access.&lt;/strong&gt; Guests should reach the specific things they were
invited for and not the whole tenant. Pair it with the review cadence in
&lt;a href=&quot;/notes/microsoft-365-guest-access-cleanup&quot;&gt;the guest cleanup note&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Require MFA for device enrolment.&lt;/strong&gt; Closes the gap where somebody enrols a
device without a strong credential and thereby satisfies the compliant-device
policy above.&lt;/p&gt;
&lt;p&gt;That is the set. Everything beyond it is refinement, and refinement without the
above is decoration.&lt;/p&gt;
&lt;h2&gt;Report-only first, without exception&lt;/h2&gt;
&lt;p&gt;Report-only mode evaluates a policy against real sign-ins and records what would
have happened, changing nothing. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-report-only&quot;&gt;report-only mode documentation&lt;/a&gt;
covers reading the results in sign-in logs.&lt;/p&gt;
&lt;p&gt;The temptation to skip it is strongest on the policy that most needs it. Block
legacy authentication looks obviously correct and it is the one that will break a
scanner in the office that emails scans through SMTP, or a monitoring
integration nobody documented, or a mail client on a director&#x27;s phone.&lt;/p&gt;
&lt;p&gt;A week in report-only tells you which. That week costs you a week. Not doing it
costs you an outage on something business-critical that you then have to
diagnose under pressure, having just changed identity policy, which is the worst
possible time to be reading sign-in logs for the first time.&lt;/p&gt;
&lt;p&gt;The discipline that makes this work is a naming convention with the state in the
name. &lt;code&gt;CA01 - Require MFA - All users - REPORT ONLY&lt;/code&gt; becomes
&lt;code&gt;CA01 - Require MFA - All users&lt;/code&gt; when you promote it. Then a policy whose name
disagrees with its state is visibly wrong, and &lt;code&gt;TEST DO NOT ENABLE&lt;/code&gt; cannot
happen.&lt;/p&gt;
&lt;h2&gt;The exclusion that keeps you employed&lt;/h2&gt;
&lt;p&gt;Every policy above excludes the break-glass accounts. This is not optional and
it is not a compromise.&lt;/p&gt;
&lt;p&gt;A one-person tenant has no colleague with Global Administrator to undo a policy
that locked everybody out. The recovery path is a Microsoft support case, which
takes hours you do not have while nobody can log in. Two cloud-only accounts,
excluded from every Conditional Access policy, monitored for any use at all, are
the thing that turns that scenario from an incident into an inconvenience.
&lt;a href=&quot;/notes/break-glass-accounts&quot;&gt;The break-glass note&lt;/a&gt; covers how to set them up
and, more importantly, how to test them.&lt;/p&gt;
&lt;p&gt;Exclude a group rather than named accounts, so adding a third emergency account
later does not mean editing seven policies.&lt;/p&gt;
&lt;h2&gt;The exclusions that are load-bearing and look wrong&lt;/h2&gt;
&lt;p&gt;A warning, because this is a genuine trap and I have watched it bite.&lt;/p&gt;
&lt;p&gt;Some exclusions in a working tenant are required configuration rather than
oversights. A service principal excluded so an automation flow can run. An
application excluded because its own authentication does not support the control
you are enforcing. A specific sign-in scenario excluded because the platform
requires it.&lt;/p&gt;
&lt;p&gt;Before removing any exclusion you did not create, find out what it is for. An
exclusion that looks like laziness is sometimes the only reason a remote access
product or a device sign-in flow works at all, and removing it produces an
outage whose cause is not obvious, because nothing appears to have broken except
one specific journey.&lt;/p&gt;
&lt;p&gt;Write the reason into the policy description when you find out. That is the
cheapest possible fix for the next person, who will be you.&lt;/p&gt;
&lt;h2&gt;Where this sits&lt;/h2&gt;
&lt;p&gt;Getting this set right, in report-only, with the evidence to show it, is most of
what a customer security questionnaire is asking about identity, and it is
&lt;a href=&quot;/book/&quot;&gt;Annex A 5.15 and 8.2&lt;/a&gt; territory if you are heading for certification.&lt;/p&gt;
&lt;p&gt;If you would rather it were done with you than by you, that is
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt;. The rest of
&lt;a href=&quot;/notes/microsoft-365/&quot;&gt;the Microsoft 365 notes&lt;/a&gt; cover the surrounding pieces.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Is Security Defaults enough for a small company?&lt;/h3&gt;
&lt;p&gt;It is much better than nothing and it is free. It enforces MFA and blocks legacy
authentication with no configuration. What you give up is granularity: you
cannot exclude a break-glass account, you cannot run anything in report-only,
and you cannot treat administrators differently. Start there if you have nothing,
and move to Conditional Access when you need an exception, because the first
exception is what forces the move.&lt;/p&gt;
&lt;h3&gt;Do I need Entra ID P1 or P2?&lt;/h3&gt;
&lt;p&gt;Conditional Access needs P1, which comes with Business Premium and E3. The
risk-based policies need P2. If you are on P1, deploy the six that do not need
risk conditions and leave the seventh.&lt;/p&gt;
&lt;h3&gt;How long should I leave a policy in report-only?&lt;/h3&gt;
&lt;p&gt;Long enough to cover a full business cycle for whatever it touches. A week for
most things, a month if it affects something that only runs at month end.
Payroll and finance systems are the usual reason to wait longer.&lt;/p&gt;
&lt;h3&gt;What if report-only shows failures I cannot explain?&lt;/h3&gt;
&lt;p&gt;Do not promote the policy. An unexplained would-have-blocked result is the
policy telling you something in your estate does something you do not know
about, and finding out is the whole point. Promoting anyway converts a question
into an outage.&lt;/p&gt;
&lt;h3&gt;Should the break-glass accounts have MFA?&lt;/h3&gt;
&lt;p&gt;They should have a strong credential, stored securely, and be excluded from
policy enforcement so a broken policy cannot lock them out. The protection comes
from the credential and from alerting on any use, not from the policy engine
that might be the thing that has failed.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>An ISO 27001 risk assessment an auditor will actually accept</title>
    <link href="https://acloud.solutions/notes/iso-27001-risk-assessment/"/>
    <id>https://acloud.solutions/notes/iso-27001-risk-assessment/</id>
    <updated>2025-12-09T09:00:00Z</updated>
    <published>2025-12-09T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>An ISO 27001 risk assessment needs a method before a score. Clause 6.1.2, real risk owners, and why 30 maintained rows beat 200 abandoned ones.</summary>
    <content type="html">&lt;p&gt;The spreadsheet has 214 rows. Each has a likelihood between 1 and 5, an impact
between 1 and 5, and a product of the two in a column shaded red, amber or
green. It took a fortnight. It has not been opened since, and nobody can explain
why row 87 scores 12 rather than 9.&lt;/p&gt;
&lt;p&gt;An iso 27001 risk assessment is not judged on completeness. It is judged on
whether the method is coherent, whether the owners are real, and whether it
explains the controls you chose. A 30-row register that satisfies those three
beats 214 rows that satisfy none.&lt;/p&gt;
&lt;h2&gt;What clause 6.1.2 actually requires&lt;/h2&gt;
&lt;p&gt;The clause is more prescriptive than most, and reading it properly saves a
rewrite.&lt;/p&gt;
&lt;p&gt;The clause text itself is worth buying the
&lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;standard&lt;/a&gt; for rather than working from a
summary, because the wording is precise and the precision is the point.&lt;/p&gt;
&lt;p&gt;It requires a defined process that produces consistent, valid and comparable
results. &lt;strong&gt;Defined&lt;/strong&gt; and &lt;strong&gt;consistent&lt;/strong&gt; are the operative words: two people
assessing the same risk should land in roughly the same place, which means the
criteria have to be written down before anything is scored.&lt;/p&gt;
&lt;p&gt;It requires you to identify risks to confidentiality, integrity and
availability, identify risk owners, analyse and evaluate the risks, and compare
against criteria you established in advance.&lt;/p&gt;
&lt;p&gt;And it requires retained documented information about the process. Not just the
register, the method.&lt;/p&gt;
&lt;p&gt;That last point is where most first attempts fail. They produce a register with
no accompanying statement of how likelihood and impact were defined, so the
numbers are unfalsifiable. An auditor asking &quot;why is this a 4&quot; has no way to
check the answer, and neither do you in twelve months.&lt;/p&gt;
&lt;h2&gt;An iso 27001 risk assessment needs a method before a score&lt;/h2&gt;
&lt;p&gt;Write the method first, in one page, before the register exists. It needs four
things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Definitions of likelihood.&lt;/strong&gt; Not &quot;medium&quot;. Something anchored: 1 is once in
ten years or less, 3 is annually, 5 is monthly or more. Frequency is easier to
agree on than adjectives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Definitions of impact&lt;/strong&gt;, in terms your business recognises. Financial, and
also operational and reputational. For a SaaS company, &quot;platform unavailable to
all customers for more than four hours&quot; is a level everyone understands.
Contractual thresholds are useful here because they are external and specific.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How the two combine&lt;/strong&gt;, and where the acceptance line sits. A 5 by 5 matrix is
fine. What matters is stating in advance which combinations require treatment,
so the treatment decision is a rule rather than a preference.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who owns the acceptance decision&lt;/strong&gt; for a risk above the line. This should be a
named role in management, not you, because accepting business risk is a
leadership function and clause 5 wants leadership involved.&lt;/p&gt;
&lt;p&gt;Write that page, get it approved, then score. The scores become defensible
because the criteria predate them.&lt;/p&gt;
&lt;h2&gt;Owners who are real people&lt;/h2&gt;
&lt;p&gt;Every risk needs an owner, and the temptation in a small company is to put your
own name against all of them because you do all the work.&lt;/p&gt;
&lt;p&gt;That is wrong in a way an auditor will probe. The risk owner is not who
implements the control, it is who owns the consequence and can accept the risk.
For &quot;customer data disclosed through a misconfigured storage account&quot;, you
implement the fix; the person who owns the consequence is whoever answers to the
customer.&lt;/p&gt;
&lt;p&gt;Practically, in a company of forty, that means a handful of owners: a managing
director, a head of engineering, possibly a finance lead for anything with a
contractual penalty. Talk to them, tell them what they own, and record that
conversation. A risk owner who does not know they own a risk is a finding at
Stage 2, because the auditor will ask them.&lt;/p&gt;
&lt;h2&gt;Thirty rows that are maintained&lt;/h2&gt;
&lt;p&gt;The register that survives has a specific shape. Risks expressed as scenarios
rather than as asset lists.&lt;/p&gt;
&lt;p&gt;Not &quot;Laptops&quot;. A laptop is an asset, not a risk. The risk is &quot;a laptop with
cached production credentials is lost or stolen, leading to unauthorised access
to customer data&quot;. That phrasing does three things: it names the asset, the
threat and the consequence, so the control that addresses it is obvious, and so
is the reason you selected that control.&lt;/p&gt;
&lt;p&gt;Somewhere between 20 and 40 scenarios covers a small SaaS company properly. Any
fewer and you have missed categories. Many more and you are enumerating assets
rather than assessing risk, and you will not maintain it.&lt;/p&gt;
&lt;p&gt;The categories worth covering: identity and access, endpoints, cloud
configuration, application security, supplier and sub-processor failure, data
loss and backup, availability, insider risk including a departing employee, and
the one people omit, key person dependency, which in a one-person IT function is
a real and material risk that belongs in the register honestly.&lt;/p&gt;
&lt;h2&gt;Linking to Annex A through the SoA&lt;/h2&gt;
&lt;p&gt;This is the connection auditors check and beginners miss.&lt;/p&gt;
&lt;p&gt;The risk assessment identifies risks. The treatment plan says what you will do
about each. The Statement of Applicability records which Annex A controls apply
and why. Those three documents have to agree.&lt;/p&gt;
&lt;p&gt;So each risk in the register should reference the controls treating it, and each
applicable control in
&lt;a href=&quot;/notes/iso-27001-statement-of-applicability&quot;&gt;the Statement of Applicability&lt;/a&gt;
should be traceable to at least one risk. A control marked applicable that no
risk requires invites the question of why it is there. A risk with no control is
either accepted, which needs a recorded acceptance, or untreated, which is a
finding.&lt;/p&gt;
&lt;p&gt;That traceability is also how you justify exclusions cleanly. If no risk in your
register touches physical media, the controls about physical media are not
applicable, and the register is the evidence.&lt;/p&gt;
&lt;h2&gt;What gets asked at Stage 2&lt;/h2&gt;
&lt;p&gt;From experience of the questions rather than the theory:&lt;/p&gt;
&lt;p&gt;How did you arrive at these criteria. Who approved the method. Show me a risk
that changed after treatment and the evidence of the change. Who is the owner of
this specific risk, and can I speak to them. When was the register last
reviewed, and what changed. Show me a risk you accepted and the record of who
accepted it.&lt;/p&gt;
&lt;p&gt;Notice that none of those are about scoring. They are about whether the process
is real. A register with modest scores, clear owners and a visible review history
survives all six. An elaborate one produced in a fortnight and untouched since
survives none.&lt;/p&gt;
&lt;p&gt;Review it quarterly, and record that you did with the date and any changes, per
&lt;a href=&quot;/notes/audit-evidence-automation&quot;&gt;scheduled evidence collection&lt;/a&gt;. The review
history is what turns the register from a document into a system.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;How many risks should the register have?&lt;/h3&gt;
&lt;p&gt;Between 20 and 40 for a small SaaS company. The real test is whether every
applicable Annex A control traces to at least one risk, and whether you can
maintain it quarterly. If you dread opening it, it is too long.&lt;/p&gt;
&lt;h3&gt;Do I need a formal risk assessment tool?&lt;/h3&gt;
&lt;p&gt;No. A spreadsheet is acceptable and common at this scale, provided the method is
documented alongside it and there is a review history. Tooling helps with
evidence collection rather than with the thinking, which is
&lt;a href=&quot;/notes/compliance-automation-platforms-worth-it&quot;&gt;the compliance platform question&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Can I be the owner of every risk?&lt;/h3&gt;
&lt;p&gt;You should not be. The owner accepts the consequence, which is a leadership
function. Expect three or four owners in a company of forty, and make sure each
of them knows what they own, because the auditor may ask them directly.&lt;/p&gt;
&lt;h3&gt;What if a risk is above the acceptance line and we cannot fix it?&lt;/h3&gt;
&lt;p&gt;Then it is a recorded, accepted risk with a named accepter and a review date.
That is a legitimate outcome and the standard provides for it. What is not
legitimate is a risk quietly scored downward until it falls below the line,
which is visible in a version history and reads badly.&lt;/p&gt;
&lt;h3&gt;How does this relate to the treatment plan?&lt;/h3&gt;
&lt;p&gt;The assessment identifies and evaluates. The treatment plan says what you will
do, by when, and who owns it. They are separate documents because they change on
different schedules, and an auditor will ask for both. The plan is what turns
the assessment from an opinion into a commitment.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Azure managed disk pricing: you are paying for the tier, not the gigabytes</title>
    <link href="https://acloud.solutions/notes/azure-managed-disk-pricing-provisioned-tier/"/>
    <id>https://acloud.solutions/notes/azure-managed-disk-pricing-provisioned-tier/</id>
    <updated>2025-12-02T09:00:00Z</updated>
    <published>2025-12-02T09:00:00Z</published>
    <category term="Azure cost"/>
    <summary>Azure managed disk pricing bills by provisioned tier, not gigabytes. A 128 GB Premium SSD costs the same as a 100 GB one, and flat per-GB maths is wrong.</summary>
    <content type="html">&lt;p&gt;There is a disk in your subscription called &lt;code&gt;disk-web01-old&lt;/code&gt;. It was detached in
2021 by someone who meant to come back to it. It holds 43 GB of data on a 128 GB
Premium SSD, and for four years it has been billing about 23.85 USD a month for
the privilege of existing.&lt;/p&gt;
&lt;p&gt;The trap in azure managed disk pricing is that the meter does not care how much
data is on the disk, or even how big you asked the disk to be. It cares which
performance tier your requested size lands in.&lt;/p&gt;
&lt;p&gt;So open a spreadsheet and estimate what deleting it saves. If you multiply 43 GB
by a per-GB rate you will get roughly a quarter of the real number, and you will
hand that quarter to someone who controls budgets.&lt;/p&gt;
&lt;h2&gt;How azure managed disk pricing actually works&lt;/h2&gt;
&lt;p&gt;Premium SSD v1 and Standard SSD are billed in tiers, not by the gigabyte. Each
tier has a fixed monthly price and a fixed size. Ask for anything inside a
tier&#x27;s range and you pay that tier&#x27;s price.&lt;/p&gt;
&lt;p&gt;The Premium ladder starts like this:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Provisioned size&lt;/th&gt;
&lt;th&gt;What you get billed for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;P6&lt;/td&gt;
&lt;td&gt;64 GB&lt;/td&gt;
&lt;td&gt;64 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P10&lt;/td&gt;
&lt;td&gt;128 GB&lt;/td&gt;
&lt;td&gt;128 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P15&lt;/td&gt;
&lt;td&gt;256 GB&lt;/td&gt;
&lt;td&gt;256 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P20&lt;/td&gt;
&lt;td&gt;512 GB&lt;/td&gt;
&lt;td&gt;512 GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Standard SSD uses an E ladder with the same sizes and lower prices: E6, E10,
E15, E20. Standard HDD uses S.&lt;/p&gt;
&lt;p&gt;So a 100 GB Premium SSD is a P10. It is billed as 128 GB. A 128 GB Premium SSD
is also a P10, billed identically. Provisioning 100 GB rather than 128 GB saves
you nothing at all, and costs you 28 GB of headroom you have already paid for.
If you have ever carefully specified 100 GB to be frugal, you did the frugal
thing and were charged for the unfrugal one.&lt;/p&gt;
&lt;p&gt;It gets better at the bottom of the ladder. A 4 GB Premium disk is a P1, and
the smallest tier still has a floor price. There is no such thing as a
nearly-free Premium disk, which is why the &quot;just a small one for testing&quot; disks
are worth finding.&lt;/p&gt;
&lt;p&gt;The primary source for the ladders is Microsoft&#x27;s own page on
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/virtual-machines/disks-types&quot;&gt;managed disk types and their tiers&lt;/a&gt;,
which lists the sizes and IOPS per tier. Prices vary by region, so read them from
the Retail Prices API rather than a blog post, including this one.&lt;/p&gt;
&lt;h2&gt;Reading the tier rather than guessing it&lt;/h2&gt;
&lt;p&gt;The disk object tells you its tier directly, so there is no need to infer it from
the size. &lt;code&gt;DiskSizeGB&lt;/code&gt; is what you asked for. &lt;code&gt;Sku.Name&lt;/code&gt; is what you are paying
for.&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-AzDisk | Select-Object `
    Name,
    DiskSizeGB,
    @{ n = &#x27;Sku&#x27;;   e = { $_.Sku.Name } },
    @{ n = &#x27;State&#x27;; e = { $_.DiskState } },
    @{ n = &#x27;Owner&#x27;; e = { if ($_.ManagedBy) { $_.ManagedBy.Split(&#x27;/&#x27;)[-1] } else { &#x27;unattached&#x27; } } } |
    Sort-Object DiskSizeGB -Descending
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;DiskState&lt;/code&gt; of &lt;code&gt;Unattached&lt;/code&gt; is the interesting one. &lt;code&gt;Reserved&lt;/code&gt; means the disk is
still associated with a VM that is deallocated, which is a different problem and
still billing.&lt;/p&gt;
&lt;p&gt;Then map the SKU to a tier price from the Retail Prices API rather than
hardcoding anything:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;powershell&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;$region = &#x27;uksouth&#x27;
$filter = &amp;quot;serviceName eq &#x27;Storage&#x27; and armRegionName eq &#x27;$region&#x27; &amp;quot; +
          &amp;quot;and priceType eq &#x27;Consumption&#x27; and contains(meterName, &#x27;P10&#x27;)&amp;quot;
$uri = &amp;quot;https://prices.azure.com/api/retail/prices?currencyCode=&#x27;USD&#x27;&amp;amp;`$filter=$filter&amp;quot;
(Invoke-RestMethod -Uri $uri).Items |
    Select-Object meterName, unitOfMeasure, retailPrice
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That endpoint needs no authentication, which makes it pleasant to work with and
easy to accidentally hammer. It is paged, and the filter syntax is OData, so the
&lt;code&gt;$filter&lt;/code&gt; needs escaping in PowerShell. The
&lt;a href=&quot;https://learn.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices&quot;&gt;Retail Prices API reference&lt;/a&gt;
documents the query parameters.&lt;/p&gt;
&lt;h2&gt;The 3.7x problem, and why finance remembers it&lt;/h2&gt;
&lt;p&gt;Take that 128 GB Premium SSD in a mid-priced region. Billed as P10, it comes to
roughly 23.85 USD a month. Estimate it instead at a flat per-GB Premium rate
against the 43 GB actually in use and you land near 6.40 USD.&lt;/p&gt;
&lt;p&gt;That is an understatement of about 3.7x. On one disk it is a rounding error. On
the eight findings in the sample output on the front page of this site, which
total 137.26 USD a month, a flat-rate estimate would have reported something
closer to 40 USD and the whole exercise would have looked like it was not worth
anyone&#x27;s afternoon. That figure and the findings behind it are on the
&lt;a href=&quot;/&quot;&gt;front page of this site&lt;/a&gt; if you want to see the shape of it.&lt;/p&gt;
&lt;p&gt;The first version of my own script priced every disk at zero, which finance
found unpersuasive, so I am not in a position to be smug about this. But the
failure mode matters more than the arithmetic. If you go into a cost conversation
with numbers that are 3.7x light, one of two things happens. Either nobody acts,
because the saving looks trivial. Or somebody acts, discovers the real saving was
four times larger, and quietly stops trusting your numbers for the next thing you
bring them. The second outcome is worse and lasts longer.&lt;/p&gt;
&lt;h2&gt;What the tier model does not include&lt;/h2&gt;
&lt;p&gt;A tier price is a starting point, not an invoice. Several things move it, and
none of them are visible in a disk object:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reservations.&lt;/strong&gt; A one or three year disk reservation changes the effective
  rate. The Retail Prices API returns pay-as-you-go consumption prices unless you
  ask otherwise.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Savings plans.&lt;/strong&gt; Compute savings plans do not cover storage, but people
  assume they cover everything, so it is worth saying.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Hybrid Benefit.&lt;/strong&gt; Affects licensing, not disk meters, and is another
  thing that gets blamed for a discrepancy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise agreement discounts.&lt;/strong&gt; Your negotiated rate is not the retail one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snapshots and bursting.&lt;/strong&gt; Snapshots bill separately, and on-demand bursting
  adds a charge that a size lookup will never show you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the honest framing for any number you produce is that it is for prioritising
work, not for billing. A figure good enough to decide which twelve things to
delete first does not need to survive an audit by the finance team, and claiming
otherwise is how you end up defending a spreadsheet instead of deleting a disk.&lt;/p&gt;
&lt;h2&gt;Where to start&lt;/h2&gt;
&lt;p&gt;Unattached disks are the easiest money in Azure because there is no
counterargument. Nothing is using them. Nobody has to be consulted about
downtime. The only real question is whether the data matters, which is what
snapshots are for.&lt;/p&gt;
&lt;p&gt;Look for the three patterns that account for most of them. Disks left behind when
a VM was deleted without the &quot;delete with VM&quot; option set. Disks from a migration
that finished eighteen months ago. And disks with &lt;code&gt;temp&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;old&lt;/code&gt; or &lt;code&gt;copy&lt;/code&gt;
in the name, provisioned by someone who fully intended to tidy up.&lt;/p&gt;
&lt;p&gt;Once disks are done,
&lt;a href=&quot;/notes/orphaned-azure-resources&quot;&gt;the inventory of everything else nobody deletes&lt;/a&gt;
covers the categories that bill quietly: unassociated public IP addresses, empty
load balancers, dead network interfaces and snapshots. The rest of the
&lt;a href=&quot;/notes/azure-cost/&quot;&gt;azure cost notes&lt;/a&gt; work through idle machines and tagging,
and the &lt;a href=&quot;/tools/azclean-toolkit/&quot;&gt;AzClean Toolkit&lt;/a&gt; runs all of it as ten
read-only scripts if you would rather not write the queries yourself.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Does a 100 GB Premium SSD really cost the same as a 128 GB one?&lt;/h3&gt;
&lt;p&gt;Yes. Both provision into the P10 tier and both bill at the P10 rate. If you need
100 GB, ask for 128 GB and use the headroom, because you are paying for it
either way.&lt;/p&gt;
&lt;h3&gt;Do unattached disks still cost money?&lt;/h3&gt;
&lt;p&gt;Yes, at the full tier rate. A managed disk bills from creation until deletion
regardless of whether anything is attached to it. This is the single most common
source of avoidable Azure spend I find in small estates.&lt;/p&gt;
&lt;h3&gt;Is a deallocated VM&#x27;s disk still billing?&lt;/h3&gt;
&lt;p&gt;Yes. Deallocating a VM stops the compute meter, not the storage one. The disk
shows a &lt;code&gt;DiskState&lt;/code&gt; of &lt;code&gt;Reserved&lt;/code&gt; and continues to bill at its tier price, which
is why &quot;we turned that server off&quot; and &quot;that server costs nothing&quot; are different
statements.&lt;/p&gt;
&lt;h3&gt;Why not just use the Azure Cost Management API for all of this?&lt;/h3&gt;
&lt;p&gt;You can, and for actual spend you should. The difference is that Cost Management
tells you what you were charged last month, aggregated by resource, while a disk
inventory tells you what you are still being charged for right now and why. Use
Cost Management to check your numbers, and an inventory to decide what to delete.&lt;/p&gt;
&lt;h3&gt;Which tier ladder applies to Premium SSD v2?&lt;/h3&gt;
&lt;p&gt;Neither. Premium SSD v2 bills provisioned capacity, IOPS and throughput
independently rather than in fixed tiers, so the tier reasoning in this post does
not apply to it. Check the SKU before assuming which model you are in.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 scope statement: you do not have to certify the whole company</title>
    <link href="https://acloud.solutions/notes/iso-27001-scope-statement/"/>
    <id>https://acloud.solutions/notes/iso-27001-scope-statement/</id>
    <updated>2025-11-25T09:00:00Z</updated>
    <published>2025-11-25T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>An ISO 27001 scope statement decides how much work you sign up for. Clause 4.3, interfaces and dependencies, and why over-broad scope is self-inflicted.</summary>
    <content type="html">&lt;p&gt;The first draft says &quot;all information systems and processes of the company&quot;. It
was written in an afternoon because it seemed uncontroversial, and it has just
committed you to certifying the finance team&#x27;s spreadsheets, the office door
locks, the marketing agency&#x27;s access to your CMS, and a legacy application two
people use that nobody has patched since 2021.&lt;/p&gt;
&lt;p&gt;An iso 27001 scope statement is the highest-consequence paragraph in the whole
project, and it is usually written before anyone understands what it costs.&lt;/p&gt;
&lt;h2&gt;What clause 4.3 asks for&lt;/h2&gt;
&lt;p&gt;The requirement is short. Determine the boundaries and applicability of the
information security management system, and consider the interfaces and
dependencies between what you do and what other organisations do.&lt;/p&gt;
&lt;p&gt;Three things follow from that wording.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Boundaries can be narrower than the company.&lt;/strong&gt; You may certify a product, a
platform, a business unit, or a set of services. You do not have to certify
everything, and nothing in the standard suggests you should.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exclusions must be justifiable, not merely stated.&lt;/strong&gt; &quot;Excludes the marketing
department&quot; is fine if marketing genuinely does not touch the information the
ISMS protects. It is not fine if they have access to the customer database.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interfaces and dependencies must be identified.&lt;/strong&gt; This is the part people
skip. If a service in scope depends on a supplier, a shared identity provider,
or a team outside the scope, those relationships have to be named, because they
are where the risk crosses the boundary.&lt;/p&gt;
&lt;h2&gt;Why over-broad scope is self-inflicted&lt;/h2&gt;
&lt;p&gt;Every additional thing in scope multiplies through four documents.&lt;/p&gt;
&lt;p&gt;It appears in the risk assessment, because in-scope assets need risks
identified. It appears in the Statement of Applicability, because the controls
you select have to cover it. It generates evidence obligations for every
applicable control, monthly or quarterly, forever. And it becomes something an
auditor can sample at Stage 2 and at every surveillance audit thereafter.&lt;/p&gt;
&lt;p&gt;So a scope that includes the office building means physical security controls,
which means visitor logs, which means an evidence stream you now maintain
indefinitely. A scope that includes a legacy application means that
application&#x27;s vulnerabilities are in the register and the auditor will ask what
you are doing about them.&lt;/p&gt;
&lt;p&gt;None of that is wrong. It is just work you chose, frequently without realising
you were choosing it, in a paragraph written before the gap analysis.&lt;/p&gt;
&lt;h2&gt;What a workable iso 27001 scope statement looks like&lt;/h2&gt;
&lt;p&gt;For a SaaS company, the pattern that holds up:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;text&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;The ISMS covers the design, development, operation and support of the
[product name] platform, including the cloud infrastructure it runs on,
the corporate systems used by personnel with access to that platform,
and the supporting functions of engineering, technical support and
information security.

Delivered from remote and home working locations, with cloud
infrastructure hosted in [region].

Excluded: [named function], which has no access to platform data or to
systems processing it. Physical offices are excluded on the basis that
no company premises store or process information within scope; the
interfaces and dependencies below cover the cloud hosting provider and
identity provider on which in-scope services depend.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note what that does. It scopes by service rather than by department, which
matches how a SaaS company actually works. It brings in the corporate systems
used by people with platform access, because excluding those would be
indefensible when a laptop with production access is the obvious risk. And it
handles physical security by explaining why it does not apply rather than by
ignoring it.&lt;/p&gt;
&lt;p&gt;A remote-first company genuinely may have no premises in scope. Saying so
explicitly, with the reason, is a scope decision. Leaving physical security
unmentioned is an omission an auditor will find.&lt;/p&gt;
&lt;h2&gt;Interfaces and dependencies, concretely&lt;/h2&gt;
&lt;p&gt;The ones that matter for a small SaaS company, and each needs naming:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The cloud provider.&lt;/strong&gt; Infrastructure is theirs, configuration is yours, and
the boundary between those two is worth stating because it determines which
controls you own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The identity provider&lt;/strong&gt;, if it is not the same thing. Everything in scope
depends on it, and a compromise there is a compromise of everything.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sub-processors handling in-scope data.&lt;/strong&gt; These are in your supplier register
and their assurance is your evidence, which is
&lt;a href=&quot;/notes/vendor-risk-review-small-company&quot;&gt;the supplier review question&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Customer-managed responsibilities.&lt;/strong&gt; If customers administer their own users
in your platform, some controls are theirs. Say so.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Any function outside scope that nonetheless touches in-scope systems.&lt;/strong&gt; If
finance uses a system that reads platform data, either bring it in or explain
the control at the boundary.&lt;/p&gt;
&lt;h2&gt;How scope shapes everything downstream&lt;/h2&gt;
&lt;p&gt;Get this right and the rest of the project gets smaller in a way that compounds.&lt;/p&gt;
&lt;p&gt;The risk assessment only considers in-scope assets, so the register is shorter
and the risks are ones you can actually own.
&lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;The risk assessment&lt;/a&gt; becomes tractable rather
than encyclopaedic.&lt;/p&gt;
&lt;p&gt;The Statement of Applicability inherits the same boundary, so controls that
would otherwise need a justification for exclusion become simply out of scope.&lt;/p&gt;
&lt;p&gt;Evidence obligations shrink proportionally, which matters most because they are
the recurring cost rather than the one-off.&lt;/p&gt;
&lt;p&gt;And Stage 2 sampling is bounded by it. An auditor cannot ask for evidence about
something outside the scope you declared, which is not a loophole, it is the
purpose of declaring a scope.&lt;/p&gt;
&lt;h2&gt;Getting it agreed&lt;/h2&gt;
&lt;p&gt;Scope is a leadership decision, not a technical one, and clause 5 wants
leadership involved. That is useful rather than bureaucratic: a scope somebody
senior has signed off is a scope you can point at when a well-meaning colleague
suggests adding something in month five.&lt;/p&gt;
&lt;p&gt;Two things to put in front of them. What each candidate inclusion costs, in
recurring evidence rather than in one-off effort, because that is the number
that matters and nobody estimates it. And what the customer who triggered the
project actually asked for, which is frequently narrower than the internal
assumption.&lt;/p&gt;
&lt;p&gt;Record the decision in the management meeting minutes with the scope statement
attached. That single record satisfies part of clause 5, gives you the leadership
commitment evidence an auditor asks for, and settles the question. The
&lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO 27001 standard itself&lt;/a&gt; is the
authority on what 4.3 requires, and it is worth reading the clause rather than a
summary of it, because it is four sentences long and every word does something.&lt;/p&gt;
&lt;p&gt;Revisit the scope annually as part of management review, and formally amend it
if the business has changed. A certificate whose scope no longer matches what
the company does is a finding waiting for a surveillance audit.&lt;/p&gt;
&lt;h2&gt;The mistake worth avoiding&lt;/h2&gt;
&lt;p&gt;Do not scope narrowly to dodge work in a way your customers will notice.&lt;/p&gt;
&lt;p&gt;A certificate whose scope excludes the product the customer buys is worse than
no certificate, because it looks like an attempt to mislead. Procurement teams
read scope statements, and a mismatch between the certificate and the service
being purchased becomes a longer conversation than the one you were trying to
avoid.&lt;/p&gt;
&lt;p&gt;The test: would the customer who triggered this project be satisfied by this
scope. If not, widen it. If yes, resist widening it further out of a general
sense that more is safer, because more is only more.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/book/&quot;&gt;The book&lt;/a&gt; covers scoping in more detail, including the wording that
survived an audit, and
&lt;a href=&quot;/consulting/&quot;&gt;the security and compliance work&lt;/a&gt; is the other option if you
would rather the first draft came from somebody who has watched a few of these
get questioned.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Sentinel analytics rules you have not tested are rules you do not have</title>
    <link href="https://acloud.solutions/notes/sentinel-analytics-rules-validation/"/>
    <id>https://acloud.solutions/notes/sentinel-analytics-rules-validation/</id>
    <updated>2025-11-18T09:00:00Z</updated>
    <published>2025-11-18T09:00:00Z</published>
    <category term="Azure security"/>
    <summary>Sentinel analytics rules fail silently when a table or column is missing. What a validator checks, and why twelve proven rules beat sixty imported ones.</summary>
    <content type="html">&lt;p&gt;The rule is called &quot;Suspicious sign-in from unfamiliar location&quot;. It has been
enabled for fourteen months. It is scheduled every five minutes, it has a
severity of High, and it has never produced a single alert.&lt;/p&gt;
&lt;p&gt;Two explanations. Either nothing suspicious has happened in fourteen months, or
the rule does not work. Sentinel analytics rules give you no way to tell those
apart from the portal, because a rule that cannot run does not report an error.
It returns zero rows, which looks identical to a quiet estate.&lt;/p&gt;
&lt;h2&gt;Why sentinel analytics rules fail quietly&lt;/h2&gt;
&lt;p&gt;The causes are dull, which is why they persist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The table does not exist in your workspace.&lt;/strong&gt; Someone copied a rule that
queries &lt;code&gt;SecurityEvent&lt;/code&gt;, and you never deployed the agent that populates it. The
query is valid KQL. It simply has nothing to run against, and Sentinel treats an
empty table the same as an empty result.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A column was renamed.&lt;/strong&gt; Schemas change. &lt;code&gt;TimeGenerated&lt;/code&gt; is stable, but plenty
of connector-specific columns are not, and a &lt;code&gt;project&lt;/code&gt; of a column that no longer
exists narrows your result to nothing rather than raising an error.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The connector was never enabled.&lt;/strong&gt; The most common version of the first
problem. &lt;code&gt;AuditLogs&lt;/code&gt; and &lt;code&gt;SigninLogs&lt;/code&gt; require the Entra ID connector. If somebody
set up the workspace and somebody else imported the rules, nobody necessarily
checked.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The rule was written for a different tenant&#x27;s layout.&lt;/strong&gt; Custom tables,
different table names, a different Log Analytics workspace structure. Community
rulesets are enormously useful and they were written against somebody else&#x27;s
estate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nothing has matched yet, legitimately.&lt;/strong&gt; This is a real answer, and it is
indistinguishable from all of the above unless you check.&lt;/p&gt;
&lt;h2&gt;What a validator should check&lt;/h2&gt;
&lt;p&gt;The point is to make &quot;this rule works&quot; a fact you have established rather than
an assumption. Five checks, in this order, because each one is only meaningful
if the previous passed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It parses.&lt;/strong&gt; Genuine KQL parsing rather than a regular expression hunting for
keywords. A missing pipe or an unbalanced bracket should fail at your desk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every table referenced exists&lt;/strong&gt; in the workspace you are targeting, checked
against the live schema rather than a list of what usually exists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every column referenced exists&lt;/strong&gt; on those tables. This is the one that catches
schema drift, and it is the reason parsing alone is not enough.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It returns rows against historic data.&lt;/strong&gt; Run the logic over a wide lookback,
ninety days rather than five minutes. If a privilege escalation rule finds no
role assignments in ninety days, either your estate is unusually static or the
rule is wrong, and both are worth knowing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Severity and MITRE tactics are populated.&lt;/strong&gt; An unclassified High alert is one
nobody triages, and an alert nobody triages is worse than no alert because it
consumes the attention you were saving.&lt;/p&gt;
&lt;p&gt;The first three should block deployment. The fourth should warn, because a
detection that is legitimately quiet is fine. Microsoft&#x27;s
&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/sentinel/detect-threats-custom&quot;&gt;guidance on custom analytics rules&lt;/a&gt;
covers the rule mechanics; the validation layer is the part you have to build or
buy.&lt;/p&gt;
&lt;h2&gt;Two categories first&lt;/h2&gt;
&lt;p&gt;For a small estate, configuration drift and privilege escalation are where to
start, and everything else can wait.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configuration drift&lt;/strong&gt; is the security control that quietly stopped applying. A
Conditional Access policy modified or deleted. A storage account made public. A
diagnostic setting removed, which is the one that covers the attacker&#x27;s tracks
and almost nobody watches. These fire rarely, and when they fire they are almost
always worth reading.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Privilege escalation&lt;/strong&gt; is access that appeared. A role assignment at
subscription scope. A new credential on an existing app registration. A guest
elevated. Same property: rare, and interesting when it happens.&lt;/p&gt;
&lt;p&gt;Both categories share the thing that makes them viable for one person. They
alert on change rather than on volume, so they do not require somebody watching a
screen. They require somebody reading an email occasionally.&lt;/p&gt;
&lt;h2&gt;A rule worth having&lt;/h2&gt;
&lt;p&gt;Conditional Access modification, which is the one people are most surprised to
need until the first time somebody excludes themselves from MFA:&lt;/p&gt;
&lt;div class=&quot;codewrap&quot; data-lang=&quot;kusto&quot;&gt;&lt;button class=&quot;copybtn&quot; type=&quot;button&quot;&gt;Copy&lt;/button&gt;&lt;pre class=&quot;mono&quot;&gt;&lt;code class=&quot;language-kusto&quot;&gt;AuditLogs
| where TimeGenerated &amp;gt; ago(1d)
| where OperationName has_any (
    &amp;quot;Update conditional access policy&amp;quot;,
    &amp;quot;Delete conditional access policy&amp;quot;,
    &amp;quot;Add conditional access policy&amp;quot;)
| extend Actor = tostring(InitiatedBy.user.userPrincipalName)
| extend PolicyName = tostring(TargetResources[0].displayName)
| extend Modified = tostring(TargetResources[0].modifiedProperties)
| project TimeGenerated, OperationName, PolicyName, Actor, Modified, Result
| order by TimeGenerated desc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run that over ninety days on your own workspace before you schedule it. If it
returns nothing, either nobody has touched Conditional Access in three months,
or &lt;code&gt;AuditLogs&lt;/code&gt; is not being ingested. Find out which.&lt;/p&gt;
&lt;h2&gt;Fewer rules, proven&lt;/h2&gt;
&lt;p&gt;The instinct when setting up Sentinel is to import everything available, on the
grounds that more detection is more security. It is not, for two reasons.&lt;/p&gt;
&lt;p&gt;Rules you have not validated give you false confidence, which is worse than no
confidence because it stops you looking. And rules that fire often get muted,
which trains you to ignore the channel the real alert will arrive in.&lt;/p&gt;
&lt;p&gt;Twelve rules that provably run, each of which you could explain to somebody, is
a better position than sixty imported ones where you could not say which are
live. That is the argument behind
&lt;a href=&quot;/tools/azclean-detections/&quot;&gt;AzClean Detections&lt;/a&gt;, and the
&lt;a href=&quot;/notes/sentinel-cost-control&quot;&gt;ingestion cost note&lt;/a&gt; covers the other constraint
on how many you can afford to feed.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;How do I tell whether a rule has ever fired?&lt;/h3&gt;
&lt;p&gt;Check the incidents and alerts generated by that rule name over a long window
rather than the rule blade. A rule with no alerts in ninety days is a question,
not necessarily a fault, but it should always be a question you have asked.&lt;/p&gt;
&lt;h3&gt;Does running validation queries cost me anything?&lt;/h3&gt;
&lt;p&gt;Queries against data already ingested are not charged per query on the standard
model, but they do consume workspace resources and there are limits on
concurrent queries. Validating twelve rules over ninety days is not a meaningful
cost. Ingestion is where the money goes, which the
&lt;a href=&quot;/notes/sentinel-cost-control&quot;&gt;Sentinel cost note&lt;/a&gt; covers.&lt;/p&gt;
&lt;h3&gt;Should I validate the built-in Microsoft rule templates too?&lt;/h3&gt;
&lt;p&gt;Yes, and for the same reason. A built-in template can reference a table your
workspace does not have, because the templates cover connectors you may not have
enabled. Being Microsoft&#x27;s rule does not make it a working rule in your tenant.&lt;/p&gt;
&lt;h3&gt;What about rules that need a connector I am not paying for?&lt;/h3&gt;
&lt;p&gt;Disable them rather than leaving them enabled and empty. An enabled rule with no
data source is the exact thing this note is about, and leaving it in place makes
your rule list untrustworthy.&lt;/p&gt;
&lt;h3&gt;Is a rule that returns nothing over ninety days always broken?&lt;/h3&gt;
&lt;p&gt;No. Some detections should be silent for years, which is the point of them. The
distinction is whether you have confirmed it can run, and validating tables and
columns answers that without needing the event to have occurred.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>ISO 27001 implementation small business guide for the volunteered</title>
    <link href="https://acloud.solutions/notes/iso-27001-on-your-own/"/>
    <id>https://acloud.solutions/notes/iso-27001-on-your-own/</id>
    <updated>2025-11-11T09:00:00Z</updated>
    <published>2025-11-11T09:00:00Z</published>
    <category term="ISO 27001 and compliance"/>
    <summary>ISO 27001 implementation small business reality: a realistic timeline for one person, where the time actually goes, and what to do in the first fortnight.</summary>
    <content type="html">&lt;p&gt;The message arrives on a Tuesday. A customer&#x27;s procurement team has asked
whether you hold ISO 27001, the answer is no, and the deal is large enough that
somebody senior has decided the answer should become yes. You are the person who
knows about security, in the sense that you are the person who knows about
everything, and the project is now yours.&lt;/p&gt;
&lt;p&gt;Iso 27001 implementation small business projects nearly always start like that.
Not from a strategic decision about information security, but from a sales
conversation, which matters because it sets a deadline before anyone has
established what the work involves.&lt;/p&gt;
&lt;h2&gt;What iso 27001 implementation small business projects actually involve&lt;/h2&gt;
&lt;p&gt;The standard has two halves and people spend their effort on the wrong one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Clauses 4 to 10&lt;/strong&gt; are the management system. Understanding your context and
interested parties. Leadership commitment, which means real decisions by real
managers, recorded. Planning, including the risk assessment and the objectives.
Support: resources, competence, awareness, documented information. Operation.
Performance evaluation, which is monitoring, internal audit and management
review. Improvement, meaning nonconformities and corrective action.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Annex A&lt;/strong&gt; is 93 controls across four themes: organisational, people, physical
and technological. You consider each one, apply the ones relevant to your risks,
and justify the exclusions in a Statement of Applicability.&lt;/p&gt;
&lt;p&gt;Everybody starts with Annex A because it looks like a checklist and checklists
feel tractable. Then the auditor spends the morning asking how the risk
assessment method was chosen and whether management review produced any
decisions, and the controls turn out to be the easy part. The clauses are the
system; the controls are evidence that the system does something.&lt;/p&gt;
&lt;h2&gt;A realistic timeline&lt;/h2&gt;
&lt;p&gt;For one person, part time, in a company of a few dozen people with reasonable
technical hygiene already in place, six to nine months to certification is
achievable. Three months is not, and the reason is not effort.&lt;/p&gt;
&lt;p&gt;Two constraints are structural. Stage 2 requires evidence that controls have
operated over a period, so you cannot compress the operating window by working
harder. And clause 9 requires an internal audit and a management review to have
happened before the certification audit, both of which need scheduling around
other people&#x27;s diaries.&lt;/p&gt;
&lt;p&gt;A shape that works:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Months 1 to 2.&lt;/strong&gt; Scope, context, interested parties, gap analysis. Decide what
is in and out and write it down properly, because
&lt;a href=&quot;/notes/iso-27001-scope-statement&quot;&gt;scope shapes everything downstream&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Months 2 to 4.&lt;/strong&gt; Risk assessment and treatment plan, then the Statement of
Applicability derived from it. Policies written and approved during this period.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Months 4 to 6.&lt;/strong&gt; Implement whatever the treatment plan requires. Start
generating evidence deliberately rather than incidentally.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Months 6 to 7.&lt;/strong&gt; Internal audit, then management review. Fix what the internal
audit finds, which is the point of doing it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Month 7 onward.&lt;/strong&gt; Stage 1, close the findings, Stage 2.&lt;/p&gt;
&lt;p&gt;If the deadline you have been given is shorter than this, the conversation to
have now is about which quarter certification lands in rather than about working
faster. That conversation goes better in month one than in month five.&lt;/p&gt;
&lt;h2&gt;Where the time actually goes&lt;/h2&gt;
&lt;p&gt;Not where people budget it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The risk assessment&lt;/strong&gt;, because a defensible one is harder than a complete one.
A 200-row register produced in a week will not be maintained and will not
survive questioning. A 30-row register with real owners, a stated method and
clear links to the controls you selected will.
&lt;a href=&quot;/notes/iso-27001-risk-assessment&quot;&gt;The risk assessment note&lt;/a&gt; covers what an
auditor actually asks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Policies and their lifecycle.&lt;/strong&gt; Writing a policy takes an afternoon.
Getting it approved by the right person, acknowledged by staff, and reviewed on
a schedule, with evidence of each, takes months of calendar time even though it
is hours of work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Evidence.&lt;/strong&gt; This is the one that catches everybody. Controls are fine; proving
they operated across a period is the work, and it is not retrospective. An
access review you performed in February without recording it did not happen as
far as the audit is concerned.&lt;/p&gt;
&lt;p&gt;The practical consequence: start capturing evidence in month one, before the
controls are finished, because the period being sampled at Stage 2 includes the
months when you were still building.
&lt;a href=&quot;/notes/audit-evidence-automation&quot;&gt;Scheduled evidence collection&lt;/a&gt; pays back more
than any other automation in the project.&lt;/p&gt;
&lt;h2&gt;What to do in the first fortnight&lt;/h2&gt;
&lt;p&gt;Four things, in this order, none of which require a decision from anybody else.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Write the scope statement.&lt;/strong&gt; One paragraph naming what is included, what is
excluded, and the interfaces and dependencies. This is clause 4.3 and it is the
document everything else refers back to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do a gap analysis against Annex A.&lt;/strong&gt; Honestly, in a spreadsheet, with three
values per control: in place, partial, absent. Do not fix anything yet. The
output is the size of the project, which is what you need for the timeline
conversation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Book the internal auditor.&lt;/strong&gt; Seriously, in the first fortnight. Independence
is the hardest constraint to satisfy at this scale, availability is worse than
you expect, and discovering in month six that you cannot arrange it is a delay
you cannot recover.
&lt;a href=&quot;/notes/iso-27001-internal-audit-one-person&quot;&gt;The internal audit note&lt;/a&gt; covers the
options.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Get leadership commitment recorded.&lt;/strong&gt; Not a conversation, a recorded decision:
a management meeting with the scope, the objectives and the resource commitment
minuted. Clause 5 requires it, an auditor will ask for it, and it is far easier
to obtain in the enthusiasm of month one.&lt;/p&gt;
&lt;h2&gt;Getting the standard&lt;/h2&gt;
&lt;p&gt;You need to read the standard, and it is not free. ISO/IEC 27001:2022 is
available from &lt;a href=&quot;https://www.iso.org/standard/27001&quot;&gt;ISO&lt;/a&gt; and from national
standards bodies. Budget for it. Working from summaries and blog posts, including
this one, is how you end up confidently wrong about a clause.&lt;/p&gt;
&lt;h2&gt;Questions&lt;/h2&gt;
&lt;h3&gt;Can one person really do this?&lt;/h3&gt;
&lt;p&gt;Yes, with two caveats. Internal audit needs somebody who is not you, and
leadership decisions need actual managers. Everything else can be done by one
competent person alongside another job, over the timeline above.&lt;/p&gt;
&lt;h3&gt;How much does certification cost?&lt;/h3&gt;
&lt;p&gt;The certification body&#x27;s fee depends on headcount and scope and is quoted per
engagement, so any figure here would be invented. Get three quotes; they vary
more than you would expect. Budget separately for the standard itself and for
whatever the treatment plan requires you to buy.&lt;/p&gt;
&lt;h3&gt;Do I need a consultant?&lt;/h3&gt;
&lt;p&gt;Not necessarily, and the honest test is whether you have time rather than
whether you have knowledge. A consultant compresses the calendar and brings
pattern recognition about what auditors accept. If you have nine months and
reasonable technical foundations, doing it yourself produces a system you
understand, which matters more in year two than in year one.&lt;/p&gt;
&lt;h3&gt;Is ISO 27001 the right certification?&lt;/h3&gt;
&lt;p&gt;Not always. If your customers are UK public sector or SME, Cyber Essentials may
be what they actually want and it is a fraction of the effort.
&lt;a href=&quot;/notes/cyber-essentials-vs-iso-27001&quot;&gt;The comparison note&lt;/a&gt; covers which buyers
ask for what. Find out what the customer who triggered this actually requires
before committing to nine months.&lt;/p&gt;
&lt;h3&gt;What happens after certification?&lt;/h3&gt;
&lt;p&gt;A surveillance audit each year and recertification every three. Year two is the
one that catches people, because the controls that lapse are the annual ones
nobody diarised.
&lt;a href=&quot;/notes/iso-27001-surveillance-audit&quot;&gt;The surveillance note&lt;/a&gt; covers it.&lt;/p&gt;</content>
  </entry>
</feed>
