| English | 中文版 |
Spec Number: NPS-3 Status: Proposed Version: 0.11 Date: 2026-05-11 Port: 17433 (default, shared) / 17435 (optional dedicated) Authors: Ori Lynn / INNO LOTUS PTY LTD Depends-On: NPS-1 (NCP v0.9)
The key words “MUST”, “MUST NOT”, “SHOULD”, and “MAY” in this document are to be interpreted as described in RFC 2119.
NIP issues a verifiable Neural Identity (NID) to every AI agent, NWP node, and human operator, carrying capability declarations and scope-bound permissions. It supports trust-chain propagation and real-time revocation. NIP is the heart of the NPS security model.
| Role | Description |
|---|---|
| Root CA | Root certificate authority; stored offline |
| Org CA | Organization intermediate CA; one per organization |
| Agent | AI agent holding an NID certificate |
| Node | NWP node holding an NID certificate |
| Operator | Human administrator holding an Operator certificate |
| Verifier | The party verifying an NID (usually a Node) |
Root CA (offline, rarely used)
│
└── Org Intermediate CA (one per org, 1-year validity)
├── Agent Certificate (30-day validity, auto-renewal supported)
├── Node Certificate (90-day validity)
└── Operator Certificate (1-year validity, bound to MFA)
nid = "urn:nps:" entity-type ":" issuer-domain ":" identifier
entity-type = "agent" / "node" / "org"
issuer-domain = <RFC 1034 domain>
identifier = 1*(ALPHA / DIGIT / "-" / "_" / ".")
Examples
urn:nps:agent:ca.innolotus.com:550e8400-e29b-41d4 ← AI agent
urn:nps:node:api.myapp.com:products ← NWP node
urn:nps:org:mycompany.com ← Organization CA
Two identifier prefixes are reserved on NIDs of entity-type = agent and signal a structural role within the orchestrator / session lineage model. Both follow the existing identifier ABNF (1*(ALPHA / DIGIT / "-" / "_" / ".")).
| Prefix | Role | Example |
|---|---|---|
group- |
Orchestrator group NID — the trust anchor for a fleet of session NIDs issued by the CA on the group’s behalf. Longer-lived (default 365 days) and revocable. | urn:nps:agent:ca.example.com:group-7f3c9e1a-b2d8-4c6f-9a01 |
session- |
Short-lived session NID issued under a group. The portion after session- MUST be of the form {unix-timestamp}-{random} where {random} is at least 8 hex characters. Default validity 1 hour, max 24 hours. |
urn:nps:agent:ca.example.com:session-1714672800-f3a92c0b |
Identifiers without these prefixes continue to behave as ordinary agent NIDs. Receivers MUST NOT reject a NID solely on its prefix; the prefix is informational and the authoritative role is carried in the signed IdentFrame.lineage.role field (§5.1.3). The protocol-level nop:orchestrate capability (NPS-5) continues to express the role of being an orchestrator and is independent of this prefix convention.
| Algorithm | Use | Key length |
|---|---|---|
| Ed25519 (primary) | High-frequency agent verification | 32-byte private key / 32-byte public key |
| ECDSA P-256 (fallback) | Compatibility scenarios | 32-byte private key / 64-byte public key |
Public-key encoding: {algorithm}:{base64url(DER)}, e.g. ed25519:MCowBQYDK2VwAyEA....
Agent identity declaration carrying the certificate. Sent as the handshake frame on every new connection.
Field definitions
| Field | Type | Required | Description |
|---|---|---|---|
frame |
uint8 | required | Fixed value 0x20 |
nid |
string | required | Agent NID |
pub_key |
string | required | Public key; format {alg}:{base64url} |
capabilities |
array | required | Capabilities held by the agent |
scope |
object | required | Access-scope declaration |
issued_by |
string | required | Issuer NID (Org CA) |
issued_at |
string | required | Issue time (ISO 8601 UTC) |
expires_at |
string | required | Expiration time (ISO 8601 UTC) |
serial |
string | required | Certificate serial (globally unique per Org CA, hex) |
signature |
string | required | CA’s signature over this frame; format {alg}:{base64url} |
cert_format |
string (enum) | required | Certificate encoding format. One of "x509-der" / "raw-pubkey". Excluded from the signed canonical JSON (see §5.1.3 canonicalisation note). |
cert_chain |
array of string | required when cert_format = "x509-der" |
DER-encoded certificate chain, base64url-encoded, leaf first. When cert_format = "raw-pubkey", cert_chain MUST be omitted (not present in the serialised frame and not included in the canonical form). Excluded from the signed canonical JSON (see §5.1.3 canonicalisation note). |
metadata |
object | optional | Agent metadata — see below |
assurance_level |
string | optional | One of "anonymous" / "attested" / "verified" (see §5.1.1). REQUIRED when the NID’s certificate carries the id-nid-assurance-level extension. Receivers MUST treat an absent field as "anonymous" (backward compatibility with v1.0-alpha.2 publishers). When both field and cert extension are present, they MUST carry the same value — phase gate: Phase 1–2 (current) enforcement is opt-in (SHOULD check, MAY enforce); starting Phase 3 flag day (see NPS-RFC-0003 §8.1) enforcement is MUST, violation returns NIP-ASSURANCE-MISMATCH. (NPS-RFC-0003) |
lineage |
object | optional | Signed lineage metadata. Present when the NID is an orchestrator group (role = "group") or a short-lived session (role = "session"). See §5.1.3. (NPS-CR-0003) |
ocsp_staple |
string | optional | Base64url-encoded DER OCSP response stapled by the Agent at send time (NIP v0.9 §5.1.4). Receivers SHOULD verify the staple signature; an expired staple returns NIP-OCSP-STAPLE-EXPIRED. When absent, receivers MAY perform an online OCSP lookup per the ocsp_url declared in the NWM. |
node_roles |
array[string] | optional | Self-declared node-role tags, e.g. ["memory", "orchestrator"] (NIP v0.10). Same vocabulary as NDP AnnounceFrame.node_roles. Phase 1–2: self-declared, informational. Phase 3 flag day: MUST match the id-nps-node-roles X.509 extension (1.3.6.1.4.1.65715.2.2); mismatch returns NIP-CERT-NODE-ROLES-MISMATCH. |
metadata fields (optional)
| Field | Type | Description |
|---|---|---|
model_family |
string | Model-family identifier used by the agent, e.g. "openai/gpt-4o", "anthropic/claude-4" |
tokenizer |
string | Tokenizer identifier used by the agent, e.g. "cl100k_base" |
runtime |
string | Agent runtime identifier, e.g. "langchain/0.2", "autogen/0.4" |
The metadata field is not included in the signature computation; an agent MAY set it at runtime. Nodes use the tokenizer in metadata to perform CGN auto-matching (see token-budget.md).
Trust boundary for unsigned metadata (normative — closes issue #39)
Because metadata is outside the signature, every value inside it is agent-supplied and unverified. Nodes MUST NOT use any field of IdentFrame.metadata (including but not limited to model_family, tokenizer, and runtime) as input to:
For these uses a Node MUST instead consume a verified signal — an attribute carried in the signed IdentFrame body, the X.509 NID certificate (NPS-RFC-0002 extensions), or a CA-attested side channel — or a Node-internal observed measurement. Treating unsigned metadata as authoritative is a conformance violation.
Three-tier tokenizer trust model
To make the boundary above operational for token accounting, NPS defines three distinct tokenizer signals. Implementations MUST keep them separable in code paths and logs.
| Tier | Source | Trust | Permitted uses |
|---|---|---|---|
declared_tokenizer |
Agent-supplied via IdentFrame.metadata.tokenizer or the X-NWP-Tokenizer request header. Unsigned. |
Agent self-claim only. | Estimation hints only: shaping pre-flight CGN estimates, cache-key disambiguation, telemetry. MUST NOT drive billing, quota elevation, reputation, or security. |
verified_tokenizer |
CA-attested or platform-attested binding of a tokenizer identifier to the NID — e.g. an X.509 NID-cert extension, an AaaS-operator attestation under NPS-AaaS-Profile, or another signed channel agreed by the deployment. | Cryptographically verifiable. | Authoritative for policy, billing, quota tiers, and assurance-gated access. Settlement-grade flows MUST gate on this tier. |
observed_tokenizer_profile |
Node-side statistical or behavioral inference (e.g. byte-length distributions, response-shape fingerprinting, sampled re-tokenization). | Node-internal measurement. | Abuse detection, drift alerts, anomaly scoring, and inputs to a Node’s own reputation engine. MUST NOT be exported to peers as a verified claim. |
When more than one tier is available the Node MUST prefer the highest-trust tier for any decision the boundary above restricts; lower tiers MAY be retained alongside for diagnostic comparison.
Standard capabilities values
| Capability | Description |
|---|---|
nwp:query |
May query Memory Nodes |
nwp:action |
May invoke Action Nodes |
nwp:stream |
May receive StreamFrame responses |
ncp:stream |
May initiate NCP streaming |
nop:delegate |
May delegate subtasks to other agents |
nop:orchestrate |
May act as an orchestrator and emit TaskFrames |
topology:read |
May read Anchor Node topology data via reserved query types topology.snapshot / topology.stream (NPS-2 §12); Anchor Nodes MUST require this capability at Phase 1–2 per NPS-2 §12.4. Self-declared and signed at Phase 1–2; CA-attested role binding deferred to Phase 3 (RFC-0002 amendment). |
llm:complete |
May invoke the standard NWP llm.complete action on an LLM/Thinking Profile node (NPS-2 §4.2a, §7.5) |
llm:stream |
May receive streaming LLM completion responses (LlmCompleteActionRequest.stream = true) |
llm:tool_call |
May submit tool definitions and receive tool-call requests in LLM completion flows |
llm:embed |
May invoke standard embedding actions when a node advertises embedding support |
llm:rerank |
May invoke standard rerank actions when a node advertises rerank support |
scope field
{
"nodes": ["nwp://api.myapp.com/*"],
"actions": ["orders:read", "orders:create"],
"max_token_budget": 50000
}
Signature computation
The signature is computed over the canonical JSON of the IdentFrame with the signature field removed (keys sorted alphabetically, no whitespace).
Full example
{
"frame": "0x20",
"nid": "urn:nps:agent:ca.innolotus.com:550e8400-e29b-41d4",
"pub_key": "ed25519:MCowBQYDK2VwAyEA...",
"capabilities": ["nwp:query", "nwp:action", "ncp:stream"],
"scope": {
"nodes": ["nwp://api.myapp.com/*"],
"actions": ["orders:read", "orders:create"],
"max_token_budget": 50000
},
"issued_by": "urn:nps:org:mycompany.com",
"issued_at": "2026-04-10T00:00:00Z",
"expires_at": "2026-05-10T00:00:00Z",
"serial": "0x0A3F9C",
"signature": "ed25519:3045022100..."
}
NPS defines three assurance levels an Agent identity may carry, modelled on NIST SP 800-63 IAL and CA/B Forum DV/OV/EV. The level travels in IdentFrame.assurance_level and is the source of truth for Node policy decisions (NWM.min_assurance_level); when X.509 NID certificates are in use (NPS-RFC-0002), the cert MUST also carry the id-nid-assurance-level extension and the two MUST agree — phase gate: enforcement is opt-in in Phase 1–2 (current); mandatory starting Phase 3 flag day (see NPS-RFC-0003 §8.1).
| Level | Enum value | Minimum CA criteria | Typical use |
|---|---|---|---|
| L0 | "anonymous" |
Self-signed, OR CA-signed without out-of-band identity binding | Hobbyist Agents, dev / test, free read-only endpoints |
| L1 | "attested" |
NID signed by an RFC-0002-compliant CA; CA attests possession of the NID private key (e.g. ACME agent-01 challenge); contact email or domain verified. The id-nid-assurance-level X.509 extension uses IANA-assigned OID 1.3.6.1.4.1.65715.2.1; the companion id-nps-node-roles extension uses 1.3.6.1.4.1.65715.2.2 (PEN 65715 assigned to LabAcacia 2026-05-08, NPS-CR-0004; see NPS-RFC-0002 §10 OQ-2). |
Most production Agents; default rate-limit tier |
| L2 | "verified" |
L1 criteria plus CA binds the operator’s legal identity (corporate registration for org-NIDs, signed AaaS-operator attestation for hosted Agents) | Regulated integrations, paid premium tiers, contract-grade orchestration |
Default is "anonymous" — pre-RFC-0003 NIDs and any NID lacking the field are treated as L0. A Node demanding stricter levels declares min_assurance_level in its NWM (NPS-2 §4.1, §4.3).
The values are an ordered enum: anonymous < attested < verified. A request whose level is below the Node’s required level MUST be rejected with NWP-AUTH-ASSURANCE-TOO-LOW (NPS-AUTH-FORBIDDEN).
Forward compatibility: An implementation receiving an assurance_level value not present in this enum MUST treat it as a protocol error and return NIP-ASSURANCE-UNKNOWN (NPS-CLIENT-BAD-FRAME). Implementations MUST NOT silently demote an unknown value to anonymous — silent demotion would create a security loophole for future higher-assurance levels introduced by a later spec revision.
See NPS-RFC-0003 for full design rationale, including the X.509 critical-extension flip planned in coordination with NPS-RFC-0002.
Companion to assurance levels (§5.1.1). Where
assurance_levelanswers “who is this Agent?”, reputation log entries answer “how has this NID behaved?” — published as a Certificate-Transparency-style append-only log so that any party (Node, auditor, downstream operator) can reach the same evidence about the same NID without a pre-existing relationship with the publisher.
A reputation entry is a signed JSON object that an issuer (typically an AaaS Anchor Node, an auditor, or a CA) publishes against a subject_nid to record one observed behavioral incident. Entries are aggregated by log operators that maintain an append-only history; the wire format below is the entry shape itself, independent of any specific log operator’s HTTP surface (see NPS-RFC-0004 §4.3 for the operator interface).
Field definitions
| Field | Type | Required | Description |
|---|---|---|---|
v |
uint8 | required | Schema version. This document defines 1. |
log_id |
string (NID) | required | NID of the log operator that appended (or will append) this entry. MAY equal issuer_nid for self-published entries. |
seq |
uint64 | required | Monotonically increasing per-log_id sequence number. Set by the log operator on append. |
timestamp |
string (RFC 3339 UTC) | required | Log operator’s commit time. |
subject_nid |
string (NID) | required | The NID this entry is about. |
incident |
string (enum) | required | One of the values in §5.1.2.1, or a forward-compatible unknown value (receivers MUST preserve unknown values). |
severity |
string (enum) | required | One of info / minor / moderate / major / critical. |
window |
object | optional | { start: ISO 8601, end: ISO 8601 } describing the observation window. |
observation |
object | optional | Free-form, machine-readable, per-incident-type detail (e.g. {requests: 45000, threshold: 300} for a rate-limit violation). |
evidence_ref |
string (URL) | optional | URL where richer evidence (logs, transcripts) lives. |
evidence_sha256 |
string (hex) | optional | SHA-256 of the evidence blob; lets queriers detect tampering with the off-log evidence. |
issuer_nid |
string (NID) | required | NID of the party making the assertion. MAY equal log_id. |
signature |
string | required | {alg}:{base64url} Ed25519 signature by issuer_nid’s private key over the entry minus signature, canonicalised per RFC 8785 (JCS). Log operators verify this signature, then re-sign the full entry with their log_id key for the ordering commitment (dual-signature model). |
| Value | Meaning |
|---|---|
cert-revoked |
CA revoked the subject_nid’s cert. |
rate-limit-violation |
Sustained violation of published rate limits. |
tos-violation |
Violated an AaaS Anchor Node’s published terms. |
scraping-pattern |
Behavior matched scraper heuristics. |
payment-default |
CGN or fiat default on a committed transaction. |
contract-dispute |
Unresolved contractual breach on an async NOP task. |
impersonation-claim |
Third-party claim that subject_nid is impersonating them. |
positive-attestation |
Explicit positive signal (e.g. independent audit passed). |
Receivers MUST treat unknown incident values as opaque pass-through (forward compatibility); operator-side filters MAY ignore them. See NPS-RFC-0004 §4.2 for the long-form rationale.
Errors
| Code | When |
|---|---|
NIP-REPUTATION-ENTRY-INVALID (NPS-CLIENT-BAD-FRAME) |
Entry signature fails verification or canonical form is malformed. |
NIP-REPUTATION-LOG-UNREACHABLE (NPS-DOWNSTREAM-UNAVAILABLE) |
A log operator referenced by a Node’s reputation_policy cannot be reached during admission evaluation. |
NWP-AUTH-REPUTATION-BLOCKED (NPS-AUTH-FORBIDDEN) |
Reputation policy matched a reject_on rule on the requesting subject_nid. (Defined in NPS-2 §6 — Anchor / Memory / Action / Complex / Bridge Nodes that opt in.) |
Phase 1 of NPS-RFC-0004 standardises the entry wire format and the signature rule above; the Merkle-tree / Signed Tree Head / inclusion-proof surface (RFC 9162-style) and the operator HTTP API land in Phase 2 alongside the NDP discovery hint. See the RFC for the full phasing.
IdentFrame.lineage carries the signed parent-chain metadata that links a short-lived session NID back to its orchestrator group NID, and that records who owns / authorised the group. The trust chain is:
human owner → Operator key (§2.1) → orchestrator group NID → short-lived session NID
lineage is part of the signed canonical JSON of the IdentFrame (unlike metadata, which is excluded). Modifying any sub-field invalidates the CA signature — this is what makes the chain verifiable end-to-end: a Node admitting a session NID can prove that lineage.parent_nid was authoritatively asserted by the CA at issuance time, not retro-fitted on the wire.
Field definitions
| Field | Type | Required | Description |
|---|---|---|---|
role |
enum ("group" / "session") |
required when lineage is present |
Lineage role of this NID. |
parent_nid |
string (NID) | required when role = "session" |
Immediate parent NID. For a 1-level chain (group → session), equals group_nid. |
group_nid |
string (NID) | required when role = "session" |
Group NID at the root of the chain. Equals parent_nid for a 1-level chain; reserved for future deeper chains. |
session_id |
string | required when role = "session" |
Stable id of this execution; matches the session-... portion of the NID identifier (§3.1). Echoes back so consumers can index without parsing the URN. |
purpose |
string (≤256 UTF-8 bytes) | optional | Free-form, human-readable label for what this execution is for, e.g. "order-classification-job". |
owner_user_id |
string | optional | Stable identifier of the human owner this group is acting on behalf of (e.g. internal user UUID). SHOULD be set when role = "group" and the deployment knows the owner. |
owner_key_id |
string | optional | kid hint identifying the owner-key (Operator key, OIDC sub, hardware-token id) that authorised creation of the group. |
Group-NID example
"lineage": {
"role": "group",
"owner_user_id": "user-7f3c9e1a",
"owner_key_id": "op-kid-2026-04"
}
Session-NID example
"lineage": {
"role": "session",
"parent_nid": "urn:nps:agent:ca.example.com:group-7f3c9e1a-b2d8-4c6f-9a01",
"group_nid": "urn:nps:agent:ca.example.com:group-7f3c9e1a-b2d8-4c6f-9a01",
"session_id": "session-1714672800-f3a92c0b",
"purpose": "data-extraction-job-42",
"owner_user_id": "user-7f3c9e1a",
"owner_key_id": "op-kid-2026-04"
}
Backward compatibility: pre-CR-0003 publishers omit lineage; pre-CR-0003 verifiers that strict-canonicalise (sort + omit signature / metadata / cert_format / cert_chain) will drop unknown fields if their DTO does not carry them, in which case signature verification of a CR-0003 frame fails. New senders aware of CR-0003 produce CR-0003 frames; old verifiers MUST be upgraded to verify them. Ordinary agent NIDs without lineage continue to verify exactly bit-compatibly.
Errors
| Code | When |
|---|---|
NIP-CA-GROUP-REVOKED (NPS-AUTH-FORBIDDEN) |
Cannot issue a session under a group that has been revoked. |
NIP-CA-PARENT-NOT-FOUND (NPS-CLIENT-NOT-FOUND) |
The parent_nid / group NID referenced by a session-issue request does not exist. |
NIP-CA-PARENT-NOT-GROUP (NPS-CLIENT-BAD-PARAM) |
The referenced parent NID exists but is not registered as lineage.role = "group". |
NIP-CA-SESSION-VALIDITY-INVALID (NPS-CLIENT-BAD-PARAM) |
Requested session validity below 60 seconds or above the CA’s configured maximum. |
NIP-CA-JWS-INVALID (NPS-AUTH-UNAUTHENTICATED) |
Group-JWS authorisation on a session-issue request fails signature, header, or shape validation. |
NIP-CA-JWS-EXPIRED (NPS-AUTH-UNAUTHENTICATED) |
Group-JWS iat outside the CA’s clock-skew window (default ±5 minutes). |
NIP-CERT-PARENT-REVOKED (NPS-AUTH-UNAUTHENTICATED) |
A session NID’s parent / group NID is revoked or expired (chain check, §7 step 3a). |
See NPS-CR-0003 for the full motivation, JWS shape, and migration impact.
An Agent MAY attach a pre-fetched OCSP response to the ocsp_staple field of its IdentFrame, enabling the receiving Node to verify certificate revocation status without a live OCSP round-trip.
Verification rules (receiver)
ocsp_staple from base64url to obtain the DER-encoded OCSPResponse.cert_chain or the Node’s local trust store).thisUpdate and nextUpdate: if the current time is after nextUpdate, return NIP-OCSP-STAPLE-EXPIRED.certStatus in SingleResponse for the certificate identified by serial. If revoked, return NIP-CERT-REVOKED.When ocsp_staple is absent, the Node MAY perform an online OCSP lookup to the URL declared in NWM.ocsp_url (§4.1). This lookup is optional but RECOMMENDED for "verified" assurance level endpoints.
X.509 OID Registry (NIP v0.9 — PEN 65715 arc)
| OID | Name | ASN.1 type | Description |
|---|---|---|---|
1.3.6.1.4.1.65715.2.1 |
id-nid-assurance-level |
UTF8String | Agent assurance level (anonymous / attested / verified). CA MUST populate when issuing. |
1.3.6.1.4.1.65715.2.2 |
id-nps-node-roles |
SEQUENCE OF UTF8String | Role tags carried in AnnounceFrame.node_roles / IdentFrame.node_roles. CA SHOULD populate from the enrollment request. Phase 3 enforcement. |
1.3.6.1.4.1.65715.2.3 |
id-nps-capabilities |
SEQUENCE OF UTF8String | Capability strings (same vocabulary as IdentFrame.capabilities). CA MAY populate as a CA-attested alternative to the unsigned capabilities field. Phase 3. |
Cross-CA trust-chain propagation and capability grant. A TrustFrame lets one CA (the grantor) authorise another CA (the grantee) to issue IdentFrames whose capabilities are accepted by Nodes that already trust the grantor — without the grantee being added to each Node’s trusted_issuers list. The grant is scoped to a capability subset and a set of nwp:// URL patterns; it is verifiable end-to-end via the grantor’s signature. Open SDKs carry the full wire frame and MAY provide basic validation for explicitly pinned grantor anchors; managed multi-CA federation, trust-anchor discovery, revocation feeds, and commercial trust-chain policy are NPS Cloud concerns.
Field definitions
| Field | Type | Required | Description |
|---|---|---|---|
frame |
uint8 | required | Fixed 0x21. |
grantor_nid |
string (NID) | required | NID of the granting CA. MUST be in the verifying Node’s trusted_issuers for the TrustFrame to take effect. |
grantee_ca |
string (NID) | required | NID of the receiving CA. IdentFrames whose issued_by equals grantee_ca are admitted under the grant. |
trust_scope |
array of string | required | Capability strings the trust covers. MUST be a subset of the standard capabilities enum defined in §5.1 (nwp:query / nwp:action / nwp:stream / ncp:stream / nop:delegate / nop:orchestrate / topology:read / llm:complete / llm:stream / llm:tool_call / llm:embed / llm:rerank). A grantee MUST NOT issue downstream IdentFrames carrying capabilities outside this set. |
nodes |
array of string | required | nwp:// URL patterns this trust applies to. * matches a single path segment; ** matches multiple segments. Empty array means the grant covers no nodes (effectively inert). |
issued_at |
string (ISO 8601 UTC) | required | Issuance time. |
expires_at |
string (ISO 8601 UTC) | required | Expiry time. After this instant the frame MUST be rejected with NIP-TRUST-FRAME-EXPIRED. |
serial |
string (hex) | required | 16-character zero-padded hex serial number used for revocation tracking via RevokeFrame (§5.3). |
signer_nid |
string (NID) | required | NID whose private key signs this frame. MUST be either grantor_nid itself or an authorised delegated agent NID under grantor_nid’s domain, recognised by local policy as an operator/delegated signer. |
signature |
string | required | {alg}:{base64url} — ed25519: (Ed25519) or ecdsa-p256: (ECDSA P-256). |
Signature computation
The signature is computed over the canonical JSON of the TrustFrame with the signature field removed (keys sorted alphabetically, no whitespace) — same canonicalisation rule as IdentFrame in §5.1. Supported algorithms: Ed25519 (ed25519:) and ECDSA P-256 (ecdsa-p256:).
Errors
| Code | When |
|---|---|
NIP-TRUST-FRAME-INVALID (NPS-CLIENT-BAD-FRAME) |
TrustFrame is malformed (missing required field, signature verification fails, or canonical form is invalid). |
NIP-TRUST-FRAME-EXPIRED (NPS-AUTH-UNAUTHENTICATED) |
Current time is past expires_at. |
NIP-TRUST-FRAME-GRANTOR-REVOKED (NPS-AUTH-UNAUTHENTICATED) |
The grantor_nid’s own CA certificate is revoked or expired at verification time. |
NIP-TRUST-FRAME-SCOPE-EXCEEDS-GRANTOR (NPS-AUTH-FORBIDDEN) |
trust_scope contains a capability that the grantor itself does not hold (no-scope-expansion principle, §10.3). |
NIP-TRUST-FRAME-NODES-PATTERN-INVALID (NPS-CLIENT-BAD-FRAME) |
An entry in nodes is not a syntactically valid nwp:// URL pattern, or uses wildcards in a position where they are not permitted. |
Full example
{
"frame": "0x21",
"grantor_nid": "urn:nps:org:org-a.com",
"grantee_ca": "urn:nps:org:org-b.com",
"trust_scope": ["nwp:query", "nwp:action"],
"nodes": ["nwp://api.org-a.com/public/**"],
"issued_at": "2026-05-11T00:00:00Z",
"expires_at": "2026-12-31T00:00:00Z",
"serial": "00000000000A3F9C",
"signer_nid": "urn:nps:org:org-a.com",
"signature": "ed25519:3045022100..."
}
Revokes an NID, all certificates issued under an NID, or a specific certificate identified by serial. RevokeFrames are emitted by an issuing CA (or by an authorised delegated agent under that CA) and pushed to subscribed Nodes via the NIP push channel; receivers update their local cert / OCSP cache and reject subsequent requests authenticated under the revoked target. A RevokeFrame is fire-and-forget at the protocol layer (no response frame on success); receivers MUST emit an ErrorFrame only when the frame itself is malformed or unauthorised.
Field definitions
| Field | Type | Required | Description |
|---|---|---|---|
frame |
uint8 | required | Fixed value 0x22. |
target_nid |
string (NID) | required | NID being revoked. MAY be an agent NID, node NID, group NID, or org NID. |
serial |
string (hex) | optional | Specific certificate serial under target_nid to revoke. If present, MUST match the serial of a currently-issued cert for target_nid. If omitted, ALL currently-issued certs for target_nid are revoked (effectively revoking the NID itself). |
reason |
string (enum) | required | One of the values defined in the reason table below. |
revoked_at |
string (ISO 8601 UTC) | required | Wall-clock instant at which revocation takes effect. Receivers SHOULD reject any request whose IdentFrame issued_at is at or before revoked_at. |
parent_nid |
string (NID) | conditional | REQUIRED when reason = "parent_revoked"; identifies the group NID whose cascade triggered this revocation (NPS-CR-0003). MUST be omitted for any other reason. |
signer_nid |
string (NID) | required | NID of the CA or delegated agent signing this revocation. MUST be either the issuing CA of target_nid, an authorised agent NID under that CA’s domain holding the nip:revoke capability, or — for cascade revocations — the CA that issued parent_nid. |
signature |
string | required | {alg}:{base64url} signature by signer_nid’s private key. Supported algorithms: ed25519: (Ed25519) or ecdsa-p256: (ECDSA P-256). |
reason enum
| Value | Description |
|---|---|
key_compromise |
Agent / node private key is known or suspected to be compromised. Highest urgency. |
ca_compromise |
The issuing CA’s signing key is compromised; ALL certificates under that CA are implicitly revoked, and a per-NID RevokeFrame MAY be emitted for each affected child. |
affiliation_changed |
Agent left the issuing organisation; ALL of its capabilities are revoked even if individual certs have not yet expired. |
superseded |
Replaced by a re-issued certificate carrying the same NID (e.g. routine rotation that needs to invalidate the prior serial). The serial field SHOULD be set to identify the superseded cert. |
cessation_of_operation |
Agent / node has been decommissioned and will never present credentials again. |
parent_revoked |
(NPS-CR-0003) Cascade emitted by the CA on a session-NID whose group NID was revoked. The parent_nid field MUST be set to the group NID. Distinguishes ancestry-driven invalidation from a session revoked on its own merits. |
Forward compatibility: receivers encountering a reason value not present in the table above MUST treat it as key_compromise (the most restrictive interpretation). Receivers MAY additionally log the unknown value for diagnostic purposes and MAY emit NIP-REVOKE-FRAME-REASON-UNKNOWN to the publishing CA over a side channel, but MUST NOT silently demote an unknown reason to a less restrictive one.
Signature computation
The signature is computed over the canonical JSON of the RevokeFrame with the signature field removed (keys sorted alphabetically, no whitespace) — same canonicalisation rule as IdentFrame in §5.1 (RFC 8785 JCS).
Errors
| Code | When |
|---|---|
NIP-REVOKE-FRAME-INVALID (NPS-CLIENT-BAD-FRAME) |
RevokeFrame is malformed (missing required field, signature verification fails, or canonical form is invalid). |
NIP-REVOKE-FRAME-UNAUTHORIZED-ISSUER (NPS-AUTH-FORBIDDEN) |
signer_nid is not authorised to revoke target_nid (not the issuing CA of target_nid, not an authorised delegated agent under that CA holding nip:revoke, and — for parent_revoked — not the CA that issued parent_nid). |
NIP-REVOKE-FRAME-SERIAL-MISMATCH (NPS-CLIENT-BAD-PARAM) |
serial is present but does not match any currently-issued cert for target_nid. |
NIP-REVOKE-FRAME-REASON-UNKNOWN (NPS-CLIENT-BAD-FRAME) |
reason carries a value outside the defined enum. Receivers treat the revocation as key_compromise for safety (see Forward compatibility above); this code is reported back to the publishing CA so the publish can be corrected. |
Full example
{
"frame": "0x22",
"target_nid": "urn:nps:agent:ca.innolotus.com:550e8400-e29b-41d4",
"serial": "0x0A3F9C",
"reason": "key_compromise",
"revoked_at": "2026-04-10T12:00:00Z",
"signer_nid": "urn:nps:org:ca.innolotus.com",
"signature": "ed25519:3045022100..."
}
Cascade example (parent_revoked)
{
"frame": "0x22",
"target_nid": "urn:nps:agent:ca.example.com:session-1714672800-f3a92c0b",
"reason": "parent_revoked",
"revoked_at": "2026-04-10T12:00:00Z",
"parent_nid": "urn:nps:agent:ca.example.com:group-7f3c9e1a-b2d8-4c6f-9a01",
"signer_nid": "urn:nps:org:ca.example.com",
"signature": "ed25519:..."
}
parent_revoked (NPS-CR-0003) is set by the CA on a session-NID RevokeFrame it emits as part of cascade revocation when the session’s group NID was revoked. It distinguishes a session that was forcibly invalidated by ancestry from one revoked on its own merits.
Registration Auto-renewal Revocation CA rotation
│ │ │ │
↓ ↓ ↓ ↓
CA issues 7 days pre-expiry RevokeFrame Old + new CA
IdentFrame Agent triggers takes effect in parallel
30-day validity CA issues new cert immediately for 30 days
Both valid 1 hour Nodes reject Smooth rollover
all requests
for that NID
Edge deployments that terminate native-mode mutual TLS at an nps-ingress (L2) gateway
(NPS-RFC-0006 §6.3) benefit from short-lived certificates to minimise revocation exposure
without per-request OCSP round-trips. This profile is additive to the standard validity tiers
(§2.1) and is selected by the CA at issuance.
| Property | Standard Node cert | Short-lived edge cert |
|---|---|---|
| Validity | 90 days | 1–24 hours (default 6 h) |
| Renewal trigger | 7 days pre-expiry | renewal window = 25% of validity remaining |
| Renewal overlap | both valid 1 h | both valid until the old cert’s expires_at |
| Revocation reliance | OCSP / CRL | lifetime ≤ OCSP cache TTL — short validity is the primary revocation mechanism; OCSP is defense-in-depth |
| OCSP-staple interaction | optional | the gateway SHOULD staple (IdentFrame.ocsp_staple, NIP v0.9 §8.2); a stapled response older than the cert’s remaining validity MUST be refreshed (NIP-OCSP-STAPLE-EXPIRED) |
Rules:
[1h, 24h]. A request to issue outside this
range returns NIP-CA-SESSION-VALIDITY-INVALID (reused from the session-NID path, §5).agent-01, NPS-RFC-0002) so an edge node
self-renews before the renewal window without operator action.nps-ingress) MUST reject a presented short-lived cert whose
expires_at ≤ now with NIP-CERT-EXPIRED; because validity is short, relying parties MAY
skip per-request OCSP when the cert lifetime is ≤ their configured OCSP cache TTL.Node receives IdentFrame
│
├─ 1. Check expires_at > now (expired → NIP-CERT-EXPIRED)
├─ 2. Check issued_by is in NWM trusted_issuers (not trusted → NIP-CERT-UNTRUSTED-ISSUER)
├─ 3. Verify signature with issued_by CA public key (fail → NIP-CERT-SIGNATURE-INVALID)
├─ 3a. (NPS-CR-0003) If lineage.parent_nid is present, OCSP-lookup the parent
│ (revoked or expired → NIP-CERT-PARENT-REVOKED)
├─ 4. OCSP lookup (when NWM configures ocsp_url) or local CRL check (revoked → NIP-CERT-REVOKED)
├─ 5. Check capabilities contains what the node requires (missing → NIP-CERT-CAPABILITY-MISSING)
└─ 6. Check scope.nodes covers the target node path (not covered → NWP-AUTH-NID-SCOPE-VIOLATION)
All checks pass → authorize the request
Step 3a (chain check) is mandatory whenever lineage.parent_nid is present, regardless of whether the session NID itself is still inside its own validity window. Combined with the CA-side cascade documented in §5.3 (parent_revoked reason), it provides defense-in-depth: a misconfigured CA that fails to record the cascade still gets caught at the verifier; a CA that did record it still publishes the entries to the CRL for simple consumers.
Note on TrustFrame chains (§5.2): when the IdentFrame’s issued_by is not in the Node’s trusted_issuers directly, step 3 MAY still succeed via a TrustFrame chain. After step 3 (CA signature check), if the IdentFrame was issued by a grantee_ca, the Node SHOULD verify that a valid, unexpired TrustFrame exists from a matching grantor_nid (which IS in trusted_issuers) covering the requested capability and target node path. The TrustFrame itself MUST pass its own checks (§5.2 error table) — failure short-circuits admission with the corresponding NIP-TRUST-FRAME-* code instead of falling through to NIP-CERT-UNTRUSTED-ISSUER.
Inbound RevokeFrame handling (§5.3): RevokeFrames arrive asynchronously over the NIP push channel and are not part of the per-IdentFrame admission flow above. When a Node receives a RevokeFrame it MUST:
Node receives RevokeFrame (push channel)
│
├─ R1. Parse the frame and verify signer_nid signature over canonical JSON
│ (fail → emit ErrorFrame NIP-REVOKE-FRAME-INVALID; do not apply)
├─ R2. Verify signer_nid is authorised to revoke target_nid — see §5.3 signer_nid rules
│ (fail → emit ErrorFrame NIP-REVOKE-FRAME-UNAUTHORIZED-ISSUER; do not apply)
├─ R3. If `serial` is present, verify it matches a known issued cert for target_nid
│ (mismatch → emit ErrorFrame NIP-REVOKE-FRAME-SERIAL-MISMATCH; do not apply)
├─ R4. If `reason` is outside the defined enum, treat as `key_compromise` (most restrictive)
│ and emit ErrorFrame NIP-REVOKE-FRAME-REASON-UNKNOWN to the publisher
├─ R5. Poison the local cert / OCSP cache for target_nid
│ (if `serial` present, scope to that cert; otherwise scope to all certs for target_nid)
└─ R6. No success response is sent — RevokeFrame is fire-and-forget at the protocol layer.
After R5 takes effect, any subsequent IdentFrame for target_nid (or for the specific serial if scoped) will fail step 4 of the IdentFrame verification flow above with NIP-CERT-REVOKED.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /v1/agents/register |
Operator Cert | Register an agent; returns NID + IdentFrame |
| POST | /v1/agents/{nid}/renew |
Agent Cert | Renew a certificate (up to 7 days before expiry) |
| POST | /v1/agents/{nid}/revoke |
Operator Cert | Revoke an NID |
| GET | /v1/agents/{nid}/verify |
None | Verify NID validity (OCSP lookup) |
| POST | /v1/nodes/register |
Operator Cert | Register an NWP node; issues a Node Certificate |
| POST | /v1/orchestrators/groups/register |
Operator Cert | (NPS-CR-0003) Register an orchestrator group; returns IdentFrame with lineage.role = "group" |
| POST | /v1/orchestrators/groups/{group_nid}/sessions/issue |
Group JWS or Operator Cert | (NPS-CR-0003) Issue a short-lived session NID under the group |
| POST | /v1/orchestrators/groups/{group_nid}/revoke |
Operator Cert | (NPS-CR-0003) Revoke the group AND cascade-revoke every live session under it |
| GET | /v1/orchestrators/groups/{group_nid}/sessions |
Operator Cert | (NPS-CR-0003) List sessions issued under this group (audit) |
| GET | /v1/ca/cert |
None | CA public-key certificate |
| GET | /v1/crl |
None | Certificate revocation list |
| GET | /.well-known/nps-ca |
None | CA discovery endpoint |
/.well-known/nps-ca response
{
"nps_ca": "0.1",
"issuer": "urn:nps:org:ca.mycompany.com",
"display_name": "MyCompany NPS CA",
"public_key": "ed25519:MCowBQYDK2VwAyEA...",
"algorithms": ["ed25519", "ecdsa-p256"],
"endpoints": {
"register": "https://ca.mycompany.com/v1/agents/register",
"verify": "https://ca.mycompany.com/v1/agents/{nid}/verify",
"node_verify": "https://ca.mycompany.com/v1/nodes/{nid}/verify",
"crl": "https://ca.mycompany.com/v1/crl"
},
"capabilities": ["agent", "node", "operator", "orchestrator-group"],
"max_cert_validity_days": 30
}
NPS-CR-0005 introduces a three-tier Registration Authority (RA) model that admits agents into the CA along policy-driven paths in addition to the Operator-credential POST /v1/agents/register flow above. The default tier remains operator_only — the new tiers are opt-in via NipCaOptions.EnrollmentTier and add the following endpoints:
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /v1/enrollment/tokens |
Operator Cert | (NPS-CR-0005, Tier 2) Mint a single-use, NID-scoped bootstrap token. |
| GET | /v1/enrollment/pending |
Operator Cert | (NPS-CR-0005, Tier 3) List registration requests awaiting admin decision. |
| POST | /v1/enrollment/pending/{id}/approve |
Operator Cert | (NPS-CR-0005, Tier 3) Approve a pending request and issue the IdentFrame. |
| POST | /v1/enrollment/pending/{id}/reject |
Operator Cert | (NPS-CR-0005, Tier 3) Reject a pending request with an operator-supplied reason. |
The three tiers (allowlist / bootstrap token / pending queue), the new error codes (NIP-RA-TOKEN-INVALID, NIP-RA-TOKEN-EXPIRED, NIP-RA-NID-NOT-ALLOWED, NIP-RA-PENDING-REJECTED), and the NipCaOptions.EnrollmentTier selector are specified in full by NPS-CR-0005. The body, request/response shapes, and verification flow for these endpoints will land in this section once CR-0005 reaches Implemented.
| Error Code | NPS Status | Description |
|---|---|---|
NIP-CERT-EXPIRED |
NPS-AUTH-UNAUTHENTICATED |
Certificate has expired |
NIP-CERT-REVOKED |
NPS-AUTH-UNAUTHENTICATED |
Certificate has been revoked |
NIP-CERT-SIGNATURE-INVALID |
NPS-AUTH-UNAUTHENTICATED |
Certificate signature verification failed |
NIP-CERT-UNTRUSTED-ISSUER |
NPS-AUTH-UNAUTHENTICATED |
Issuer not in the trust list |
NIP-CERT-CAPABILITY-MISSING |
NPS-AUTH-FORBIDDEN |
Certificate missing a required capability |
NIP-CERT-SCOPE-VIOLATION |
NPS-AUTH-FORBIDDEN |
Certificate scope does not cover the target path |
NIP-CA-NID-NOT-FOUND |
NPS-CLIENT-NOT-FOUND |
NID does not exist |
NIP-CA-NID-ALREADY-EXISTS |
NPS-CLIENT-CONFLICT |
NID already exists (duplicate registration) |
NIP-CA-SERIAL-DUPLICATE |
NPS-CLIENT-CONFLICT |
Certificate serial already in use |
NIP-CA-RENEWAL-TOO-EARLY |
NPS-CLIENT-BAD-PARAM |
Renewal window not yet open |
NIP-CA-SCOPE-EXPANSION-DENIED |
NPS-AUTH-FORBIDDEN |
Requested scope exceeds the parent scope |
NIP-OCSP-UNAVAILABLE |
NPS-SERVER-UNAVAILABLE |
OCSP service temporarily unavailable |
NIP-OCSP-STAPLE-EXPIRED |
NPS-AUTH-UNAUTHENTICATED |
IdentFrame.ocsp_staple nextUpdate has elapsed — staple is stale; Agent must refresh and resend (NIP v0.9 §5.1.4) |
NIP-CERT-NODE-ROLES-MISMATCH |
NPS-CLIENT-BAD-FRAME |
IdentFrame.node_roles does not match the id-nps-node-roles X.509 extension; Phase 3 enforcement (NIP v0.10) |
NIP-TRUST-FRAME-INVALID |
NPS-CLIENT-BAD-FRAME |
TrustFrame signature or format is invalid — see §5.2 |
NIP-TRUST-FRAME-EXPIRED |
NPS-AUTH-UNAUTHENTICATED |
TrustFrame expires_at is in the past — see §5.2 |
NIP-TRUST-FRAME-GRANTOR-REVOKED |
NPS-AUTH-UNAUTHENTICATED |
TrustFrame grantor_nid’s own CA certificate is revoked or expired — see §5.2 |
NIP-TRUST-FRAME-SCOPE-EXCEEDS-GRANTOR |
NPS-AUTH-FORBIDDEN |
TrustFrame trust_scope contains a capability the grantor itself does not hold (no-scope-expansion principle, §10.3) — see §5.2 |
NIP-TRUST-FRAME-NODES-PATTERN-INVALID |
NPS-CLIENT-BAD-FRAME |
TrustFrame nodes entry is not a valid nwp:// URL pattern — see §5.2 |
NIP-REVOKE-FRAME-INVALID |
NPS-CLIENT-BAD-FRAME |
RevokeFrame is malformed (missing required field, signature verification fails, or canonical form is invalid) — see §5.3 |
NIP-REVOKE-FRAME-UNAUTHORIZED-ISSUER |
NPS-AUTH-FORBIDDEN |
RevokeFrame signer_nid is not authorised to revoke target_nid — see §5.3 |
NIP-REVOKE-FRAME-SERIAL-MISMATCH |
NPS-CLIENT-BAD-PARAM |
RevokeFrame serial is present but does not match any currently-issued cert for target_nid — see §5.3 |
NIP-REVOKE-FRAME-REASON-UNKNOWN |
NPS-CLIENT-BAD-FRAME |
RevokeFrame reason carries a value outside the defined enum; receivers treat it as key_compromise — see §5.3 |
NIP-ASSURANCE-MISMATCH |
NPS-CLIENT-BAD-FRAME |
IdentFrame.assurance_level does not match the cert extension id-nid-assurance-level (downgrade-attack defense) — see §5.1.1 |
NIP-ASSURANCE-UNKNOWN |
NPS-CLIENT-BAD-FRAME |
assurance_level carries a value outside the defined enum (anonymous / attested / verified) — see §5.1.1 |
NIP-REPUTATION-ENTRY-INVALID |
NPS-CLIENT-BAD-FRAME |
Reputation log entry signature fails verification or canonical form is malformed — see §5.1.2 (NPS-RFC-0004) |
NIP-REPUTATION-LOG-UNREACHABLE |
NPS-DOWNSTREAM-UNAVAILABLE |
A log operator referenced by a Node’s reputation_policy cannot be reached during admission evaluation — see §5.1.2 (NPS-RFC-0004) |
NIP-CA-GROUP-REVOKED |
NPS-AUTH-FORBIDDEN |
Cannot issue a session under a group NID that has been revoked — see §5.1.3 (NPS-CR-0003) |
NIP-CA-PARENT-NOT-FOUND |
NPS-CLIENT-NOT-FOUND |
The parent_nid / group NID referenced by a session-issue request does not exist — see §5.1.3 (NPS-CR-0003) |
NIP-CA-PARENT-NOT-GROUP |
NPS-CLIENT-BAD-PARAM |
The referenced parent NID exists but is not registered as lineage.role = "group" — see §5.1.3 (NPS-CR-0003) |
NIP-CA-SESSION-VALIDITY-INVALID |
NPS-CLIENT-BAD-PARAM |
Requested session validity below 60 seconds or above the CA’s configured maximum — see §5.1.3 (NPS-CR-0003) |
NIP-CA-JWS-INVALID |
NPS-AUTH-UNAUTHENTICATED |
Group-JWS authorisation on a session-issue request fails signature, header, or shape validation — see §5.1.3 (NPS-CR-0003) |
NIP-CA-JWS-EXPIRED |
NPS-AUTH-UNAUTHENTICATED |
Group-JWS iat outside the CA’s clock-skew window (default ±5 minutes) — see §5.1.3 (NPS-CR-0003) |
NIP-CERT-PARENT-REVOKED |
NPS-AUTH-UNAUTHENTICATED |
A session NID’s parent / group NID is revoked or expired (chain check, §7 step 3a) — see §5.1.3 (NPS-CR-0003) |
HTTP-mode status mapping: see status-codes.md.
CA private keys MUST be stored in an HSM or in an encrypted key file (AES-256-GCM). The OSS reference implementation uses encrypted files and reserves an HSM interface.
OCSP response times SHOULD be normalized (fixed 200 ms delay) to prevent certificate-status inference via response-time side channels.
At every link in the delegation chain, scope MUST NOT exceed that of its parent. CAs MUST enforce this at issuance time.
| Version | Date | Changes |
|---|---|---|
| 0.11 | 2026-07-04 | Adds standard LLM capability strings (llm:complete, llm:stream, llm:tool_call, llm:embed, llm:rerank) for NWP LLM/Thinking Profile discovery and authorization. TrustFrame trust_scope may cover these capabilities. No new frame fields or error codes. |
| 0.10 | 2026-06-12 | New §6.1 Short-lived / renewable cert profile (edge mTLS): 1–24 h validity tier (default 6 h) for native-mode mTLS terminated at nps-ingress (NPS-RFC-0006 §6.3); renewal window = 25% remaining; ACME agent-01 online self-renewal; lifetime ≤ OCSP cache TTL so short validity is the primary revocation mechanism; OCSP-staple refresh interaction (NIP-OCSP-STAPLE-EXPIRED); resumption-ticket bounded to cert validity (NPS-RFC-0006 §6.4). Reuses existing error codes (NIP-CA-SESSION-VALIDITY-INVALID, NIP-CERT-EXPIRED); no new codes. |
| 0.10 | 2026-06-03 | IdentFrame.node_roles (string[], optional) — self-declared role tags, same vocabulary as NDP.AnnounceFrame.node_roles; Phase 3 gate against id-nps-node-roles X.509 extension (OID 65715.2.2); NIP-CERT-NODE-ROLES-MISMATCH error code. |
| 0.9 | 2026-05-31 | IdentFrame.ocsp_staple (base64url DER OCSPResponse): §5.1.4 stapling rules (signature verify, nextUpdate check, NIP-OCSP-STAPLE-EXPIRED); X.509 OID table: id-nid-assurance-level 65715.2.1, id-nps-node-roles 65715.2.2, id-nps-capabilities 65715.2.3 (PEN 65715 — NPS-CR-0004). |
| 0.8 | 2026-05-11 | Expanded §5.2 TrustFrame: added full field definition table (10 fields, including new required issued_at, serial, and signer_nid for revocation/audit traceability), explicit signature-canonicalisation rule (matching §5.1 IdentFrame), error sub-table, and full example. Added TrustFrame verification note to §7 (admit IdentFrames whose issued_by is a grantee_ca when a valid TrustFrame from a trusted grantor_nid covers the request). Four new error codes (§9): NIP-TRUST-FRAME-EXPIRED, NIP-TRUST-FRAME-GRANTOR-REVOKED, NIP-TRUST-FRAME-SCOPE-EXCEEDS-GRANTOR, NIP-TRUST-FRAME-NODES-PATTERN-INVALID. |
| 0.7 | 2026-05-07 | NPS-CR-0003: Orchestrator group NIDs and short-lived session NIDs. New §3.1 reserves group- / session- identifier prefixes on entity-type = agent. New signed IdentFrame.lineage object with role / parent_nid / group_nid / session_id / purpose / owner_user_id / owner_key_id (§5.1.3). New revocation reason parent_revoked (§5.3). New verification step 3a for chain-check (§7). Four new CA endpoints under /v1/orchestrators/groups/... (§8). Seven new error codes (§9): NIP-CA-GROUP-REVOKED, NIP-CA-PARENT-NOT-FOUND, NIP-CA-PARENT-NOT-GROUP, NIP-CA-SESSION-VALIDITY-INVALID, NIP-CA-JWS-INVALID, NIP-CA-JWS-EXPIRED, NIP-CERT-PARENT-REVOKED. Backward-compatible for ordinary single-NID flows; opt-in for orchestrators. |
| 0.6 | 2026-05-01 | Added topology:read to the standard capabilities registry (§5.1 capabilities table). This capability is required by Anchor Nodes at Phase 1–2 to gate access to topology read operations (topology.snapshot / topology.stream) as defined by the NPS-2 §12.4 minimum authorization binding (M6). Self-declared and key-signed at Phase 1–2; CA-attested role binding (id-nps-node-roles cert extension) deferred to Phase 3 pending RFC-0002 stabilization. |
| 0.5 | 2026-04-26 | Added §5.1.2 Reputation Log Entry — wire format for Certificate-Transparency-style append-only behavioral records about a subject_nid. Phase 1 ships the entry shape (12 fields including dual-signature requirements over JCS-canonicalised form), the initial 8-value incident enum (cert-revoked / rate-limit-violation / tos-violation / scraping-pattern / payment-default / contract-dispute / impersonation-claim / positive-attestation), and the 5-step severity enum. New error codes NIP-REPUTATION-ENTRY-INVALID and NIP-REPUTATION-LOG-UNREACHABLE. Merkle / STH / inclusion-proof surface deferred to Phase 2 per NPS-RFC-0004 §8.1. |
| 0.4 | 2026-04-25 | Added §5.1.1 Assurance Levels (anonymous / attested / verified); IdentFrame gains optional assurance_level field with backward-compatible default anonymous; new error codes NIP-ASSURANCE-MISMATCH and NIP-ASSURANCE-UNKNOWN. See NPS-RFC-0003. Depends-On NCP version corrected to v0.6 per NPS-RFC-0001. |
| 0.2 | 2026-04-12 | Unified port 17433; added metadata field to IdentFrame (tokenizer auto-match); error codes switched to NPS-status-code mapping; error-code list completed |
| 0.1 | 2026-04-10 | Initial spec: NID format, IdentFrame/TrustFrame/RevokeFrame, CA Server API, verification flow |
Copyright: LabAcacia / INNO LOTUS PTY LTD · Apache 2.0