Skip to content

AppledoreLabs/SPEED

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SPEED — Secure Process to Process Encrypted Exchange and Delivery RFC

0. Overview

SPEED is a secure inter-process communication (IPC) framework that enables communication between unrelated processes written in different programming languages, such as C++, Python, and Java.

Traditional cross-process communication often relies on tight language bindings, shared libraries, sockets, shared memory, or platform-specific mechanisms such as Unix pipes. These approaches can introduce complexity, portability issues, and deployment constraints.

SPEED takes a different approach by leveraging the filesystem as its transport layer. Since virtually every operating system supports reading and writing files, SPEED can exchange messages between unrelated processes without requiring direct language coupling or network infrastructure.

In addition to message passing, SPEED supports Speed Procedure Calls (SPC), a request-response mechanism that allows one Node to invoke a service exposed by another Node. For example, a C++ Node may invoke a Python service without using shared libraries or direct runtime integration.

SPEED uses libsodium for encryption and authentication. All participating Nodes in a communication environment MUST share the same pre-shared key (PSK), which is provided by the developer through a key file.

Note: SPEED does not guarantee message durability. When operating on volatile filesystems such as tmpfs, messages, registry entries, and protocol state may be lost during system shutdown, reboot, or power failure. Applications requiring durable message delivery SHOULD configure a persistent communication directory.


1. Technical Terms

1.1 Node

A Node is a single participant in a SPEED environment. Each Node corresponds to a running operating-system process hosting a SPEED runtime.

Nodes may be implemented in different programming languages and communicate through the SPEED protocol. Upon startup, a Node registers itself with the SPEED Registry so that other Nodes can discover and communicate with it.

1.2 Logical Group

A Logical Group is an optional organizational construct used to categorize related Nodes. This logical group is termed as Fabric.

Logical Groups do not participate in routing, discovery, security decisions, or address resolution. A Node MAY belong to one or more Logical Groups.

1.3 Link

A Link is a secure communication relationship between two Nodes.

Links provide authenticated and encrypted message exchange and serve as the logical communication path through which Envelopes are exchanged.

1.4 Envelope

An Envelope is the fundamental unit of communication in SPEED.

An Envelope contains protocol metadata, routing information, security metadata, encrypted payload data, and authentication information.

Examples include:

MESSAGE
SPC_REQUEST
SPC_RESPONSE
HEARTBEAT
ERROR
ACK

1.5 Envelope Header

The Envelope Header is the protocol-level metadata section contained within every Envelope.

The Envelope Header contains information required for routing, sequencing, validation, and processing.

Typical fields include:

Protocol Version
Envelope Type
Source Node
Target Node
Sequence Number
Timestamp
Payload Length

1.6 Payload

A Payload is the application-specific data contained within an Envelope.

Payload contents vary according to the Envelope Type. Examples include text messages, SPC requests, SPC responses, error information, and heartbeat data.

1.7 Service

A Service is an application-defined object capable of processing SPC requests.

Services implement the SPEED Service Interface and are responsible for executing application-specific business logic.

1.8 Service Registry

A Service Registry is an in-memory collection maintained by a Node containing all registered Services.

The Service Registry maps Service Names to Service instances and is used during SPC request processing. It SHALL NOT be persisted to disk.

1.9 Speed Procedure Call (SPC)

A Speed Procedure Call (SPC) is a request-response interaction in which one Node invokes a Service exposed by another Node.

SPC enables cross-language procedure invocation without requiring shared libraries, language bindings, network sockets, or direct runtime integration.

1.10 Registry

The SPEED Registry is a filesystem-based discovery mechanism responsible for maintaining metadata for active Nodes.

The Registry is used for:

  • Node discovery
  • Node registration
  • Node liveness detection
  • Address resolution

The Registry is not used for message transport.

1.11 Registry Lease

A Registry Lease represents the validity period of a Node registration.

Nodes periodically renew their lease by updating their registry entry. A lease that is not renewed within the configured timeout period is considered expired, and the corresponding Node is considered offline.

