Skip to content
arrow_backBack to Insights
Essay· 8 min read

Three Ways to Screw Up Identity Engineering

Identity engineering has real failure modes. Teams that adopt it badly end up worse than teams that never adopted it at all. This article names the three most common ways it goes wrong and the antidote for each.

Identity engineering can fail. Not in theory, in practice, on real teams, with real consequences. And the failures are predictable enough to name.

We have spent the last several articles making the case that software needs an identity layer. That declaring what a system is, not just what it does, is the upstream move that makes agentic development reliable. We believe that. But we also believe that any practice worth adopting is worth being honest about. And the honest truth is that teams adopting identity engineering badly end up worse off than teams that never adopted it at all.

This article names the three most common failure modes. Not to scare anyone off, but because naming failures is how a practice matures. Every engineering discipline went through this. Agile has its failure literature. DevOps has its failure literature. Identity engineering needs one too.

Failure mode 1: The specification straitjacket

The instinct is understandable. If declaring identity is good, declaring more identity must be better. So teams write exhaustive specifications. Every behavior, every edge case, every possible interaction, all pinned down in advance. The identity layer becomes a 400-page requirements document with a new name.

This kills exactly the thing identity engineering is supposed to enable.

Martin Fowler called this out years ago when Model-Driven Architecture (MDA) was the version of this idea making the rounds. His assessment was blunt: MDA was the "Night of the Living CASE Tools", unable to deliver a better programming experience than the alternatives it was trying to replace. The model was supposed to be the source of truth. In practice, the model became a straitjacket that constrained developers without giving them anything useful in return.

Johan den Haan catalogued eight specific reasons model-driven engineering fails, and three of them map directly to over-specification: teams targeted only code generation instead of the full development lifecycle, nobody tested whether the models themselves were correct, and there was no support for evolving models as requirements changed. The model became a static artifact. Reality moved. The model didn't.

Research backs this up at a more fundamental level. A study comparing approaches at Accenture and Steria found that detailed up-front specifications constrained creativity, while an iterative approach stimulated it. This is not surprising if you think about it. When every decision is pre-made, there is nothing left for engineers (or agents) to figure out. The specification becomes a script to follow, not a boundary to work within.

The antidote is simple in principle: declare boundaries, not implementations. An identity layer should say "this service owns payment processing, guarantees idempotency, and never stores card numbers." It should not say "this service accepts a PaymentRequest object with fields amount (decimal, 2 places), currency (ISO 4217), and merchant_id (UUID v4), validates each field in sequence, then calls the gateway adapter." The first version is a boundary that leaves room for engineering judgment. The second is pseudocode with extra steps.

If your identity declarations read like implementation specs, you have built a straitjacket.

Failure mode 2: Declaration sprawl

This one creeps up on you. You start with a handful of identity declarations for your core services. Each one is clean, readable, useful. Then you add declarations for shared libraries. Then for configuration layers. Then for environments. Then for the relationships between all of them.

Before long, maintaining the identity layer is a job.

This is the same trap that Kubernetes manifests fell into. For N microservices, each with roughly 5 resource types across 3 environments, you end up managing 15N YAML files, most of which are copy-pasted from each other with minor variations. The manifests were supposed to make infrastructure declarative and manageable. At scale, they made it declarative and unmanageable.

The economics are punishing. Technical documentation production and maintenance runs roughly 10% of total product design cost. That is the cost of maintaining documentation that humans read. Identity declarations that machines and agents consume need to be even more precise, which means they cost more to maintain correctly. And if you let them drift, you have something worse than no declarations at all: you have declarations that lie.

This connects to a broader cost pattern. Software maintenance already consumes 50-80% of total cost of ownership. Adding a declaration layer that itself needs maintenance can push that number even higher. You set out to reduce maintenance burden by giving agents better context. You ended up adding a new maintenance surface.

The antidote is aggressive scoping. Not everything needs an identity declaration. Shared utility libraries that do string formatting do not need a declaration about their purpose and boundaries. The identity layer should cover the parts of your system where misunderstanding causes real damage: service boundaries, trust relationships, data ownership, behavioral guarantees. If a declaration does not prevent a specific class of mistake, it is overhead.

