I started this project to replace Paperless-ngx . I ended up keeping it and building on top. The container kept crashing every few days. Auto-tagging missed anything it hadn’t seen before. There was no vision support for scanned PDFs. And it was mine and only mine: the family’s documents were locked in a web UI my wife was never going to open, and I never wanted her to have to. The…
The first safety change I made for my agents was the one that does the least. I aliased rm to trash-put , from trash-cli , so a deleted file lands in a recoverable trash instead of vanishing. It felt responsible. Then I thought about how an agent actually runs a command, and the alias stopped looking like a guardrail. An alias only exists in an interactive shell. When Claude Code or Codex runs a…
Every recurring failure in the loop ends up as one of two things: a line in a policy file, or a small script that cleans up after it. I ended the last post by calling the loop a solved problem, with the only hard part left being the cut: deciding what goes into an issue. That was true when I wrote it, and it still is. What it skipped is the part that got interesting: what it took to let the agents…
Where the queue lives decides what the work costs. I have built two systems for handing work to AI agents. In the first, the queue lived inside the repository as a markdown file. In the second, it lives in a self-hosted issue tracker that two agent runtimes poll every twelve minutes. The second one is better, and the reason is bookkeeping. 639 Slices and a Status File security-atlas is a security…
In Agents Don’t Travel Well I called pasting screenshots into a remote Claude Code session my biggest day-to-day gripe with the whole setup. The clipboard lives on the laptop in front of me. The session lives on the Mac Studio at home. Copy an image, switch to the tmux pane, hit paste, and nothing lands. I closed that section with “if you’ve solved this, please find me.” I…
I did not set out to build a patchwork. Each piece went in because I needed it that day, and every one worked. What I ended up with was three different tools doing the same job, reaching my own machines from wherever I happened to be, each with its own config, its own failure mode, and its own maintenance. The pile was the problem, and no single tool in it was. Three Tools Doing One Job The oldest…
Every platform team has the same argument eventually, and it never ends the same way twice. One side wants a single authorization service: one place that answers “can this user do this” for every service, so the rules live in one spot and the audit is one query. The other side wants each service to decide for itself: no network hop on every check, no shared thing that can take the…
A request comes into your product carrying a real, authenticated user. By the third internal service it touches, that user is gone. The service writing to the database does not know who made the request or which tenant they belong to. It knows only that the call came from another service inside the cluster, and inside the cluster, services trust each other. The user authenticated once, at the…
Set the rule: no corporate laptops, and no VPN. Everyone works from the phone and the computer they already own, and there is no network anyone logs onto. A BYOD enterprise with no VPN is buildable, and it can be more locked down than the company handing out a managed laptop to every hire, because it is forced to stop relying on the two things that were never as trustworthy as they looked: the…
A ticket for production access sits in a queue for three days. The engineer who filed it had a deadline yesterday. So the next time they need anything, they do the rational thing: they ask for everything they might conceivably need, all at once, up front, and then they never give any of it back. Why would they? Asking again costs three more days. Multiply that across every engineer and every…
Every time we came back to authorization in the product, the model had grown. Another object type that needed sharing. Another permission that had to be finer than read and write. Another request to manage it all with roles or groups instead of one-off grants. We had reached for a Zanzibar-style model in the first place because the permissions had outgrown a role column, and then the model itself…
For most of the history of access control, logging in was a one-time decision. The user authenticates, the system issues a token, and from that moment until the token expires, access is granted on the strength of that one check. Nothing looks again. The token is a standing bet that nothing important changed between the login and the expiry, and for a long time the bet paid off often enough to…
Put your secrets in one vault. Put your logins behind one identity provider. Run privileged access through one broker. Give your workloads one identity scheme instead of a hundred static keys. The advice arrives in different vocabularies from different corners of security, and underneath it is the same instruction every time: take a scattered, ungoverned surface and collapse it to a single point…
I was most of the way through writing about break-glass access when I realized I had only written the prevention half. Build a break-glass account that stays inert until used, expires fast, and gets reviewed every time, and the prevention is solid. But the entire point of break-glass is that someone breaks it in an emergency. If no alarm fires when they do, you have built a careful emergency exit…
Grant someone read access to a database and you have made a decision about a system. You have said nothing about the data inside it. The same read permission covers the table of marketing email addresses and the table of social security numbers sitting one schema over, because the permission is attached to the database, and the database does not care what it holds. Your access control is guarding…
The problem that started this was not philosophical. We were trying to write down our SDLC. Not the aspirational one on a Confluence page, the real one, the one an auditor could follow and a team could actually live inside. Every draft failed the same way. Make it specific enough to collect evidence against, and it boxed teams into one way of working that half of them did not use. Leave it loose…
A user calls GET /invoices/4471 and gets back an invoice. The gateway in front of the service did its job: it checked that the request carried a valid token, that the user was authenticated, and that this user is allowed to call the invoices endpoint. Every check passed. The only problem is that invoice 4471 belongs to a different customer, and the user just read it by changing a number in the…
A VPN does one thing well and one thing badly. It authenticates you to a network, which is the thing it does well. Then it trusts you on all of that network, which is the thing it does badly. Once you are connected, you can route to every system on the subnet, and the only thing standing between you and any given box is whatever authentication that box happens to enforce on its own. The network…
Zero trust gets sold two wrong ways at once. As a posture, something you either have or do not, usually claimed on a slide. And as a product, something a vendor will sell you that makes you “zero trust” the moment it is deployed. It is neither. Zero trust is a set of controls that pay off in an order, and the useful question is which part you should build next. It Is Not a Product The…
You can prove exactly who is making a request and still have no idea what they are making it from. A user signs in with a phishing-resistant passkey, the strongest factor you can give them, and the login is genuinely theirs. It tells you nothing about whether the laptop behind that login is a managed, encrypted, patched company machine or a personal one riddled with malware, or a…
A phishing page can copy your login screen perfectly. The logo, the fonts, a URL one character off from the real one. You type your password, you approve the push notification on your phone, and the attacker is in, because everything you did on the fake page worked exactly as well there as it would have on the real one. The second factor did not help. It just rode along with the first one into the…
The pitch for role-based access control is clean and convincing. Define what a back-end engineer gets once, attach it to a role, and every back-end engineer inherits it. No more negotiating access per hire, no more guessing what the last person in this job had. You model the org once and access follows the model. Then reality adds an exception, and another, and the model starts to fracture. The…
Single sign-on solved logging in. One identity provider, one handshake, and every app trusts the result. Logging out never got the same treatment, and the reason is structural: there was never just one session to end. When you log into an app through SSO, the identity provider proves who you are once, and then the app sets up its own session and stops asking. Killing your account at the IdP does…
When a new hire cannot log in on day one, you hear about it within the hour. They file a ticket, their manager escalates, someone fixes it fast. When a departed contractor’s account still works three months after they left, you hear about it never, until the day it is used to get into something it should not. Both are failures of the same lifecycle. Only one of them complains. That asymmetry…
I almost did not write this one. In my head, SSO is settled: table stakes, the thing every company past a certain size obviously has, and a whole post arguing for it felt redundant. Two things changed my mind. A lot of companies are not as consolidated as they think they are. And the ones that are usually bought SSO for the convenience and stopped there, short of the part that actually matters.…
At 3am the database is down, the on-call engineer needs in, and the system that normally grants access is part of what is broken. This is the moment every “no standing access” design has to answer, and the answer is break-glass: a pre-arranged emergency path in. Get it right and it is a controlled exception that auditors respect. Get it wrong and it is a standing backdoor with a…
Every plan to get the secrets out of your workloads runs into the same wall. To pull a credential from the vault, the workload has to authenticate to the vault, which means it needs a credential to do that. You did not remove the secret. You moved it down one level, and there is always another level beneath it. This is the secret-zero problem, and it has a name borrowed from an old joke about what…
Count the identities in your company. Not the people, the identities. Every employee, plus every service account, CI runner, deploy key, bot, integration token, and now every AI agent. CyberArk’s 2025 research puts the ratio of machine identities to humans at more than 80 to 1 , and other firms put it higher. The exact number varies by who is counting; the shape does not. The overwhelming…
“No standing access” is the goal everyone agrees on and almost nobody can explain the mechanics of. If the on-call engineer does not have permanent production access, how do they get in at 3am when the database is down? If the deploy pipeline does not hold long-lived cloud keys, what does it present? The honest answer is that “no standing access” is something you build, and…
This is the map for the identity series: one argument about building identity security for the company you actually have, broken into posts you can read in any order. It starts from a single hub and branches into six threads. It is a graph more than a line, because the threads cross. Phishing-resistant MFA leans on single sign-on. Device trust comes back around under BYOD. Continuous access ties…
The pitch for workload identity is clean. Your service proves who it is with a credential the platform issues and rotates, instead of a long-lived secret you stored, shipped, and hope nobody leaked. No API key in an environment variable. No password in a vault that something still has to read. Just an identity the infrastructure vouches for, valid for minutes, scoped to one job. It is the right…
A developer has permission to assume one role. That role can start an EC2 instance. The instance comes up with an instance profile attached, which is another role. That second role can read a specific S3 bucket, write to a queue, and call an internal deploy API. The grant on the developer’s account says one thing: assume this role. What the developer can actually reach is everything at the…
I started writing a different post. It was going to lay out the perfect IAM stack, configured the way I would do it with no constraints: the identity provider, the provisioning pipeline, the policy engine, just-in-time access to everything. I got three paragraphs in and deleted them, because the premise was broken. There is no unlimited IAM budget. There is no greenfield. And “perfect”…
A simple question that most engineering organizations can’t answer: which code in our repos was written by AI, which was written by humans, and who is accountable for each? It sounds like the kind of thing you’d just know. In practice, almost no one knows. AI tooling is rolling out across teams faster than the governance stack can keep up. Each tool has different attribution behavior:…
The protocol wars everyone braced for in 2025 are over, and they ended in a way most of the predictions missed. Nobody won outright. The protocols sorted themselves by the job they do, and then most of them moved in under the same roof. In MCP Earns Its Keep at the Boundary I argued that MCP follows the same arc as every abstraction layer of the last twenty years: it earns its keep at the…
The shape that made AI useful for access reviews fits a lot of other compliance work too. The access-reviews post made a narrow argument: a manager who hasn’t touched a kubectl command in two years cannot review access better than telemetry can, and an AI agent can take the volume and the evidence-packaging while a human signs the decision and stays accountable. That pattern is not specific…
Every quarter, an email arrives. “Please review the access for your team.” A manager who hasn’t touched a kubectl command in two years clicks Approve on a list of permissions they don’t understand for people whose work they only partially see. Compliance gets its checkbox. Nothing actually changed. The system that’s supposed to catch over-permissioning produced no…
The articles arguing that MCP is going away in favor of direct API calls with workload identity are half right. The half that’s right is the half that has been right about every abstraction layer for the last twenty years: inside the trust boundary you control end-to-end, the abstraction usually costs more than it returns. The half that’s wrong is the half that treats MCP like it lives…
The MCP authorization spec was written for an AI client with a browser and a user who can click through consent. When the agent runs headless, that whole flow is gone, and the practical reality has been substituted at every production deployment I have looked at. The current MCP authorization spec, revision 2025-11-25 , mandates OAuth 2.1 with PKCE, RFC 9728 Protected Resource Metadata for…
An AI agent is not a user, and permissioning one like a user is the most expensive shortcut in the AI rollout. A user is a person with judgment, a slow reaction time, and a strong incentive not to do anything that gets them fired. The permission model you grant a user assumes all three. A user with database write access does not, in practice, drop tables, because their hand stalls at the keyboard…
An AI agent’s identity is a non-human identity, and ninety percent of what governs it is decades-old hygiene. The other ten percent is where most agent rollouts fail. I came into this post not knowing whether to call agent identities a genuinely new class of non-human identity or just service accounts that improvise. After looking at what is published and what is failing in production, the…
In the last post I argued that the value stream needs an owner. Security cannot be that owner. That post made the case that work flows horizontally across a company while the org chart runs vertically, and that the horizontal path, the value stream, belongs to no one. Security gets dragged across that stream constantly, because it is the function least able to refuse the coordination nobody else…
Your company has an org chart. It is a precise, carefully negotiated map of who owns what. It is not a map of how anything actually gets done. Pull it up and you’ll see clean vertical columns. Product and Engineering build the product and run the infrastructure it lives on. IT runs the internal systems the company itself depends on to operate, which is a different job from shipping the…
The first security hire at a company is asked to be seven specialists at once. Read the job description for a head of security role, especially at a company making its first dedicated security hire, and you’ll find a wish list that spans the entire field. Governance. Risk and compliance. Third-party risk management. Cloud security. Identity and access management. Product security. Security…
Open any LinkedIn feed in 2026 and you’ll find someone insisting that AI agents will rm -rf production any minute now. The panic case sells. The calibrated case doesn’t. But after twenty-plus years of running and advising on security programs, the destructive-action problem isn’t new. We’ve been protecting production from junior engineers, broken CI pipelines, and…
.env was already a compromise. AI agents make it a bad one. For human developers, a .env file is a small, stable risk. It lives on one machine, it’s gitignored, the developer who wrote it is the only one reading it, and most of the time nothing ever goes wrong. The control isn’t great, but the blast radius is small. AI agents change that calculation. Now the file isn’t being read…
AI just hits different. A lot of us in security have drifted further and further from our deep technical roots. For many of my peers, and for me, that meant writing real code early in our careers, then watching it become something other people did while we became “the security person who used to write code.” I’ve lost count of practitioners who have told me some version of…
The first time I opened the BlackDuck API documentation, I thought building a vulnerability collector would take a couple weeks. Fetch some projects, grab their vulnerabilities, write them to a database. How hard could it be? Famous last words. The initial build did take a couple weeks. But then came the months of discovering that every assumption I’d made was slightly wrong: undocumented…
A CISO once said to me, “Vulnerability management is easy. It’s find, then fix.” I understand the appeal of that framing. It’s clean, linear, and fits on a slide. It’s also so reductive that it obscures everything that makes vulnerability management (and security work more broadly) genuinely hard. Between “find” and “fix” is an enormous, messy…
I recently picked up Team of Teams by General Stanley McChrystal, and one concept from the book has been rattling around in my head ever since — the distinction between complicated and complex. It’s one of those frameworks that, once you see it, changes how you evaluate almost everything. It’s reshaped how I think about engineering, security, and especially the current moment…