1.12 Heartbeat

A Heartbeat is a periodic update transmitted by a Node to renew its Registry Lease.

Heartbeats are used to determine Node liveness and to prevent stale registry entries from persisting indefinitely.

1.13 Service Name

A Service Name uniquely identifies a Service within a Node's Service Registry.

Service Names MUST be unique within a single Service Registry.

1.14 Node Name

A Node Name uniquely identifies a Node within a SPEED environment.

Node Names are used for discovery, addressing, message delivery, SPC invocation, and access control. No two active Nodes may share the same Node Name.

1.15 Request ID

A Request ID is a unique identifier associated with an SPC request.

Request IDs are used to correlate SPC requests with their corresponding SPC responses. Every SPC response MUST contain the Request ID of the originating SPC request.

1.16 Access Policy

An Access Policy defines which Nodes are permitted to interact with a Node or Service.

Access Policies are evaluated during SPC execution and message processing. Requests originating from unauthorized Nodes SHALL be rejected.

1.17 Authentication Tag

An Authentication Tag is cryptographic metadata generated by the Security Layer during encryption.

Authentication Tags are used to verify message authenticity and integrity. Messages with invalid Authentication Tags SHALL be discarded.

1.18 Nonce

A Nonce is a cryptographically secure value generated for each encrypted Envelope.

Nonces are used by the encryption algorithm to ensure uniqueness and to prevent attacks caused by encryption reuse. A Nonce MUST NOT be reused with the same encryption key.

1.19 Sequence Number

A Sequence Number is a monotonically increasing identifier associated with an Envelope.

Sequence Numbers are used to maintain per-sender ordering and support replay protection.

1.20 Envelope Type

The Envelope Type identifies the purpose and structure of an Envelope payload.

The Envelope Type determines how a receiving Node interprets and processes the payload.


2. Threading Model

SPEED utilizes a per-Node threading model to ensure reliable message processing and protocol isolation.

Each Node maintains its own runtime state, including the Service Registry, registry lease information, message queues, and sequence counters.

A conforming SPEED implementation SHALL provide:

2.1 Protocol Thread

Responsible for monitoring inbox directories, reading incoming Envelopes, verifying and decrypting messages, and dispatching messages and SPC requests.

2.2 Registry Thread

Responsible for Node registration, heartbeat updates, lease renewal, and registry maintenance.

2.3 SPC Worker Thread(s)

Responsible for executing registered Services, processing SPC requests, and generating SPC responses.

SPC requests SHALL NOT execute directly on the Protocol Thread in order to prevent long-running operations from blocking message processing.

2.4 Ordering Guarantees

SPEED guarantees per-sender FIFO ordering.

Messages originating from the same sender Node SHALL be processed in the order they were transmitted. Messages originating from different sender Nodes MAY be processed concurrently.

SPEED does not guarantee global ordering across multiple sender Nodes.

2.5 Thread Safety

All public SPEED APIs SHALL be thread-safe. Applications MAY invoke message delivery and SPC operations from multiple application threads concurrently.

The synchronization mechanisms used to achieve thread safety are implementation-defined.


3. Encryption and Authentication

Security is a first-class concern within SPEED. All Envelopes exchanged between Nodes MUST be encrypted and authenticated before being written to the filesystem.

SPEED relies on libsodium to provide a consistent cryptographic implementation across all supported programming languages.

3.1 Security Goals

The SPEED security model is designed to provide:

  • Confidentiality
  • Integrity
  • Authentication
  • Replay protection
  • Cross-language compatibility

3.2 Cryptographic Algorithm

SPEED uses the following authenticated encryption algorithm:

  • Algorithm: ChaCha20-Poly1305 (IETF variant)
  • Library: libsodium
  • Key Size: 256 bits (32 bytes)
  • Nonce Size: 96 bits (12 bytes)
  • Authentication Tag: 128 bits (16 bytes)

3.3 Pre-Shared Key (PSK)

SPEED operates using a Pre-Shared Key (PSK) model.

