/** * DEC-087 — NHI P1: derive an OWASP Non-Human Identities (NHI) Top 10 / NIST * CSF 2.0 **posture** from the h2a registry. Pure and deterministic: callers * (the CLI / MCP server) gather a snapshot from the local store and pass it in; * this module only classifies it. It owns no I/O and no clock beyond the * `now` the caller supplies. * * It is the shared posture model that `h2a nhi report` reports, `h2a nhi attest` * signs, and against which `h2a nhi offboard` acts. Coverage rationale and the * full risk mapping live in `evaluations/nhi.md`. h2a is a coordination * protocol, so these are *primitives* — full prevention still depends on key * custody / IAM / deployment outside h2a (see the coverage legend there). */ import type { H2AEnvelope, H2ARole } from "./types.js"; /** OWASP NHI risks h2a can derive from its own registry (subset of the Top 10). */ export declare const H2A_NHI_RISK_IDS: readonly ["NHI1", "NHI4", "NHI5", "NHI7", "NHI9"]; export type H2ANhiRiskId = (typeof H2A_NHI_RISK_IDS)[number]; export type H2ANhiSeverity = "info" | "low" | "medium" | "high"; export declare const H2A_NHI_DEFAULT_LONG_LIVED_KEY_DAYS = 90; export interface H2ANhiInstanceSnapshot { readonly id: string; readonly role?: string; /** Currently-active public keys (PEM), already net of revocations. */ readonly activeKeys: readonly string[]; } export interface H2ANhiSubagentSnapshot { readonly id: string; readonly parentInstance: string; readonly status: "active" | "revoked"; readonly capabilities?: readonly string[]; } export interface H2ANhiKeyEventSnapshot { readonly instance: string; readonly publicKey: string; readonly type: "added" | "revoked"; readonly at: string; } export interface H2ANhiPostureInput { readonly instances: readonly H2ANhiInstanceSnapshot[]; readonly subagents?: readonly H2ANhiSubagentSnapshot[]; /** Keyring events; enables key-age (NHI7). Optional — age is skipped if absent. */ readonly keyEvents?: readonly H2ANhiKeyEventSnapshot[]; /** ISO timestamp the report is generated at (defaults to now). */ readonly now?: string; /** Keys older than this many days are flagged long-lived (NHI7). */ readonly longLivedKeyMaxDays?: number; } export interface H2ANhiFinding { readonly risk: H2ANhiRiskId; readonly title: string; /** NIST CSF 2.0 function(s) the risk maps to. */ readonly csf: string; readonly severity: H2ANhiSeverity; /** Number of flagged subjects (0 = clean). */ readonly count: number; readonly detail: string; readonly subjects: readonly string[]; } export interface H2ANhiPostureSummary { readonly instances: number; readonly instancesWithoutKey: number; readonly activeKeys: number; readonly subagents: number; readonly activeSubagents: number; readonly revokedSubagents: number; } export interface H2ANhiPostureReport { readonly generatedAt: string; readonly summary: H2ANhiPostureSummary; readonly findings: readonly H2ANhiFinding[]; } /** Short, stable, non-reversible key id for posture output (never the PEM). */ export declare function nhiKeyFingerprint(publicKeyPem: string): string; /** * Classify a registry snapshot into an NHI posture report. One finding per * evaluated risk is always present (count 0 ⇒ severity `info`), so the shape is * stable across calls and safe to attest. */ export declare function auditNhiPosture(input: H2ANhiPostureInput): H2ANhiPostureReport; /** * DEC-087 (P1b): an NHI **attestation** is a posture report wrapped in a * signed h2a envelope (DEC-073). It introduces no new artifact kind — it is a * plain `event` envelope whose body carries the report under a `kind` tag — so * a recipient verifies *who* attested *what posture* with the standard * `verifyEnvelopeSignature`. This builds the canonical *unsigned* envelope; * the caller signs it with `signEnvelope` so the private key never enters core. */ export declare const H2A_NHI_ATTESTATION_BODY_KIND = "nhi-attestation"; export interface H2ANhiAttestationActor { readonly instance: string; readonly role: H2ARole; readonly scope: string; } export interface H2ANhiAttestationBody { readonly kind: typeof H2A_NHI_ATTESTATION_BODY_KIND; readonly report: H2ANhiPostureReport; } export declare function nhiAttestationEnvelope(input: { readonly report: H2ANhiPostureReport; readonly actor: H2ANhiAttestationActor; readonly createdAt?: string; }): H2AEnvelope; /** * DEC-090 (P2): a per-identity **inventory** of the NHI estate — distinct from * the risk-oriented `auditNhiPosture`. Each instance is listed with its active * keys (fingerprint, age, long-lived flag, reuse), its subagents (status, * capability bound) and its offboard state, so an operator can plan rotations * and spot reuse across the whole estate. Pure: the caller supplies the * snapshot (registry + keyring events + offboard tombstones) and `now`. */ export interface H2ANhiOffboardSnapshot { readonly instance: string; readonly at: string; readonly reason?: string; } export interface H2ANhiKeyInventory { readonly fingerprint: string; readonly addedAt?: string; readonly ageDays?: number; readonly longLived: boolean; /** Other instances holding this same active key (reuse). */ readonly sharedWith: string[]; } export interface H2ANhiSubagentInventory { readonly id: string; readonly status: "active" | "revoked"; readonly capabilities: string[]; readonly bounded: boolean; } export interface H2ANhiInstanceInventory { readonly id: string; readonly role?: string; readonly offboarded: boolean; readonly offboardedAt?: string; readonly offboardReason?: string; readonly keys: H2ANhiKeyInventory[]; readonly subagents: H2ANhiSubagentInventory[]; } export interface H2ANhiInventoryTotals { readonly instances: number; readonly offboarded: number; readonly activeKeys: number; readonly reusedKeys: number; readonly longLivedKeys: number; readonly subagents: number; readonly activeSubagents: number; } export interface H2ANhiInventory { readonly generatedAt: string; readonly totals: H2ANhiInventoryTotals; readonly instances: H2ANhiInstanceInventory[]; } export interface H2ANhiInventoryInput { readonly instances: readonly H2ANhiInstanceSnapshot[]; readonly subagents?: readonly H2ANhiSubagentSnapshot[]; readonly keyEvents?: readonly H2ANhiKeyEventSnapshot[]; readonly offboards?: readonly H2ANhiOffboardSnapshot[]; readonly now?: string; readonly longLivedKeyMaxDays?: number; } export declare function nhiInventory(input: H2ANhiInventoryInput): H2ANhiInventory; //# sourceMappingURL=nhi.d.ts.map