The policy catalogue
The catalogue is fixed in the product. You can switch a policy off and retune its parameters; you cannot write a new one, and you cannot delete one. Twenty-six policies ship. All are enabled by default exceptagent_invocation_rate_anomalous.
Identity and credential policies
Activity policies
These needactivity_events, which no connector collects. See Activity and exposure policies.
Agent policies
Twelve further policies —unowned_agent, agent_autonomy_undeclared, unsupervised_agent_mutates, agent_tool_reaches_high_impact, agent_tool_effect_unknown, agent_credential_shared, agent_acted_outside_its_tools, shadow_agent_unprofiled, agent_delegated_authority_unowned, agent_delegates_to_agent, agent_lineage_unknown and agent_invocation_rate_anomalous — hold AI agents to rules about ownership, declared autonomy, the tools they may use and who they act for.
Reading and tuning a policy
GET /api/v1/policies returns the whole catalogue with your organization’s overrides and each policy’s availability; GET /api/v1/policies/{policyKey} returns one. Both need policy:read, which every role holds.
PUT /api/v1/policies/{policyKey} enables, disables or retunes one. It needs policy:manage — inside TRUSTIVAN, an Organization Admin. A parameter outside its range is refused with 422 and a per-parameter problem (unknown_parameter, not_a_number, not_an_integer, below_minimum, above_maximum); the rejected value is not echoed back. An unknown policy key is 404.
Every policy can be switched off. None is mandatory.
Availability: what a policy needs before it can run
Each policy declares the facts it requires, drawn from a fixed list: identity inventory, identity ownership, identity usage, credential inventory, permission grants, resource classification, resource reachability, activity events, credential exposure, agent inventory, agent tool grants, agent autonomy, agent delegation and agent lineage. When no connected environment supplies a required fact, the policy is unavailable and names what is missing. It is not reported as zero findings.An unavailable policy is skipped entirely. Findings it raised on an earlier run are not resolved, because nothing looked at them. If you disconnect the environment a policy depended on, its findings stay open until the facts come back and an evaluation clears them, or you close them by hand.
Evaluation runs
An evaluation opens a run, applies every runnable policy in batches, writes the findings, captures risk snapshots, and closes the run.GET /api/v1/policies/evaluations lists runs newest first, with policy:read.
What triggers one
- A person, through
POST /api/v1/findings/evaluateor Govern → Policies → Run evaluation. This needspolicy:manage, so inside TRUSTIVAN only an Organization Admin can start one — a Security Analyst can triage findings but cannot run the evaluator. - A synchronization that collected something, automatically, straight afterwards. A run that collected nothing triggers nothing.
409 when a run is already in progress for your organization — enforced by a database constraint, not by a check that could race — and 422 when there is no identity inventory or no runnable policy. If evaluation throws, the run is recorded as failed, audited, and the error is returned to the caller.
Findings
A finding is one policy’s conclusion about one subject, with the facts that produced it. It is identified by the policy and the subject together, so re-running evaluation updates the same finding rather than creating a second one. Findings are never deleted.Status
PATCH /api/v1/findings/{findingId}/status needs finding:manage — an Organization Admin or a Security Analyst. Setting resolved is refused with 422: that status is the evaluator’s reading of evidence, not an opinion. Setting the status it already has is 409.
There is no route that creates a finding.
What an evaluation does to an existing finding
- Still matches, and it was suppressed (
risk_accepted,false_positive) — left alone. - Still matches, and it was
resolved— reopened toopen. - No longer matches —
resolved, unless it isfalse_positive, which stays.
GET /api/v1/findings/{findingId}/history returns it, and /evidence returns the observations behind the finding.
Reading the queue
GET /api/v1/findings lists findings, sorted by severity, with finding:read. GET /api/v1/findings/summary gives the counts plus whether this organization has ever evaluated — so an empty queue on a never-evaluated organization does not read as a clean estate.
exposureId, resourceId and subjectKind are accepted by the list endpoint and currently have no effect on the results. Filter by identityId, credentialId, status, severity, policy, kind, provider, unownedOnly or actionableOnly instead.Risk
Per identity
An identity’s severity is the highest severity among its open findings — not a band derived from its score. Its score is the sum of its open findings’ severity points, clamped to 0–100:
Risk is computed when you read it, from the findings as they stand, so it cannot disagree with the findings page. Each contributing finding is shown with the score.
GET /api/v1/findings/risk returns risk by identity; /risk/identity/{identityId}/comparison compares the live score with the most recent earlier snapshot.
Snapshots, history and posture
Every evaluation run captures a snapshot per identity that has at least one open finding — its score, severity and the findings behind it — and one organization-wide posture snapshot holding the findings by severity, the identities by risk band, how many subjects were not assessable and how many policies were unavailable. An identity with nothing open is omitted rather than written as a zero.GET /api/v1/findings/risk/posture returns the trend, up to 30 points by default and 180 at most. /risk/identity/{identityId}/history returns one identity’s snapshots, newest first.
A trend point is improving, worsening, unchanged or no_comparison — band first, score as the tiebreak. A posture comparison is marked not comparable when the later run assessed less than the earlier one: if more subjects were skipped or more policies were unavailable, a lower finding count is a coverage change, not an improvement, and NHI Security says so rather than drawing an encouraging line.
Policy exceptions
An exception records that your organization has deliberately exempted a subject from a policy, with a justification, an owner and an end date. Request it withPOST /api/v1/policy-exceptions (policy:exception:request — Organization Admin or Security Analyst); decide it with POST /api/v1/policy-exceptions/{id}/decision (policy:exception:approve — Organization Admin).
- Exactly one scope: an identity, a credential, a resource or a team. There is no “everything”.
- Duration is 1 to 90 whole days, and
expiresAtis always set — no exception is permanent. Renewal is a new request, never an extension. - The approver must be a different person from the requester. The attempt is refused with
403and recorded in the audit trail as a failure. - Withdrawing is the requester’s act; revoking is an approver’s, and needs a reason.
Remediation
A remediation action is a proposed fix, optionally linked to the finding that prompted it:revoke_credential, rotate_credential, disable_identity, remove_permission, quarantine_identity, decommission_identity, assign_owner, create_ticket or notify_owner.
- Propose with
POST /api/v1/remediation(remediation:propose— Organization Admin or Security Analyst). - Every action that would change something at the provider needs an approval, and the approver must not be the proposer.
- The three irreversible kinds — revoking a credential, decommissioning an identity, removing a permission — need a dry run first.
- Execution is additionally gated by a deployment setting and by having an executor for that provider. The summary reports whether execution is enabled at all.
- A succeeded action of a reversible kind can be rolled back once.
Activity and exposure policies
Five activity policies andcredential_exposed depend on facts no connector collects: what identities actually did, and where credential material has turned up. NHI Security does not pretend to have them — the policies report as unavailable and name the missing fact.
Both facts arrive through ingestion endpoints instead, for a pipeline you run:
Both permissions belong to the Organization Admin role inside TRUSTIVAN. Records that cannot be matched to the inventory are reported back as rejections with a reason rather than silently dropped, and each submission is recorded as an ingestion run you can list.
NHI Security has no API keys of its own. Every request is authenticated by your TRUSTIVAN session, except the runtime gate, which uses its own bearer credentials. A pipeline that ingests activity has to carry a session, which makes this an integration to plan rather than a header to set. See Limitations.