All Nodes participating in the same SPEED communication environment MUST possess the same encryption key. Key distribution is the responsibility of the application developer.

The encryption key SHALL be loaded from a key file during Node initialization.

Example:

speed.setKey("speed.key");

The key file MUST contain a valid 256-bit key encoded in Base64 format.

Example speed.key file:

SPEED-KEY-V1

q7x7Q1FxmFJ8hWx8g3r4i0N2mD4S3K9Yv0nV5P8Qz1U=

Future versions of the protocol MAY support automatic key negotiation and key rotation mechanisms.

3.4 Envelope Encryption Flow

Before transmission, an Envelope is constructed by the Protocol Layer.

The Security Layer then performs the following steps:

  1. Generate a cryptographically secure random nonce.
  2. Serialize the Envelope payload.
  3. Encrypt the payload using ChaCha20-Poly1305.
  4. Generate the authentication tag.
  5. Construct the final encrypted Envelope.
  6. Write the encrypted Envelope to the filesystem transport.

Upon receipt:

  1. The receiving Node loads the Envelope.
  2. The authentication tag is verified.
  3. The payload is decrypted.
  4. The Envelope is passed to the Protocol Layer for processing.
  5. Invalid Envelopes MUST be discarded immediately.

3.5 Nonce Requirements

A unique nonce MUST be generated for every Envelope encrypted using a given key.

Nonces SHALL be generated using a cryptographically secure random number generator provided by libsodium.

Reusing a nonce with the same encryption key is strictly prohibited and may compromise message confidentiality.

3.6 Replay Protection

Every Envelope SHALL contain:

  • Sequence Number
  • Timestamp
  • Nonce

The receiving Node MAY maintain a replay cache to detect duplicate or previously processed Envelopes.

Envelopes containing stale timestamps, reused nonces, or duplicate sequence numbers SHOULD be rejected.


4. SPEED Envelope

4.1 High-Level Structure

+-------------------------------+
|       SPEED Envelope          |
+-------------------------------+
|      Envelope Header          |
+-------------------------------+
|      Security Header          |
+-------------------------------+
|      Encrypted Payload        |
+-------------------------------+
|      Authentication Tag       |
+-------------------------------+

4.2 SPEED Envelope Header v1

Each SPEED Envelope Header v1 is exactly 64 bytes.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-------+-------+---------------+-------------------------------+
| Ver   | Type  | Flags         | Header Length                |
+-------+-------+---------------+-------------------------------+
|                       Sequence Number                         |
+---------------------------------------------------------------+
|                       Timestamp (ms)                          |
+---------------------------------------------------------------+
|                         Payload Size                          |
+---------------------------------------------------------------+
|                        Source Node ID                         |
|                                                               |
+---------------------------------------------------------------+
|                        Target Node ID                         |
|                                                               |
+---------------------------------------------------------------+

4.3 Header Field Breakdown

Field Size Description
Version 1 Byte SPEED protocol version
Envelope Type 1 Byte MESSAGE, SPC_REQUEST, SPC_RESPONSE, EVENT, DISCOVERY, HEARTBEAT, ERROR
Flags 2 Bytes Reserved
Header Length 4 Bytes Header size
Sequence Number 8 Bytes Sender sequence counter
Timestamp 8 Bytes Unix timestamp (ms)
Payload Size 8 Bytes Encrypted payload size
Source Node ID 16 Bytes UUID
Target Node ID 16 Bytes UUID

4.4 Envelope Types

enum class EnvelopeType : uint8_t {
    MESSAGE      = 1,
    SPC_REQUEST  = 2,
    SPC_RESPONSE = 3,
    EVENT        = 4,
    DISCOVERY    = 5,
    HEARTBEAT    = 6,
    ERROR        = 7,
    ACK          = 8
};

4.5 Envelope Semantics

All SPEED traffic uses the same Envelope Header format. The Envelope Type determines how the payload is interpreted by the receiving Node.


5. Node Identity and Naming

Every Node participating in a SPEED environment MUST possess a unique Node Name.

