In a hybrid workforce, agents are not anonymous executors — they are identity principals. Forge’s Non-Human Identity (NHI) system gives every agent a verifiable credential that the governance pipeline checks at dispatch time. This is the foundation for answering “who is this agent, and should it be allowed to act?”
The NHI system is designed around a pluggable provider abstraction. The governance pipeline does not care how credentials are issued or validated — it delegates that to an NhiProvider implementation. Today, Forge ships with a local provider that stores credentials on the agent definition document. When an enterprise identity backend (such as Aembit) is integrated, the pipeline stays the same; only the provider implementation changes.
The NhiProvider Interface
The NHI architecture is built on a provider abstraction that decouples credential management from governance enforcement. Any backend that can issue and validate agent credentials can implement this interface.
The core identity type stored on each agent:
interface NonHumanIdentity {
nhiId: string; // Unique credential identifier
agentId: string; // Agent this credential belongs to
issuedAt: number; // Unix timestamp of credential issuance
expiresAt: number; // Unix timestamp of credential expiry
scopes: string[]; // Permitted action scopes
issuer: string; // Identity provider that issued this credential
}
Source: convex/trust_fabric/identity/types.ts
The NhiProvider contract requires three capabilities:
| Capability | Description |
|---|
| Issue | Create a new NHI credential for an agent, setting expiry and scopes |
| Validate | Check that a credential is current, unexpired, and issued by a trusted source |
| Revoke | Invalidate a credential before its natural expiry |
Providers are plugged into the governance pipeline through the bindings layer (convex/trust_fabric/bindings.ts). The pipeline fetches the agent document, extracts NHI fields, and passes them to the identity gate for validation.
LocalNhiProvider
The default implementation stores NHI credentials directly on the agentDefinitions table as optional fields:
| Field | Type | Description |
|---|
nhiId | string | Unique credential identifier |
nhiExpiresAt | number | Unix timestamp when the credential expires |
Source: convex/schema/agent_definitions.ts
This approach is intentionally simple. Credentials are set when an agent definition is created or updated, and the identity gate reads them directly from the agent document at dispatch time. No external service calls are required.
For testing, a MockNhiProvider can be used to simulate credential issuance and expiry without persisting to the database. This is useful for unit testing gate behavior with expired or missing credentials.
The local provider does not currently store scopes or issuer on the agent definition document. These fields exist on the NonHumanIdentity type for forward compatibility with enterprise providers that issue scoped, attributed credentials. The identity gate does not enforce scopes today — see the Scope Gate section below.
Identity Gate
Gate 2 in the dispatch pipeline validates the agent’s NHI credential. It runs early in the sequence — after gateway health and agent status, before resource and policy checks.
The gate implements graceful degradation: agents without NHI credentials pass through. This is a deliberate design choice that allows the NHI system to be adopted incrementally. As agents are enrolled with credentials, the gate begins enforcing expiry for those agents without requiring a migration of the entire fleet.
| Scenario | Outcome | Error Code |
|---|
No nhiId on agent | Pass | — |
Valid nhiId, nhiExpiresAt in the future | Pass | — |
Valid nhiId, nhiExpiresAt in the past or missing | Block | nhi_expired |
Source: convex/trust_fabric/gates/gate_2_identity.ts
// Simplified gate logic
function identityGate(ctx: GateContext): SafetyGateResult {
const nhiId = ctx.agentDoc.nhiId;
const nhiExpiresAt = ctx.agentDoc.nhiExpiresAt;
// No NHI configured -- pass (graceful degradation)
if (!nhiId) {
return { pass: true };
}
// NHI exists -- validate expiry
if (!nhiExpiresAt || nhiExpiresAt <= Date.now()) {
return {
pass: false,
errorCode: "nhi_expired",
retryable: false,
message: `Agent NHI credential expired`,
};
}
return { pass: true };
}
An nhi_expired block is not retryable. The credential must be reissued or the agent definition updated with a new expiry before dispatch will succeed. In Forge Console, expired NHI credentials surface as attention items on the agent detail page.
Scope Gate
Gate 7 in the dispatch pipeline is reserved for NHI scope enforcement — validating that the requested action falls within the agent’s credential scopes. This gate exists as a structural placeholder in the pipeline.
Current state: The scope gate is a pass-through stub. It always returns { pass: true }.
// convex/trust_fabric/gates/gate_7_scope.ts
function scopeGate(): SafetyGateResult {
return { pass: true };
}
Scope enforcement is currently handled through the entitlements system and role-derived authority bounds rather than NHI credential scopes. When Aembit or another enterprise identity provider is integrated, this gate will be activated to validate credential scopes against the requested action, creating a second layer of scope enforcement alongside role-based authority.
The scope gate is intentionally separated from the identity gate (Gate 2). Identity answers “is this agent who it claims to be?” Scope answers “is this agent allowed to do this specific thing?” Keeping them distinct allows each to evolve independently.
Credential Broker
When the governance pipeline produces an allow decision, the agent’s NHI metadata is packaged into a governance packet that travels with the execution request. This packet is part of the 8-field traceability record (STD-03.3) that every agent action produces:
governancePacket: {
agentId: string;
nhiId?: string; // NHI credential ID, when present
autonomyRung: string; // Agent's autonomy level
owningTeam: string; // Team responsible for this agent
riskTier: string; // Agent's risk classification
fiduciaryFlag: boolean; // Whether agent is designated for elevated duty-of-care data handling
}
Source: convex/trust_fabric/traceability.ts
The nhiId in the governance packet serves two purposes:
- Traceability — Every action an agent takes is linked to the specific credential that was valid at dispatch time. If a credential is later revoked, the audit trail shows exactly which actions were authorized under it.
- Downstream authentication — When enterprise NHI providers are integrated, the credential ID can be exchanged for a short-lived access token that the execution runtime uses to authenticate with external services.
Today, the credential broker is a data-packaging step — it reads NHI fields from the agent document and includes them in the governance packet. There is no live token exchange or credential refresh during execution.
Registry Reconciliation
Every 6 hours, a scheduled reconciliation job (convex/trust_fabric/identity/reconciliation.ts) cross-references all active agent definitions against the agent registry. This catches two categories of identity problems:
| Status | Meaning | Consequence |
|---|
| current | Registry entry exists and was checked within 6 hours | Normal operation |
| stale | Registry entry exists but has not been reconciled recently | Dispatch allowed with warning logged |
| missing | No registry entry at all | Dispatch blocked with registry_missing error |
Agents with no registry entry are treated as shadow IT — they should not be dispatching work. The governance pipeline checks registry status before evaluating any other gates, and a missing entry produces an immediate block with a P0 notification to operators.
Registry reconciliation runs on a 6-hour cycle via crons.ts. There is a window between an agent being deregistered and the next reconciliation run where the stale agent could still dispatch. The governance pipeline’s pre-dispatch registry check mitigates this by verifying registry presence at dispatch time, not just at reconciliation time.
Enterprise Integration Path
The NHI architecture is designed for enterprise identity provider integration. The target integration is Aembit, a workload identity platform purpose-built for non-human identities.
What exists today:
NonHumanIdentity type with fields for enterprise credential metadata (scopes, issuer)
- Identity gate (Gate 2) validating credential expiry at dispatch time
- Scope gate (Gate 7) as a structural placeholder for scope enforcement
- Governance packet carrying
nhiId through the execution chain
- Registry reconciliation detecting unregistered agents
What Aembit integration will add:
| Capability | Current | With Aembit |
|---|
| Credential issuance | Manual, stored on agent definition | Automated, issued by Aembit identity broker |
| Credential validation | Local expiry check | Live validation against Aembit’s identity service |
| Scope enforcement | Pass-through stub | Real-time scope validation against Aembit credential scopes |
| Credential rotation | Manual update of nhiExpiresAt | Automatic rotation with configurable TTL |
| Revocation | Delete nhiId from agent definition | Instant revocation via Aembit, reflected at next dispatch |
| Audit | nhiId in governance packet | Full credential lifecycle audit trail in Aembit + Forge |
The integration requires procuring an Aembit account and implementing an AembitNhiProvider that replaces the LocalNhiProvider. The governance pipeline, gate sequence, and traceability system require no changes — they already consume the NonHumanIdentity interface.
Until Aembit is procured, the local provider remains fully functional for credential management. The graceful degradation in Gate 2 means organizations can begin enrolling agents with NHI credentials today and gain expiry enforcement immediately, with the path to enterprise-grade identity management clear and non-breaking.
Next Steps