Skip to main content

Identities (NHI)

Quick example​

# Register a new NHI
curl "$TRINITITE_BASE/v1/identities" \
-H "Authorization: Bearer $TRINITITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "billing-assistant",
"tier": "T2",
"workload_origin": "k8s://billing/refund-bot",
"guardian": "stripe-refund-guardian"
}'

See NHI Governance for the architecture.


Overview​

A Non-Human Identity (NHI) is a first-class identity for an autonomous workload — an AI agent, a service principal, a federated cloud identity. NHIs carry a privilege tier and a registered workload origin, and are the unit of identity that the LLM Proxy, MCP Gateway, and CLI Firewall authorize against.

This page covers the three NHI surfaces:

  1. NHI lifecycle — /v1/proxy/nhi/*. CRUD, JIT tokens, tier transitions, lifecycle bindings, cascade revocation, economic sessions, IMDS shield, orchestration config.
  2. NHI Federation — /v1/nhi/federation/*. External identity providers; mirrored identities; sync; events; posture.
  3. NHI ↔ Guardian binding — /v1/nhi-guardian/*. Which Guardian governs which NHI; which NHIs are ungoverned; concentration; policy impact; tier attestation.

For analytics rollups across these dimensions, see the Analytics API.

Authentication: Authorization: Bearer <session_token | api_key> with the relevant nhi:* permission.


NHI lifecycle (/v1/proxy/nhi)​

Identities​

MethodPathPermission
POST/v1/proxy/nhi/identitiesnhi:update
GET/v1/proxy/nhi/identitiesnhi:read
GET/v1/proxy/nhi/identities/{id}nhi:read
DELETE/v1/proxy/nhi/identities/{id}nhi:update

Create​

{
"label": "ci-runner-prod",
"principal_user_id": "usr_01JF8RUS1A2B3C4D5E6F7G8H9I",
"privilege_tier": 2,
"workload_id": "k8s://prod/agent-pool/ci-runner",
"workload_attestation_hash": "sha256:e3b0c44...",
"max_spawn_depth": 1,
"parent_nhi_id": null
}
FieldTypeRequiredDescription
labelstringYes1–255 chars
principal_user_idstringNoHuman principal responsible for this agent. Auto-provisions a lifecycle binding
privilege_tierintegerNo1–3. Default 1
workload_idstringNoLogical grouping
workload_attestation_hashstringNoHash of the workload definition
max_spawn_depthintegerNo0–3. Limits how deep child NHIs may chain
parent_nhi_idstringNoParent NHI for child agents

Returns 201 Created with the NHI object.

Privilege tiers​

TierTypical access
1Read-only by default (lowest)
2Standard tool access
3Elevated; explicit Guardian-attested tier transition required

Revoke​

DELETE /v1/proxy/nhi/identities/{id} with body { "reason": "..." }. Returns 204 No Content. Active sessions and JIT tokens are invalidated.


JIT tokens​

POST /v1/proxy/nhi/tokens issues a Just-In-Time token. Single-use, short-lived. The plaintext token is returned once.

{
"nhi_id": "nhi_01JF8RNHI1A2B3C4D5E6F7G8H9",
"task_correlation_id": "task_2026-05-01-deploy-prod",
"ttl_seconds": 300,
"allowed_network_cidr": "10.0.0.0/16"
}

Response — 201 Created:

{
"token_id": "ntk_01JF8RNTK1A2B3C4D5E6F7G8H9I",
"nhi_id": "nhi_01JF8RNHI1A2B3C4D5E6F7G8H9",
"plaintext_token": "njit_4f8d9e2a1c6b7f3a9e1d2c4b5a6f7e8d",
"expires_at": "2026-05-01T22:19:00Z",
"issued_tier": 2
}

Use the plaintext token as X-Trinitite-Nhi-Token on subsequent proxy or gateway calls.


Tier transitions​

POST /v1/proxy/nhi/tier-transitions requests a privilege tier elevation. Requires a guardian_approval_hash proving the assigned Guardian signed off — see tier attestation below.

{
"nhi_id": "nhi_01JF8RNHI1A2B3C4D5E6F7G8H9",
"target_tier": 3,
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"guardian_approval_hash": "sha256:8f3c...",
"intent_summary": "Elevate to deploy production helm release."
}

Returns 201 Created with the tier transition record.


Lifecycle bindings​

Bind an NHI to a human principal. On principal offboarding, bound NHIs cascade-revoke.

MethodPathPermission
POST/v1/proxy/nhi/lifecycle-bindingsnhi:update
GET/v1/proxy/nhi/lifecycle-bindingsnhi:read
{
"nhi_id": "nhi_01JF8RNHI1A2B3C4D5E6F7G8H9",
"principal_user_id": "usr_01JF8RUS1A2B3C4D5E6F7G8H9I",
"hris_employee_id": "EMP-12345"
}

Cascade revocation​

POST /v1/proxy/nhi/cascade-revocation revokes all NHIs bound to a departing principal.

{ "principal_user_id": "usr_01JF8RUS1A2B3C4D5E6F7G8H9I" }

Returns a summary of revoked identities.


Economic sessions​

A spend-bounded session attached to an NHI. The economic circuit breaker trips when the session exceeds its limit. See also Governance Controls → Credential controls.

MethodPathPermission
POST/v1/proxy/nhi/economic-sessionsnhi:update
GET/v1/proxy/nhi/economic-sessionsnhi:read
PATCH/v1/proxy/nhi/economic-sessions/{sessionId}nhi:update
DELETE/v1/proxy/nhi/economic-sessions/{sessionId}nhi:update
POST/v1/proxy/nhi/economic-sessions/{sessionId}/tripnhi:update
POST/v1/proxy/nhi/economic-sessions/{sessionId}/resetnhi:update

The trip and reset endpoints manually fire / clear the breaker — useful in incident response.

IMDS shield events​

GET /v1/proxy/nhi/imds-events — read-only stream of cloud Instance Metadata Service shield events caught at the proxy boundary.

Orchestration config​

GET /v1/proxy/nhi/orchestration-config and PATCH ... — retry / backoff configuration per NHI tier.

EX-2.7 tool attempts​

MethodPathPermission
GET/v1/proxy/nhi/tool-attemptsnhi:read
GET/v1/proxy/nhi/tool-attempts/summarynhi:read

Read-only feed of every attempt by an NHI to call a tool — including the verdict, blocker (if any), and policy that fired.


NHI Federation (/v1/nhi/federation)​

External NHIs (AWS IAM roles, Azure AD service principals, GCP, Kubernetes service accounts, OIDC subjects, Astrix, Aembit) are mirrored into the platform via the federation registry.

Providers​

MethodPathPermission
POST/v1/nhi/federation/providersnhi:update
GET/v1/nhi/federation/providersnhi:read
GET/v1/nhi/federation/providers/{id}nhi:read
PATCH/v1/nhi/federation/providers/{id}nhi:update
DELETE/v1/nhi/federation/providers/{id}nhi:update
POST/v1/nhi/federation/providers/{id}/syncnhi:update
{
"provider_type": "aws_iam",
"label": "AWS prod-iam",
"config_json": {
"account_id": "123456789012",
"role_arn_pattern": "arn:aws:iam::123456789012:role/agent-*"
},
"tier_mapping": {
"default": 1,
"by_role_tag": { "tier:2": 2, "tier:3": 3 }
}
}

POST .../sync triggers an out-of-band sync; 200 OK response includes { added, updated, deleted, sync_duration_ms } stats.

Federated identities​

MethodPathPermission
GET/v1/nhi/federation/identitiesnhi:read
POST/v1/nhi/federation/identities/importnhi:update
POST/v1/nhi/federation/identities/{id}/linknhi:update
POST/v1/nhi/federation/identities/{id}/unlinknhi:update

Federated identities are linkable to platform-issued NHIs via link / unlink — once linked, governance and analytics aggregate across the pair.

Federation events​

MethodPathPermission
POST/v1/nhi/federation/eventsnhi:update
GET/v1/nhi/federation/eventsnhi:read

Bulk-ingest events from external IdPs (e.g. role assumption logs). POST accepts { events: [...] } and returns 202 Accepted with { ingested }.

Posture summary​

GET /v1/nhi/federation/posture — composite federation health (provider connectivity, drift, mirror staleness).


NHI ↔ Guardian binding (/v1/nhi-guardian)​

A binding determines whether and how an NHI's traffic is governed. Modes:

ModeBehaviour
inputGuardian evaluates inbound user prompts only
outputGuardian evaluates outbound model responses only
bidirectionalBoth directions

Assignments​

MethodPathPermission
POST/v1/nhi-guardian/assignmentsnhi:update
GET/v1/nhi-guardian/assignmentsnhi:read
GET/v1/nhi-guardian/assignments/{id}nhi:read
PATCH/v1/nhi-guardian/assignments/{id}nhi:update
DELETE/v1/nhi-guardian/assignments/{id}nhi:update
{
"nhi_id": "nhi_01JF8RNHI1A2B3C4D5E6F7G8H9",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"governance_mode": "bidirectional",
"priority": 100,
"auto_route": true,
"effective_from": "2026-05-01T00:00:00Z",
"effective_until": null
}

Higher priority wins when an NHI has multiple active assignments. auto_route: true means the proxy auto-resolves this assignment when the calling NHI omits an explicit Guardian envelope.

Resolve / ungoverned​

GET /v1/nhi-guardian/resolve/{nhiId} — returns the Guardian that would govern this NHI right now (the active resolution chain).

GET /v1/nhi-guardian/ungoverned — every NHI that currently has no active Guardian assignment. Useful for rolling out governance and for posture dashboards.

Metrics​

GET /v1/nhi-guardian/metrics — pair-level aggregate metrics (verdict counts, latency, drift signals).

GET /v1/nhi-guardian/metrics/timeseries — bucketed timeseries view.

Training suggestions​

The platform mines proxy logs for cases where the assigned Guardian should have corrected or blocked but didn't (or vice versa) and surfaces them as training suggestions.

MethodPathPermission
GET/v1/nhi-guardian/training-suggestions/{guardianId}nhi:read
POST/v1/nhi-guardian/training-suggestions/{id}/acceptnhi:update
POST/v1/nhi-guardian/training-suggestions/{id}/rejectnhi:update

Accepted suggestions feed directly into the next Training job for the Guardian.

Concentration & policy impact​

GET /v1/nhi-guardian/concentration — surfaces over-concentration risk (one Guardian governing too many NHIs, or one NHI blocking the fleet on a single binding).

GET /v1/nhi-guardian/policy-impact/{documentId} — for a given Policy document, which NHIs are affected if its assigned Guardians are retrained.

Tier attestation​

POST /v1/nhi-guardian/tier-attestation/{nhiId} — the Guardian-signed attestation feeding POST /v1/proxy/nhi/tier-transitions.

{
"target_tier": 3,
"intent_summary": "Elevate to run helm release.",
"evidence": { "training_runs": ["job_01JF..."] }
}

Response — 200 OK:

{
"guardian_approval_hash": "sha256:8f3c...",
"guardian_id": "gov_01JF8R3M3X4N5Q6T7V8W9Y0Z1A",
"expires_at": "2026-05-01T23:00:00Z"
}

The guardian_approval_hash is what POST /v1/proxy/nhi/tier-transitions will validate.


Errors​

HTTPerror.codeCause
400validation_errorBody or query failed schema validation
401unauthenticatedMissing or invalid credential
401nhi_token_invalidNHI JIT token rejected
403forbiddenCaller lacks nhi:read / nhi:update
404not_foundNHI, federation provider, assignment, or training suggestion not found
409conflictConcurrent modification, duplicate assignment
409economic_session_limit_exceededEconomic session breaker tripped
422unprocessable_entityTier transition without a valid guardian_approval_hash
429rate_limitedPer-organization rate limit exceeded

Next steps​