A Node Name serves as the primary identifier used for discovery, routing, access control, message delivery, and SPC invocation. Because Node Names are used directly by application developers when addressing Nodes, they MUST be globally unique within a SPEED communication environment.

Examples:

billing
analytics
python_worker
java_backend

The following is invalid:

billing
billing

Two active Nodes MAY NOT share the same Node Name, regardless of their implementation language or logical grouping.

Node Names SHOULD be human-readable and descriptive of the functionality provided by the Node.

Node Names MUST remain stable for the lifetime of the Node instance.

5.1 Node Addressing

All message delivery operations within SPEED are performed using Node Names.

Examples:

speed.send("billing", message);

speed.call(
    "analytics",
    "generateReport",
    arguments
);

Because Node Names are globally unique, no additional namespace, fabric identifier, or routing qualifier is required during message delivery.


6. SPEED Registry

The SPEED Registry is a filesystem-based discovery mechanism responsible for maintaining the list of all active Nodes participating in a SPEED environment.

The Registry exists solely for Node discovery and address resolution. It MUST NOT be used for message transport, message storage, or application-level communication.

6.1 Registry Location

Within a SPEED communication directory, a dedicated registry directory SHALL exist:

speed/
├── speed_registry/
├── billing/
├── analytics/
└── python_worker/

The speed_registry directory contains metadata describing all active Nodes currently participating in the SPEED environment.

6.2 Registry Structure

Each active Node SHALL register itself by creating a registry entry within the speed_registry directory.

Example:

speed_registry/
├── billing.node
├── analytics.node
└── python_worker.node

Each registry entry contains metadata describing the corresponding Node.

Example:

{
  "name": "billing",
  "status": "online",
  "startupTimestamp": 1754371268
}

The exact serialization format is implementation-defined but MUST remain consistent across all SPEED language bindings.

6.3 Node Registration

Upon startup, a Node SHALL:

  1. Validate that its Node Name is not already registered.
  2. Create its registry entry.
  3. Advertise its availability to other Nodes.
  4. Begin accepting incoming Envelopes.

If a registry entry with the same Node Name already exists, Node initialization MUST fail.

This guarantees global uniqueness of Node Names within the SPEED environment.

6.4 Node Deregistration and Lease Expiration

SPEED does not rely solely on graceful shutdown for Node removal. Since operating-system processes may terminate unexpectedly due to crashes, forced termination, power failures, or other abnormal conditions, a Node cannot be trusted to always remove its registry entry before exiting.

To address this, the SPEED Registry uses a lease-based registration model.

6.4.1 Registry Lease

Every Node registration is associated with a lease. A lease represents the maximum amount of time a Node may remain inactive before being considered offline.

Upon successful registration, a Node SHALL periodically renew its lease by updating its registry entry.

Example:

{
  "name": "billing",
  "pid": 1234,
  "startupTimestamp": 1754371268,
  "lastHeartbeat": 1754371270
}

The lastHeartbeat field indicates the most recent successful lease renewal performed by the Node.

6.4.2 Heartbeat Renewal

Each active Node MUST periodically refresh its registry entry by updating its heartbeat timestamp.

Example:

Lease Duration: 30 seconds
Heartbeat Interval: 5 seconds

The exact values are implementation-defined but SHOULD be configurable.

A Node that fails to refresh its lease within the configured lease duration SHALL be considered inactive.

6.4.3 Stale Node Detection

A registry entry becomes stale when:

Current Time - Last Heartbeat > Lease Duration

When a stale entry is detected, the Node represented by that registry entry SHALL be considered offline.

Any participating Node MAY remove stale registry entries from the SPEED Registry.

6.4.4 Process Identifier (PID)

In addition to lease information, implementations MAY store the operating-system Process Identifier (PID) associated with a Node.

Example:

{
  "name": "billing",
  "pid": 1234,
  "lastHeartbeat": 1754371270
}

The PID is intended to assist with diagnostics, monitoring, and accelerated stale-entry detection.

