DEV Community

Ivan Rossouw
Ivan Rossouw

Posted on AI-assisted

Least Privilege Is a Matrix, Not a Label

A green path can still be over-privileged

A successful deployment login feels reassuring. The credential was accepted, the target was reachable, and the pipeline can continue. Unfortunately, that result proves only one thing: this identity can reach this target.

It does not prove that the same identity cannot reach every other target.

That distinction became concrete while tightening a deployment pipeline that had relied on one broadly shared credential. The replacement used a dedicated identity for each deployable target and each environment. Names and configuration alone did not prove least privilege; the relationships still needed evidence.

The focused lesson is simple: least privilege is a matrix, not a label.

Authorization has negative space

Most functional tests naturally follow the allowed path. Give the pipeline a credential, connect to the intended target, and expect success. That is necessary, but it tests authentication and reachability more than isolation.

A boundary also has negative space: the operations that must not work.

If identity A is intended for target A, then A reaching A is only the diagonal of the matrix. A reaching B or C would reveal excess privilege. A useful authorization test therefore has two expectations:

  • required identity-to-target edges must succeed;
  • every forbidden cross-target edge must be refused.

For three identities and three targets, that means three allowed checks and six denied checks. The denials are not incidental failures. They are part of the security contract.

Put the proof before the first write

Where the test runs matters as much as what it tests.

In a deployment, discovering a bad credential after taking an application offline or starting a content sync is too late. The safer order is to validate the complete configuration, perform non-mutating probes for all intended targets, and begin the write stage only after the entire preflight has passed.

This creates an all-or-nothing gate for known authorization problems. A missing identity, a mismatched target mapping, or a failed read probe stops the operation before any remote write is issued.

The preflight is not a transaction with the later deployment. Permissions can change between probe and write, and a read check does not prove every write permission. Its value is narrower and still useful: the pipeline refuses to create a partial deployment from a configuration already known to be invalid.

Test the wiring, not only the guard

A well-tested helper can coexist with a broken workflow. A secret may be bound to the wrong variable, two targets may share a credential, or an old fallback may silently restore the broad account.

That is why the focused tests should exercise the real workflow block, not only isolated validation functions.

The tests behind this lesson use fake credentials and a mocked deployment command. They check that each operation receives the matching identity, that no shared fallback is used, and that a failed preflight produces zero write calls. They also cover missing values, ambiguous identities, wrong target mappings, and failures at each probe position.

This style of test keeps the security policy close to the executable orchestration. It catches wiring regressions that a clean unit test around a helper cannot see.

Original illustrative example

The following is original, generalized pseudocode rather than production code. It shows the ordering and the two-sided assertion:

$identities = Get-DedicatedIdentities
$targets = Get-DeploymentTargets

foreach ($identity in $identities) {
    foreach ($target in $targets) {
        $shouldAllow = $identity.TargetKey -eq $target.Key
        $didAllow = Invoke-ReadOnlyProbe $identity $target

        if ($didAllow -ne $shouldAllow) {
            throw 'Authorization matrix mismatch; no write attempted.'
        }
    }
}

Invoke-DeploymentWrites
Enter fullscreen mode Exit fullscreen mode

Production code needs careful error classification, redaction, timeouts, and retry policy. The important shape is that every expected allow and deny result is checked before control can reach the write stage.

Fail closed without leaking context

Failure messages are another boundary. A preflight should identify the target role and the kind of mismatch clearly enough to diagnose, without echoing credentials or sensitive connection details.

It should distinguish absence from incorrect scope because those failures require different fixes. Treating an absent value as “nothing to check” bypasses the gate. Avoid a compatibility fallback too: it may make deployment green while quietly defeating isolation.

Be precise about what the matrix proves

A passing matrix is evidence about the endpoint, identities, targets, and moment that were probed. It does not prove every filesystem rule, every write operation, secret rotation, future configuration, or every network route.

Mocked workflow tests prove binding, ordering, failure handling, and the absence of write calls in the test harness. They do not reproduce the hosted runner or remote service.

Those limits should be stated, not hidden. A bounded control is trustworthy because its claim matches its evidence.

The operational trade-off

Dedicated identities create real work. There are more accounts and secrets to provision, store, rotate, revoke, and audit. The matrix grows quadratically as targets are added. Read probes add latency and can introduce transient failures before a deployment.

In return, the boundary becomes explicit and executable. A compromised credential has a smaller intended blast radius. A mapping error becomes visible before mutation. Removing a shared fallback also prevents convenience from silently restoring broad access.

That trade is often worthwhile for deployment paths because they combine sensitive credentials with high-impact writes.

A practical review checklist

Before calling a deployment identity least privilege, ask:

  1. Does every target have a deliberately scoped identity?
  2. Does each required edge succeed?
  3. Does every forbidden cross-target edge fail?
  4. Are all probes complete before the first write?
  5. Does any missing value or mismatch fail closed?
  6. Can an old shared credential still appear as a fallback?
  7. Do tests execute the real workflow wiring?
  8. Are errors useful without exposing sensitive values?

The happy path tells you the deployment can run. The deny paths tell you whether the boundary is real.

Top comments (0)