The fourth day-0 decision has two halves that feel unrelated and are actually the same idea. The first half is that encryption is a default, not a feature you switch on for the sensitive things. The second half is what to do on the rare occasion when least privilege genuinely cannot be honored, when a wide grant is unavoidable. The connecting idea is that a security posture is only as trustworthy as the reasons written next to its exceptions.
Encryption is table stakes, so treat it that way
On a modern cloud, encryption at rest is not something you build. Every managed store encrypts by default, and for most data that default is exactly right and requires no thought. The interesting decision is not whether to encrypt. It is which things deserve a key you control rather than the provider's.
The answer in this project is deliberate rather than uniform. The most privileged store, the Terraform state, is encrypted with a customer-managed key, because state is the map of everything and a key you own gives you your own IAM on it, your own rotation schedule, and your own audit trail. That was the root-of-trust decision from the first part of this series, and it is the one place the extra key management earns its keep. Elsewhere, the default provider encryption is left in place on purpose, because reaching for a customer-managed key on every bucket is key-management overhead that buys little and can, if the key is ever mishandled, become the way you lose your own data. Encrypt everything, yes. Hold your own key where the data justifies the responsibility, and be honest that most data does not. Secrets live in a managed secret store and are read at runtime by the workload's own identity, never inlined into a container image, an instance's metadata, or the state file. Transport is encrypted too: the edge serves TLS with a managed certificate, and plain HTTP is answered with a permanent redirect rather than served. Encryption is the floor across the board. The only real choice is who holds the key, and that choice is made per store, with a reason.
The tradeoff nobody frames on day 0: logging is also leaking
Here is the half of this that is genuinely a day-0 decision, because it is easy to get wrong precisely when you are trying to do the responsible thing. The instinct that says "encrypt everything" has a sibling that says "log everything," and the sibling is dangerous. Every log line is a small, unencrypted, long-lived copy of whatever it captured. The more you log, the more places a secret can come to rest. Observability and secret hygiene pull in opposite directions, and the tension is real.
So part of encrypting by default is deciding, up front, what must never be recorded. An access log that captures a request in full will happily capture the authorization header, the API key in a query string, the contents of an uploaded file. Turn on verbose logging without thinking and you have just written your most sensitive values into a store that has none of the protections the real secret store has. The right move is to cap what the logs capture so they never record the credential or the payload, and to write that reasoning down in the configuration so the next person does not "improve observability" by turning it back on. This is not the exciting part of security, and it is exactly the part that leaks.
When least privilege cannot win, argue for the exception in writing
The rest of this series has been deny by default and minimal grants. This section is the honest counterweight, because real systems have exactly one or two places where the narrow answer is impossible, and pretending otherwise makes a posture brittle. What matters is what you do at those places.
The exception in this project is public access. The workload is a public, opt-in service, so unauthenticated users genuinely have to be able to invoke it. On its own that is fine. It collided with an organization-wide policy that, correctly, restricts every identity in every project to the organization's own members, which is a strong default that blocks exactly the kind of "allow anyone" grant that public access requires. The narrow, least-privilege answer would be to keep that restriction. But an external HTTPS load balancer does not authenticate itself to the backend as an organization member; the load balancer cannot be the identity. So to let public traffic through the edge at all, this one project overrides that restriction and permits the broad public grant.
That is a real widening of the default, and the temptation is to make the change quietly and move on. Instead the grant carries its compensating-control argument in the code, right next to the exception, and the argument is what makes it defensible. The override is scoped to this single project, so the organization-wide restriction stays intact everywhere else. And crucially, the broad grant is made safe by making the direct path unreachable. The service accepts traffic only from the internal load-balancer path; its own default URL is configured to be unreachable from the internet. So the "allow anyone" is not a wide-open service. It is the plumbing that lets load-balancer traffic through, while every request is still forced through the edge and its web application firewall, because there is no other door. The broad allow is real, and it is boxed in by a control that makes the breadth harmless, and both facts are written down where the grant lives.
One scope note, because this series describes the same environment at two points in its life. This broad-grant-and-compensating-control shape belongs to the load-balancer-fronted service. The no-external-IP VM that later replaced it, in the deny-by-default part, needs no such grant at all; it simply has no public address. Different mechanic, same property: the load balancer is the only way in.
The pattern under both halves
The through-line is that security lives in the reasons, not just the settings. Encryption at rest is a default anyone can turn on; the decision that matters is where you hold your own key and where you honestly admit you do not need to. Deny by default is a posture; the decision that matters is what you do at the one place you cannot honor it. In both cases the durable artifact is not the toggle. It is the sentence next to the toggle explaining why this is the safe choice, so that six months later someone reading the code inherits the reasoning and not just the result.
A grant with its justification beside it is a decision. A grant without one is a mystery that the next person will either preserve out of fear or remove out of ignorance, and both are worse than the honest paragraph you could have written when you made it. Encrypt by default, refuse to log the things you are trying to protect, and when you must open something wide, argue for it in writing, right where the grant lives.
Previously in this series: The Network Says No First. Next: The Record of Who Did What.
The same decision on AWS: Encrypt by Default, and Write Down Why the One Wide Grant Is Safe.