For example, when a new Node attempts to register using a Node Name that already exists, an implementation MAY verify whether the recorded PID is still active on the local operating system.

If the recorded PID no longer exists, the stale registry entry MAY be removed immediately without waiting for lease expiration.

6.4.5 PID Limitations

Operating-system process identifiers are not guaranteed to remain unique over time and may be reused by the operating system.

Consequently, PID values MUST NOT be treated as authoritative proof that a Node is alive.

The registry lease and heartbeat mechanism SHALL remain the primary source of truth for determining Node liveness.

6.4.6 Graceful Deregistration

Before shutting down, a Node SHOULD remove its registry entry from the SPEED Registry.

Example shutdown sequence:

  1. Stop accepting incoming Envelopes.
  2. Complete any in-flight processing.
  3. Remove the registry entry.
  4. Release filesystem resources.
  5. Broadcast a leave/exit notification.
  6. Terminate.

Graceful deregistration is an optimization and SHOULD reduce registry cleanup time. However, correctness of the SPEED Registry MUST NOT depend on graceful deregistration.

6.5 Node Recovery

If a Node crashes unexpectedly, its registry entry may remain present in the registry.

When the Node is restarted, SPEED SHALL determine whether the existing registry entry is stale using:

  1. PID validation (optional).
  2. Lease expiration validation (mandatory).

If the entry is determined to be stale, the new Node instance MAY reclaim the Node Name and create a fresh registry entry.

This mechanism prevents zombie registrations from permanently blocking Node Names while ensuring reliable recovery from unexpected process failures.

6.6 Logical Grouping

SPEED supports the concept of logical grouping as a mechanism for organizing Nodes according to application-specific requirements.

Logical Groups are informational constructs and do not participate in addressing, routing, discovery, security, or message delivery.

Examples of logical groups include:

Finance
Analytics
Monitoring
Backend Services

A Node MAY belong to one or more Logical Groups.

Examples:

billing
    ├── Finance
    └── Backend Services

analytics
    └── Analytics

Logical Groups are intended for management, monitoring, filtering, and organizational purposes only.

Message delivery SHALL always occur using the globally unique Node Name and SHALL NOT require group membership information.

Consequently, the following operation remains valid regardless of any logical grouping configuration:

speed.send("billing", message);

Logical Groups do not affect Node identity and MUST NOT introduce addressing ambiguity within the SPEED environment.


7. Speed Procedure Calls (SPC)

Speed Procedure Calls (SPC) provide a mechanism for one Node to invoke functionality exposed by another Node within a SPEED environment.

SPC is conceptually similar to Remote Procedure Calls (RPC), however SPC operates entirely through the SPEED protocol and filesystem transport layer without requiring network sockets, shared libraries, language bindings, or runtime coupling between participating Nodes.

SPC enables cross-language procedure invocation. For example, a C++ Node may invoke functionality exposed by a Python Node, and vice versa.

All SPC communication SHALL be transmitted through standard SPEED Envelopes and SHALL be subject to the same authentication, encryption, and access-control mechanisms as ordinary message delivery.

7.1 Service Registry

Each Node SHALL maintain an in-memory Service Registry.

The Service Registry contains all services that have been explicitly exposed for remote invocation through SPC.

A Service is an application-defined object responsible for processing incoming SPC requests.

Services MUST be explicitly registered by the application developer before they become accessible to remote Nodes.

Example:

class TaxService : public SpeedService {
public:
    SpeedResponse invoke(
        const SpeedRequest& request
    ) override {

        int amount =
            request.get<int>("amount");

        return {
            {"tax", amount * 0.18}
        };
    }
};

TaxService tax;

speed.register(
    "calculateTax",
    &tax
);

Upon registration, the service instance is added to the local Service Registry.

Example:

Service Registry

calculateTax
generateInvoice
validateUser

The Service Registry SHALL exist only in memory and SHALL NOT be persisted to disk.

7.2 Speed Service Interface

All SPC services SHALL implement the SPEED Service Interface.

Example:

