Identity is the perimeter

The network boundary stopped being the security boundary the moment workloads started talking to managed services over the public internet. What is left is identity: who is calling, what are they allowed to do, and how do you know.

Managed identity instead of a stored secret

A secret you never store cannot leak. Managed identities let an Azure resource authenticate to another without a credential in configuration, in a pipeline variable, or in an appsettings file.

This is the single highest-leverage change in most estates. Every connection string with a password in it is a future incident report.

Use it when any Azure-to-Azure call. There is rarely a good reason not to.
Key Vault for what remains

Some secrets are unavoidable — third-party API keys, legacy systems with no token support. Put them in Key Vault, reference them from the application, and give the application identity read access to that secret only.

The win is not just storage. It is rotation in one place, an access log, and the ability to answer “who read this and when”.

Use it when a credential genuinely cannot be replaced by an identity.
Least privilege, reviewed

Owner and Contributor at subscription scope are how most environments start and how many stay. Scope role assignments to the resource group or resource, prefer built-in roles, and use time-bound elevation for the rest.

The review matters more than the initial grant. Access accumulates: people change teams, contracts end, and nothing removes the assignment.

Use it when always — and put a recurring review in the calendar, not in someone's intentions.

Secrets, and how they escape

Secrets rarely leak through a sophisticated attack. They leak because they were committed, logged, or pasted into a support ticket.

If a credential reaches a git repository, rotate it. Rewriting history is worth doing, but it is not a remedy — forks, clones, caches and unreferenced objects on the hosting platform all outlive the rewrite. Rotation is the only thing that actually closes the exposure.

Configuration from the environment, never the repository

Ship a committed example file listing every variable the application needs, with placeholder values, and read the real ones from environment variables or a secret store.

Fail fast at startup when a required secret is missing, naming the variable. A clear error at boot is far better than an opaque failure on the first request — and far better than silently falling back to a hardcoded default, which is how public repositories end up shipping a known signing key.

Use it when every project, from the first commit.
Scan for secrets in CI, and pre-commit

Automated scanning catches the accident before it is permanent. Run it in the pipeline as a gate, and locally as a pre-commit hook so the feedback arrives before the push.

Expect false positives on example files and test fixtures, and allow-list them explicitly rather than turning the check off.

Use it when any repository that will be pushed anywhere, public or private.
Log the event, not the payload

Request and response bodies are the most useful thing in an incident and the most dangerous thing in a log store. They contain tokens, personal data and occasionally card numbers.

Log identifiers, timings, and outcomes. If you must capture bodies, redact by allow-list — a deny-list of field names will miss the one the new feature added last week.

Use it when always. Log retention outlives the reason you enabled verbose logging.

Network, still worth doing

Identity being the perimeter does not mean the network stopped mattering. It means the network is defence in depth rather than the only defence.

Private endpoints for data services

A database, storage account or Key Vault reachable from the public internet is one credential mistake from being reachable by anyone. Private endpoints put them on your virtual network and let you disable public access entirely.

The operational cost is DNS. Plan private DNS zones deliberately, or you will spend an afternoon working out why a name resolves correctly from one subnet and not another.

Use it when any data store holding data you would have to disclose a breach of.
Egress control, not just ingress

Most designs filter what comes in and let anything out. Exfiltration and command-and-control both rely on outbound traffic.

Restricting egress to known destinations is genuinely inconvenient and genuinely effective. Start with the workloads handling the most sensitive data rather than trying to do the whole estate at once.

Use it when handling regulated data, or after any incident involving a compromised workload.

Supply chain and images

Pin, scan and rebuild base images

A container image is a point-in-time snapshot of somebody else's distribution plus your code. Pin the base image by digest for reproducibility, scan it for known vulnerabilities, and rebuild on a schedule so patches actually land.

An image built eighteen months ago and never rebuilt is running eighteen months of unpatched libraries, regardless of how current your application code is.

Use it when any containerised workload you did not rebuild this quarter.
Know what you are redistributing

Bundling tools into an image — ghostscript, ffmpeg, LibreOffice, fonts — brings their licences with it. Several require attribution when the image is distributed, which an on-premise licence is.

Keep a third-party notices file with the image, and keep it current. It is a small file that prevents a genuinely awkward conversation.

Use it when you ship an image to anyone outside your own environment.

Where to read more