Agent identity architecture: test the bindings, not the IDs
A tool request containing user_id, agent_id and run_id is not an identity architecture. It is a request containing three strings. The implementation question is which component established each value, which component ma
A tool request containing user_id, agent_id and run_id is not an identity architecture. It is a request containing three strings.
The implementation question is which component established each value, which component may change it, and what prevents an authenticated caller from substituting a different value. This walkthrough proposes a binding model for a fictional invoice-review workflow. It is not a deployable authentication service or a new identity standard.
Separate identifiers by what they establish
The human initiator is the person who starts the task. The logical agent principal identifies the application actor to which policy applies. The runtime workload is the executing software. A delegation grant describes permitted authority for a task on another party's behalf.
A run ID correlates execution. It is not a permission credential. A model name describes a dependency. It is not the identity of the business actor using that dependency.
SPIFFE explicitly allows a workload to comprise several instances. Decide whether your workload identity represents an isolated agent deployment, a worker pool or another boundary. Do not assume its granularity matches your application principal.
The binding model separates the source of identity from the source of authority.
For the example, Mariam belongs to tenant Cedar and requests a draft explanation for invoice INV-204. The invoice-reviewer agent can read that invoice. It cannot change supplier bank details. Every identifier below is fictional.
Put the trusted context outside the tool arguments
At ingress, the application validates the user's authentication and resolves tenant membership from trusted account data. It selects a registered agent principal using an authorised routing decision. A client-provided display name is not an authoritative principal mapping.
A protected assignment record connects that principal, tenant, authority mode, permitted invoice and execution policy. The queue carries a reference to the assignment. The worker retrieves the protected record through an authenticated path.
This separation matters because a model can propose invoice_id=INV-990. It must not be able to revise the trusted assignment to make INV-990 permitted. Tool arguments describe a request; they do not authorise the request.
Here is an illustrative record shape, not a credential format:
{
"assignment_id": "assignment-204",
"tenant_id": "cedar",
"agent_principal": "invoice-reviewer",
"initiator": "user:mariam",
"authority_mode": "user-delegated",
"grant_ref": "grant-204",
"permitted_resource": "invoice:INV-204",
"operation": "read",
"environment": "production"
}
The schema makes relationships visible. It does not make the record trustworthy. Storage access, integrity, issuance, expiry and retrieval checks belong to the implementation. Copying this JSON into a prompt would discard the boundary it is intended to describe.
Authenticate the worker, then bind the assignment
A credential broker first authenticates the workload using the deployment's supported mechanism. It then checks whether that workload may execute the named agent in the named environment and use the referenced assignment.
SPIRE demonstrates one approach to issuing workload identities based on configured attestation conditions. It does not automatically define your application-level agent or tenant mapping.
The broker must reject a valid staging identity when the assignment requires production. It must reject a workload that is not authorised for the agent principal. It must reject a grant belonging to another assignment or tenant, even if every individual identifier resolves successfully.
These are relational checks. Looking up four existing records and declaring success would miss the point.
The diagram shows one principal using multiple authenticated runtime instances with distinct task grants. The broker must enforce the permitted relationships.
The downstream invoice API also checks the requested resource and operation. A successful broker decision must not become permission to read arbitrary invoice identifiers. The exact division of checks depends on whether the destination consumes a constrained token, performs grant lookup, or uses another documented authorisation mechanism.
Treat shared workers as a trust decision
If invoice review and supplier management run in the same process with access to both credentials, separate agent labels do not isolate them. A compromised process may be able to exercise the authority of both.
You can separate the deployments, strengthen isolation within the runtime, or design a broker that releases narrowly constrained credentials only for independently authenticated assignments. Each option adds operational work. Each requires a threat model for credential theft and context substitution.
Per-run credentials are not automatically necessary, and they are not automatically sufficient. A fresh credential with broad permissions still has broad permissions. A short lifetime limits a time window; it does not establish the correct tenant or purpose.
Google Cloud's identity delegation architecture provides a concrete provider example of separate ingress, runtime and delegated contexts. Its mechanisms should not be treated as guarantees supplied by any generic agent framework.
Keep service authority explicit
For a scheduled reconciliation, the initiator may be an approved scheduler rather than a human. The task can use an explicit service mandate with its own permitted resources.
The OAuth client credentials grant covers confidential clients accessing their own resources or previously arranged access. Do not disguise this mode as a user's continuing delegation.
In the assignment service, use distinct authority modes and prohibit silent fallback between them. A missing user grant should not cause a broker to issue a broad service token. If the product supports a separately authorised service workflow, create and review that workflow as such.
Test substitutions at the real boundary
For this example, submit an otherwise valid assignment with an invoice from another tenant. Expected result: deny before disclosure. Submit a different agent principal using the same worker credential. Expected result: deny unless an independently trusted assignment and mapping authorise that principal.
Try a valid staging workload against the production assignment. Expected result: deny. Replace the original worker with an authorised production replica while retaining a valid assignment. Expected result: allow the permitted invoice read, subject to current resource policy.
The paired example isolates the runtime-binding check. It is a proposed integration test, not proof that a particular runtime supplies the control.
Also test where the attacker supplies the substitution. A unit test against a hand-built trusted context will miss an ingress path that accepts tenant_id directly from a model-generated argument. Exercise the path that constructs the context, not only the final comparison.
Keep secrets out of the evidence. Record authenticated principal references, the resolved assignment, policy outcome and protected resource reference. The audit trail guide covers connecting those decisions to actual outcomes.
NIST's agent identity design tenets offer current design context, not a conformance test for this proposal. The implementation is ready for review when you can show where a false relationship is refused. A nicely named agent_id field is merely ready for serialisation.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.