class SpeedService {
public:
    virtual SpeedResponse invoke(
        const SpeedRequest& request
    ) = 0;

    virtual ~SpeedService() = default;
};

The invoke() method serves as the entry point for all SPC requests targeting the service.

When an SPC request is received, SPEED SHALL locate the corresponding service and invoke its invoke() method.

The service implementation is responsible for:

  • Processing request arguments.
  • Executing application-specific business logic.
  • Constructing the response payload.
  • Returning a valid SpeedResponse.

7.3 Service Registration

Services are registered using the SPEED API.

Example:

TaxService tax;

speed.register(
    "calculateTax",
    &tax
);

Optionally, an access policy MAY be specified:

TaxService tax;

speed.register(
    "calculateTax",
    &tax,
    {
        "billing",
        "analytics"
    }
);

In this example, only the Nodes billing and analytics are permitted to invoke the service.

Attempting to invoke the service from any other Node SHALL result in an ACCESS_DENIED error.

7.4 SPC Request

A Node initiates an SPC by transmitting an Envelope of type:

SPC_REQUEST

The request payload SHALL contain:

Field Description
Request ID Unique request identifier
Service Name Target service
Arguments Service arguments
Caller Node Name Requesting Node

Example:

{
  "requestId": "123",
  "service": "calculateTax",
  "arguments": {
    "amount": 1000
  }
}

The Request ID SHALL uniquely identify the request and SHALL be used to correlate the corresponding SPC response.

7.5 SPC Request Processing

Upon receiving an SPC request, a Node SHALL perform the following steps:

  1. Verify Envelope authenticity.
  2. Verify sender authorization.
  3. Locate the target service in the Service Registry.
  4. Validate service access policy.
  5. Deserialize request arguments.
  6. Construct a SpeedRequest object.
  7. Invoke the service's invoke() method.
  8. Construct a SpeedResponse object.
  9. Serialize the response.
  10. Generate an SPC response Envelope.

If any step fails, an SPC error response SHALL be generated.

7.6 SPC Response

Upon successful execution, the target Node SHALL return an Envelope of type:

SPC_RESPONSE

The response payload SHALL contain:

Field Description
Request ID Original request identifier
Status Execution result
Result Serialized response payload

Example:

{
  "requestId": "123",
  "status": "SUCCESS",
  "result": {
    "tax": 180
  }
}

The Request ID contained within the SPC response MUST match the Request ID of the originating SPC request.

7.7 SPC Errors

If a request cannot be completed, the receiving Node SHALL return an error response.

Example:

{
  "requestId": "123",
  "status": "ERROR",
  "errorCode": "SERVICE_NOT_FOUND"
}

Standard SPC error codes include:

Error Code Description
SERVICE_NOT_FOUND Target service is not registered
ACCESS_DENIED Sender is not authorized
INVALID_ARGUMENTS Request arguments are invalid
EXECUTION_FAILED Service execution failed
TIMEOUT Service execution exceeded timeout
INTERNAL_ERROR Unexpected internal error

7.8 Service Naming

Service names SHALL be unique within a Node's Service Registry.

Valid:

calculateTax
generateInvoice
validateUser

Invalid:

calculateTax
calculateTax

Attempting to register multiple services using the same name SHALL fail.

Service names SHOULD be human-readable and descriptive of the functionality they expose.

7.9 Service Lifecycle

A service remains available for remote invocation for the lifetime of the hosting Node.

When a Node terminates, crashes, or leaves the SPEED environment, all services registered within its Service Registry immediately become unavailable.

Because the Service Registry exists entirely in memory, service registrations SHALL NOT survive Node restarts and MUST be re-registered during Node initialization.

7.10 Security Considerations

SPC does not automatically expose arbitrary application methods or class members.

Only services explicitly registered through the SPEED API become remotely invokable.

SPEED SHALL NOT perform reflection, runtime method discovery, or automatic service exposure. All remotely invokable functionality MUST be intentionally registered by the application developer.

7.11 SPC Envelope Structure

SPC requests and responses are transmitted using standard SPEED Envelopes.