Healthy identity layers are thin. They cover high-stakes boundaries and leave everything else to convention and code structure. The moment maintaining declarations feels like a full-time job, you have sprawl.

Failure mode 3: The compliance trap

This is the most dangerous failure mode because it looks like success.

The team has identity declarations. They are reviewed. They are versioned. Changes go through an approval process. There are dashboards. There are audits. Everything is governed.

And nothing ships.

Current governance models are rife with toil, scaling linearly with the volume of change. Every new service needs a declaration review. Every declaration change needs an approval. Every approval needs a meeting. The governance process that was supposed to provide safety becomes the primary obstacle to getting work done.

The numbers tell the story. Engineers gradually spend less time on actual development and more time in meetings, filing tickets, and waiting for approvals. When identity declarations become part of the process tax, you have turned a technical tool into a bureaucratic checkpoint.

Research on organizational bureaucracy confirms the mechanism. Formalized workflows can be either enabling or coercive. Coercive procedures undermine commitment and stifle innovation. Enabling procedures give people structure while preserving autonomy. Coercive procedures give people rules while removing judgment. If your identity governance requires approval for changes that an engineer could evaluate independently, you have built a coercive process.

The talent cost is real. Top engineers are attracted to places where they can move fast. If they sense bureaucracy, they leave. Your best people are exactly the ones with the most options. They will not stick around to fill out declaration change request forms.

The antidote is separating governance from gatekeeping. Declarations should be versioned (that is just good practice). Changes should be auditable (so you can understand what happened after the fact). But the approval process should match the risk level of the change. Updating a service's description is not the same as changing its trust boundaries. Treat them differently.

The goal of governance is accountability, not control. If your governance process catches problems, it is working. If it mostly catches people trying to ship, it is theater.

What healthy identity engineering looks like

Across all three failure modes, the pattern is the same: a good idea taken past its useful range.

Healthy identity engineering has a few consistent properties.

Declarations are short. A service identity should fit on one screen. If it doesn't, you are either declaring too much or the service does too much. Both are problems worth fixing.

The identity layer evolves. Declarations are not carved in stone. They change as the system changes. The key is that changes are intentional, not accidental. You should know when a service's identity shifts, not discover it six months later when something breaks.

Maintenance cost is near zero for stable services. If a service has not changed, its declaration should not need attention. If stable declarations require regular maintenance, your format is too fragile or too coupled to implementation details.

Governance is proportional. Low-risk changes (clarifications, typo fixes, documentation improvements) should flow through with minimal friction. High-risk changes (new trust relationships, boundary shifts, guarantee modifications) should get scrutiny. One process for everything is always wrong.

Engineers still make decisions. The identity layer provides context and boundaries. It does not make engineering decisions. If an agent or an engineer cannot exercise judgment within the boundaries of a declaration, the declaration is too tight.

Monday morning

Here are five signs that your identity layer is becoming a problem rather than a solution.

Declaration reviews are a bottleneck. Changes queue up waiting for approval. Engineers start batching unrelated changes to minimize the number of reviews. This is the compliance trap in formation.

You have declarations for things nobody reads. Scroll through your identity files. If declarations exist that no agent consumes and no human references, they are dead weight. Delete them.

Declarations duplicate information that lives elsewhere. If your identity declaration restates what the API schema already expresses, you are maintaining two sources of truth. That is not identity engineering. That is documentation with extra steps.

Teams resist updating declarations. When engineers treat declaration updates as a chore they avoid, the declarations will drift from reality. Drifted declarations are worse than absent ones because they actively mislead.

New services take longer to set up than before. If adding a service used to take a day and now takes three because of the identity layer, you have added friction without proportional value. Measure this. It is the clearest signal.

Identity engineering is worth doing. It solves a real problem that gets worse as agents become more capable and more autonomous. But like every practice before it, it can be done badly. Naming the failure modes is the first step toward avoiding them.


The identity layer should make systems clearer, not slower. We are building tooling that keeps declarations thin, testable, and worth maintaining.

terminal

The ribo.dev Team

Building the identity layer for software.

We use cookies to understand how you use ribo.dev and improve your experience.

Learn more in our Cookie Policy