The runtime gate answers one question: may this identity take this action, right now? An AI agent runtime asks before it acts, and NHI Security answers allow, challenge or deny from what it already knows about that identity — its lifecycle state, its credentials, the tools it is entitled to use, the classification of what it is reaching for, and whether a person has granted it access.
Read this before planning around the gate. No connector discovers AI agents, so on an estate filled only by connectors there is no agent for the gate to act for, and no tool entitlements have been collected. The gate is reached by a runtime you integrate deliberately: you issue it a credential, you declare the tools its identity may use, and you declare that identity’s autonomy. Until you do, it default-denies. See Limitations.

Asking the gate

The identity is taken from the credential, never from the body — a caller cannot ask on behalf of somebody else. requestedOperation and declaredActionClass are required; toolKey, resourceKey, intent and requestId are optional. A refusal is HTTP 200 with a deny decision, not an error status. The gate answered; the answer was no. 422 is reserved for a request the gate could not read at all — a missing operation, or an action class that is not one of the known values. The answer carries the decision, the effective action class, the rules consulted and, where the refusal has a named cause, a reason such as tool_entitlement_uncollected or resource_unclassified. When a request for the same target is already awaiting a person’s decision, the answer names it, so a runtime can tell “ask someone” from “somebody already did”. Report what happened afterwards with POST /api/v1/mediation/{id}/outcome and {"outcome": "succeeded"} or {"outcome": "failed", "failureReason": "..."}. An outcome can be reported once, only for a decision that allowed the action.

Replay

If you send a requestId, a repeat of the same request returns the decision already recorded rather than evaluating again. A runtime that retries after a network failure cannot turn a deny into an allow by asking twice.

How the gate decides

Thirteen rules run. Each returns allow, challenge, deny or abstains, and the strictest answer wins. The combination starts at deny: a rule set in which everything abstains denies.

The four rules you cannot switch off

These four are re-enabled in code whatever the stored configuration says. No access grant, approval or rule change lifts them. This is what quarantine means at runtime: every action by a quarantined identity, of every class, is denied.

The nine rules you can tune

Each of these raises a challenge at most — a refusal that says “a person should decide”, not “never”. The last two abstain rather than challenge when there is no baseline yet, so a newly integrated runtime is not challenged on every call while its history is being built. GET /api/v1/runtime/rules shows the catalogue with your organization’s configuration; POST /api/v1/runtime/rules/{key} with {"isEnabled": false} switches one off. That needs runtime:rule:manage — inside TRUSTIVAN, an Organization Admin. Attempting it on a mandatory rule is 409.

Action class

The caller declares an action class, and NHI Security takes the stricter of that declaration and what the tool is known to do. A runtime cannot downgrade a mutating tool by calling the action a read, and an unclassified tool forces the class to unknown, which is treated as potentially mutating. The decision record stores the effective class, not the claim.

It fails closed

An unknown identity is denied — and the request is still recorded, so an identity nobody has inventoried asking for access is visible rather than invisible. A request naming no tool is challenged, never allowed by omission. A credential that is absent, malformed, revoked or expired is refused before the gate runs at all. If the gate cannot read the facts it needs, the request fails with an error; it never resolves to an allow.

Runtime credentials

An agent runtime authenticates with a bearer credential issued in NHI Security. Both write permissions belong to the Organization Admin role inside TRUSTIVAN.
  • The token is 32 random bytes, base64url-encoded. Nothing is encoded in it: no organization, no identity, no prefix, no expiry.
  • It is returned once, at issue. Only a hash is stored, so it cannot be read back. Lose it and you reissue.
  • Lifetime is a whole number of days, at least 1 and at most 90. There is no “never expires”.
  • Expiry and revocation are enforced inside the lookup, so there is no path that authenticates a dead credential and no cache to wait on. A revoked token and a token that never existed are indistinguishable to the caller.
  • There is no rotation. Issue the replacement, move the runtime onto it, then revoke the old one.
  • It can only be issued to an identity that is an AI agent and is active.
This credential authenticates a runtime to NHI Security. It is not a credential in your estate, and it never appears in your inventory.

Access grants

An access grant is how a person lifts a challenge: a time-boxed authorization for one identity to reach one tool or one resource.
  • Duration is 5 minutes to 7 days. The window starts when the grant is approved, not when it was asked for.
  • One approval is enough, and the approver must be a different person from the requester — refused with 403, in the domain, in the repository and by a database constraint. A single refusal defeats the request however many approvals it has.
  • A grant is in force only while its state is granted, it has not been revoked, and the clock is inside its window. A grant past its end date stops covering anything immediately, whatever its stored state says.
  • Exactly one of a tool or a resource must be named. A resource grant never covers a tool.
A grant matches on the target, not on the operation: a grant on a tool covers any operation that identity performs against that tool for the length of the window. Scope a grant by choosing a narrow tool or resource and a short duration.
Inside TRUSTIVAN, both access_grant:request and access_grant:approve belong to the Organization Admin role, and self-approval is refused. Granting an agent access therefore needs two Organization Admins in your organization. Nothing expires a grant in the background either — enforcement is correct regardless, but the access_grant.expired audit record only appears when someone calls the expirations route.

The decision log

Every decision is recorded, including every refusal, and including requests from identities the organization has never seen. Records cannot be amended or deleted; the database refuses it. All four need runtime:read, which every role holds. Evidence rows are written in the same transaction as the decision, so a decision never exists without its reasons.
Gate decisions are not written to the audit trail. The audit trail records what people did — issuing a credential, approving a grant, changing a rule. What the gate decided lives here, in a log that is equally append-only. See Governance and audit.

Getting to a first allow

  1. Have an identity of type ai_agent in the inventory. No connector produces one, so today this means an estate seeded for demonstration, or a connector you build against the discovery contract.
  2. Declare that identity’s autonomy — PATCH /api/v1/agents/{identityId}/autonomy, agent:manage.
  3. Declare what its tools do — PATCH /api/v1/tools/{toolId}/effect — and which of them it may use — POST /api/v1/tools/entitlements, both agent:manage. This is what stops tool_not_entitled and tool_effect_unclassified firing.
  4. Classify the resources it will reach — PATCH /api/v1/resources/{resourceId}/classification, resource:classify — so resource_unresolved stops firing.
  5. Issue it a runtime credential and point the runtime at POST /api/v1/mediation.
  6. Approve an access grant for anything still challenged.