SPC does not define a separate transport header. Instead, SPC extends the SPEED Envelope model by utilizing dedicated Envelope Types and SPC-specific payload structures.

The SPEED Envelope Header SHALL remain identical for all Envelope Types.

Example:

Envelope Header
├── Protocol Version
├── Envelope Type
├── Source Node Name
├── Target Node Name
├── Sequence Number
├── Timestamp
└── Payload Length

The Envelope Type determines how the payload is interpreted by the receiving Node.

Examples:

MESSAGE
SPC_REQUEST
SPC_RESPONSE
ERROR
HEARTBEAT

The receiving Node SHALL first process the Envelope Header and then dispatch the payload to the appropriate protocol handler based on the Envelope Type.

7.11.1 SPC Request Envelope

Envelope Header
│
├── Envelope Type = SPC_REQUEST
│
└── SPC Request Payload
     ├── Request ID
     ├── Service Name
     └── Arguments

7.11.2 SPC Response Envelope

Envelope Header
│
├── Envelope Type = SPC_RESPONSE
│
└── SPC Response Payload
     ├── Request ID
     ├── Status
     └── Result

7.11.3 Standard Message Envelope

Envelope Header
│
├── Envelope Type = MESSAGE
│
└── Message Payload
     └── Application Data

Although SPC Requests, SPC Responses, and standard messages contain different payload formats, all communication within SPEED SHALL utilize the same Envelope Header format.

This design ensures consistent parsing, simplifies implementation, and allows future protocol extensions without requiring additional transport-level headers.

7.12 Comparison of Message and SPC Envelopes

The following table illustrates the distinction between standard message delivery and Speed Procedure Calls.

Component Standard Message SPC Request SPC Response
Envelope Header Yes Yes Yes
Security Header Yes Yes Yes
Authentication Tag Yes Yes Yes
Request ID No Yes Yes
Service Name No Yes No
Arguments No Yes No
Execution Result No No Yes
Application Data Yes Optional Optional

The transport and security layers treat all Envelope Types identically.

The primary distinction between standard messaging and SPC communication exists exclusively within the payload structure and application-level processing logic.

Consequently, SPC is not a separate transport mechanism but rather a higher-level protocol built upon the standard SPEED Envelope model.


8. Threading Model

SPEED utilizes a per-Node threading model to ensure reliable message processing and protocol isolation.

Each Node maintains its own runtime state, including the Service Registry, registry lease information, message queues, and sequence counters.

A conforming SPEED implementation SHALL provide:

8.1 Protocol Thread

Responsible for monitoring inbox directories, reading incoming Envelopes, verifying and decrypting messages, and dispatching messages and SPC requests.

8.2 Registry Thread

Responsible for Node registration, heartbeat updates, lease renewal, and registry maintenance.

8.3 SPC Worker Thread(s)

Responsible for executing registered Services, processing SPC requests, and generating SPC responses.

SPC requests SHALL NOT execute directly on the Protocol Thread in order to prevent long-running operations from blocking message processing.

8.4 Ordering Guarantees

SPEED guarantees per-sender FIFO ordering.

Messages originating from the same sender Node SHALL be processed in the order they were transmitted. Messages originating from different sender Nodes MAY be processed concurrently.

SPEED does not guarantee global ordering across multiple sender Nodes.

8.5 Thread Safety

All public SPEED APIs SHALL be thread-safe. Applications MAY invoke message delivery and SPC operations from multiple application threads concurrently.

The synchronization mechanisms used to achieve thread safety are implementation-defined.


9. Access Control

The Access Control Layer governs communication permissions between Nodes participating in a SPEED environment.

Access Control determines which Nodes are permitted to exchange Envelopes, invoke SPC services, and establish communication relationships.

The Access Control Layer is evaluated before message transmission, message reception, SPC request processing, and SPC response processing.

Access Control operates independently from Node discovery.

Node discovery is performed through the SPEED Registry, while communication authorization is performed through the Access Registry.

9.1 Access Registry

Each Node maintains an in-memory Access Registry.

