A One-Day Security Baseline for a Solo Fleet
When you run production by yourself, security advice written for companies is mostly noise. It assumes a team to watch dashboards, a budget for tooling, a compliance regime to satisfy. I have none of those, and neither does anyone else operating a small fleet alone. So the question is not "how do I build a security program." It is "what is the smallest set of controls that stops the failures that would actually end me," and the answer is that it fits in an afternoon.
Two principles run under the whole afternoon. The threats that realistically kill a solo operation are a short, boring list with cheap, set-once defenses, so the goal is a catastrophic floor, not coverage. And the highest-leverage controls run themselves: log everything, alarm on the catastrophes, and make the irreversible mistakes structurally hard, because anything that depends on you watching fails the day you are not watching.
The real threat model is boring#
Start with what actually goes wrong for a one-person operation. The real list is mundane:
- A secret (an API key, a token) pasted into a repo and pushed.
- A credential that leaks and gets used to run up a bill or poke at your resources.
- A cost that runs away, from a mistake or a compromise, while you are asleep.
- A destructive git accident: a force-push that erases a main branch's history.
- A dependency with a known vulnerability sitting in your build.
None of these require a movie villain. They are the accidents that happen to careful people on ordinary days. And every one of them is cheap to defend against, which is the whole opportunity: a small operation cannot afford a security team, but it does not need one to handle this list.
There is one way a solo operator is more exposed than a team, and it shapes the whole approach. On a team, a second person reviews the change and sometimes catches the secret in the diff, the over-broad permission, the bucket left open. Alone, that second pair of eyes does not exist. So the automated controls below are the substitute for the review redundancy a team gets for free. The machine has to be the colleague who catches the mistake, because there is no colleague.
The baseline, set up once#
Here is what I stood up, what each piece defends, and whether it prevents a problem or just makes sure I find out fast.
| Control | What it defends against | Prevent or detect |
|---|---|---|
| CloudTrail logging across the account | "What happened, and when" after anything odd | Detect |
| GuardDuty threat detection on that trail | Credential misuse, unusual API patterns | Detect |
| IAM Access Analyzer | A resource accidentally open to the world | Detect |
| An AWS Budgets alarm, set low | Cost crossing a threshold in delayed billing data | Detect, delayed |
| GitHub secret scanning + push protection | Supported secret patterns on covered push paths | Detect; prevent supported pushes |
| Dependabot alerts | Known-bad packages in the build | Detect |
| Branch protection on every repo | Force-push or deletion of main history | Prevent |
| Scoped IAM identities for daily work | Blast radius if one credential leaks | Prevent, limit |
That is the baseline I set up. Most of it is managed services you enable, alarms you point at your email, and protection rules you apply across repositories. My setup took an afternoon and cost a few dollars a month. Each control covers a specific failure mode, with limits that matter when you rely on it.
Two principles do the heavy lifting#
The specific services matter less than the two ideas underneath them, because those ideas tell you what to reach for next as the fleet grows.
The first is detection where prevention is incomplete. Alerts can shorten the time between a failure and my response, but they do not guarantee detection within minutes. AWS Budgets typically refreshes every eight to twelve hours, and billing delays can let costs exceed a threshold before notification. A low budget alarm helps me notice spend; it neither caps the bill nor stops a compromised key.
The second is structural controls for mistakes that are hard to reverse. Branch protection can reject force-pushes and deletion on covered branches, subject to its configured bypass permissions. GitHub push protection blocks supported secret patterns and token versions; availability depends on repository settings and plan, and permitted bypasses still need attention. Unsupported or obfuscated values can escape detection, so review and scanning remain useful. Scoped identities limit which actions a leaked credential can take.
What this is not#
This baseline is detection and blast-radius control. It will not stop a determined, targeted attacker who wants specifically you. There is no continuous monitoring, no penetration testing, no compliance posture. For a personal fleet that is the correct scope: a month spent building those would be effort stolen from the actual product to defend against threats I do not face.
There is one piece of discipline the automation cannot replace, and it is the easy one to skip: test that the alerts actually reach you. The afternoon is not done when the services are enabled. It is done when you have watched a test alert actually land in your inbox, and rotated any credentials you minted along the way so none of them outlive the setup that needed them.
Related:
- When CI costs more than it saves, the budget-first instinct applied to CI
- Institutional memory for a team of one, the same operate-alone-reliably theme
Questions this post answers
- Which security risks did you prioritize for a solo fleet?
- For my solo fleet, I prioritized exposed secrets, misused credentials, runaway cloud spend, destructive changes to main branch history, and dependencies with known vulnerabilities. This is the threat set I chose for the baseline, not a claim that it covers every attacker or operation.
- Which controls make up your solo-fleet security baseline?
- My baseline uses CloudTrail for account history, GuardDuty for suspicious activity, Access Analyzer for unintended public access, and a budget alarm for cost surprises. GitHub secret scanning and push protection, Dependabot, branch protection, and scoped IAM cover repository secrets, dependencies, destructive history changes, and credential blast radius. Each control is labeled as prevention, detection, or blast-radius limitation. This is a deliberately minimal baseline for a one-person operation, not a complete security posture.
- When do you use detection instead of structural prevention?
- I favor detection when I cannot guarantee prevention, and structural guardrails when the mistake is hard to reverse. A budget alarm reveals spend; branch and push protection block specific repository mistakes; scoped identities limit what a leaked credential can reach.
- How do you verify that security alerts actually work?
- I do not count an alerting control as finished until a test alert reaches the intended inbox. I also rotate credentials created during setup so temporary access does not outlive the work that required it.