@hyperfrontend/network-protocol/securitySecurity
Purpose
The Security module defines what a security protocol implements: the per-session seal and open operations, the session a protocol is bound to, the outcome of accepting a hello frame, and the machine-readable error a protocol raises when it rejects a frame or a session.
Key Interfaces
SecuritySuite<T>
The two per-session packet operations.
interface SecuritySuite<T = any> {
readonly seal: PacketSealer<T> // (packet: UnencryptedPacket<T>) => Promise<WirePacket>
readonly open: PacketOpener<T> // (frame: WirePacket) => Promise<UnencryptedPacket<T>>
}
PacketSealer and PacketOpener are re-exported from packet/.
ProtocolSession and SessionRole
What a protocol needs to key one session. The key material itself is minted by the protocol and exchanged through hello frames once the session exists.
type SessionRole = 'initiator' | 'responder'
interface ProtocolSession {
readonly protocol: string // The negotiated protocol identifier, e.g. 'v3'
readonly role: SessionRole // Which side of the handshake this endpoint played
readonly localId: string // This endpoint's identity as stamped on packets
readonly peerId: string // The peer's identity as stamped on packets
}
HelloOutcome
type HelloOutcome = 'accepted' | 'duplicate' | 'rejected'
| Outcome | Meaning |
|---|---|
accepted | The peer's material is now known and the session can be keyed |
duplicate | The same material was already accepted; a retry, ignored |
rejected | The frame is not a hello this session can use |
ProtocolError
interface ProtocolError extends Error {
readonly code: ProtocolErrorCode // Why the protocol rejected the input
}
The error's name is 'ProtocolError'.
Error Codes
const ProtocolErrorCode = {
UnsupportedVersion: 'unsupported-version',
Replayed: 'replayed',
AuthenticationFailed: 'authentication-failed',
Malformed: 'malformed',
CounterExhausted: 'counter-exhausted',
InvalidSession: 'invalid-session',
} as const
type ProtocolErrorCode = (typeof ProtocolErrorCode)[keyof typeof ProtocolErrorCode]
| Code | Meaning |
|---|---|
unsupported-version | The frame's version byte is not this protocol's |
replayed | The frame's counter is not above the last accepted one |
authentication-failed | The frame's tag does not verify under the session's keys |
malformed | The frame is too short, or authenticated but does not carry a packet |
counter-exhausted | The session has sealed every counter value it can represent |
invalid-session | The session cannot be keyed from the material it holds |
Functions
createProtocolError
function createProtocolError(code: ProtocolErrorCode, message: string): ProtocolError
import { createProtocolError, ProtocolErrorCode } from '@hyperfrontend/network-protocol/security'
throw createProtocolError(ProtocolErrorCode.Replayed, 'Frame counter 7 is not above the last accepted counter 9')
getProtocolErrorCode
Reads the code off any thrown value, or returns null when the value is not a protocol error.
function getProtocolErrorCode(error: unknown): ProtocolErrorCode | null
import { getProtocolErrorCode } from '@hyperfrontend/network-protocol/security'
const channel = createChannel('comms', {
...options,
onDrop: (drop) => {
const code = getProtocolErrorCode(drop.cause)
if (code === 'authentication-failed' || code === 'replayed') {
alarm(drop)
}
},
})
Where the Pieces Meet
A protocol (see protocol/) implements the suite for one session; a channel (see channel/) runs it; every rejection reaches the owner as the cause of a PacketDrop.
Relationship to Other Modules
See Also
- Library Index - All modules
- Architecture Guide - Security architecture
- Security Entry - The
@hyperfrontend/network-protocol/securityentry
Related Modules
| Module | Relationship |
|---|---|
| protocol/ | Implements the suite and raises the errors |
| channel/ | Binds a session and surfaces drops |
| packet/ | The packet shapes the operations convert |
API Reference§
ƒ Functions
Parameters
| Name | Type | Description |
|---|---|---|
§code | ProtocolErrorCode | Why the protocol rejected the input |
§message | string | Human-readable detail |
Returns
ProtocolErrorcode survives the pipeline's drop reportExample
Rejecting a replayed frame
throw createProtocolError('replayed', 'Frame counter 7 is not above the last accepted counter 9')Parameters
| Name | Type | Description |
|---|---|---|
§error | unknown | Any thrown value |
Returns
ProtocolErrorCodeExample
Mapping a drop to its cause
getProtocolErrorCode(drop.cause)
// => 'authentication-failed'◈ Interfaces
Properties
Properties
Properties
◆ Types
type PacketOpener = (packet: WirePacket) => Promise<UnencryptedPacket<T>>type PacketSealer = (packet: UnencryptedPacket<T>) => Promise<WirePacket>type ProtocolErrorCode = indexedAccessaccepted: the peer's material is now known and the session can be keyedduplicate: the same material was already accepted; a retry, ignoredrejected: the frame is not a hello this session can use
type HelloOutcome = "accepted" | "duplicate" | "rejected"type SessionRole = "initiator" | "responder"● Variables
unsupported-version: the frame's version byte is not this protocol'sreplayed: the frame's counter is not above the last accepted oneauthentication-failed: the frame's tag does not verify under the session's keysmalformed: the frame authenticated but does not carry a packetcounter-exhausted: the session has sealed every counter value it can representinvalid-session: the session cannot be keyed from the material it holds