The Access Registry contains the names of Nodes that are authorized communication partners for the local Node.

Example:

speed.allow("NodeB");
speed.allow("NodeC");

Node A Access Registry:

NodeB
NodeC

This configuration indicates that Node A is permitted to communicate with Node B and Node C.

The Access Registry does not imply that the authorized Nodes currently exist.

Node existence is determined separately through the SPEED Registry.

9.2 Discovery and Authorization

SPEED separates discovery from authorization.

Before communication can occur, two conditions must be satisfied:

  1. The target Node must exist within the SPEED Registry.
  2. The target Node must be authorized by the Access Registry.

Example:

Node A Access Registry:
NodeB

SPEED Registry:
NodeA

Result:

Node B is authorized
Node B is not available
Communication cannot occur

When Node B subsequently joins the SPEED environment and registers itself, communication becomes possible.

9.3 Registry Monitoring

Nodes SHALL continuously monitor the SPEED Registry for Node registration and lease updates.

When a new Node joins the SPEED environment, it registers itself within the Registry and becomes discoverable by all participating Nodes.

Example:

Node B Starts
    ↓
Registers with SPEED Registry
    ↓
Registry Entry Created
    ↓
Other Nodes Observe Registration

This allows Nodes to dynamically discover authorized communication partners as they become available.

Similarly, when a Node leaves the environment or its lease expires, the Registry reflects its departure and communication with that Node becomes unavailable.

9.4 Capability-Based Security

SPEED uses a capability-based security model for write-side communication.

A Node MAY transmit an Envelope to another Node only if the destination Node explicitly advertises authorization for the sender.

In this model, the receiver owns the inbox and controls who may write to it. A sender MUST treat the destination Node's published capability set as the source of truth.

This approach prevents unauthorized Nodes from writing into another Node's inbox and avoids inbox pollution by rejecting unauthorized sends before any filesystem write occurs.

Example:

  • Node A is permitted by Node B only if Node B advertises Node A in its Access Registry.
  • If Node A is not listed, Node A MUST NOT write to Node B's inbox.

9.5 Outbound Authorization

Before transmitting an Envelope, a Node SHALL verify that the destination Node authorizes the sender.

If the destination Node does not authorize the sender, the Envelope SHALL NOT be transmitted.

Example processing:

Sender Node
    ↓
Check destination's access capability
    ↓
Authorized?
    ├── Yes → Transmit Envelope
    └── No  → Reject Request

9.6 Inbound Authorization

Upon receiving an Envelope, a Node SHALL validate the sender Node against its Access Registry.

Unauthorized Envelopes SHALL be discarded immediately, and no application-level processing shall occur.

9.7 Independent Authorization

Authorization within SPEED is directional.

Permission granted by one Node does not automatically grant permission in the opposite direction.

Example:

Node A allows Node B
Node B does not allow Node A

This configuration permits:

Node A → Node B

but does not permit:

Node B → Node A

Each Node independently defines its own communication policy.

9.8 Access Control and SPC

The Access Control Layer SHALL be evaluated before SPC requests are processed.

When an SPC request is received, access validation SHALL occur before service lookup and service execution. Unauthorized Nodes SHALL be rejected with an ACCESS_DENIED error.

9.9 Default Policy

The default SPEED access policy is:

Deny All

A Node SHALL NOT communicate with any other Node unless explicit authorization has been granted.

Applications MUST explicitly authorize communication partners using the SPEED API.

Example:

speed.allow("NodeB");
speed.allow("NodeC");

Only the specified Nodes become eligible communication partners.

9.10 Security Considerations

The Access Control Layer provides protocol-level communication isolation between Nodes.

Even if a Node successfully discovers another Node through the SPEED Registry and possesses a valid encryption key, communication SHALL NOT be permitted unless the destination Node explicitly authorizes that communication.

This ensures that discovery, encryption, and authorization remain independent security mechanisms within the SPEED architecture.

About

SPEED - Secure Process to Process Encrypted Exchange and Delivery

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors