macula_protocol behaviour (macula v0.20.5)

View Source

Behaviour defining the protocol that Macula mesh applications must implement.

Overview

This behaviour defines the contract that applications must implement to be considered "mesh-worthy" and allowed to participate in the Macula mesh network. The gatekeeper validates that apps implement this protocol before granting mesh access.

Why This Matters

Not every container or process should be allowed to join the mesh. This protocol ensures that: - Apps have proper identity (backed by certificates) - Apps declare their capabilities upfront - Apps can receive mesh events - Apps can be health-checked during sessions

Implementation

BEAM apps implement this as a behaviour. The implementation must export: - mesh_identity/0 - Returns the app's identity binary - mesh_capabilities/0 - Returns list of capabilities - mesh_api/0 - Returns map of topics, procedures, content_types - handle_mesh_event/2 - Handles incoming events - mesh_health/0 - Returns ok or error tuple

Non-BEAM apps implement equivalent gRPC or HTTP endpoints that the gatekeeper can probe.

Security Model

1. Identity must match the certificate's subject 2. Capabilities are validated against licenses at operation time 3. Health checks run periodically during sessions 4. Failed health checks may result in session termination

See also: macula_gatekeeper.

Summary

Types

Health check result

App identity, e.g., "io.macula.rgfaber.my-app"

Functions

Checks if a capability is valid.

Validates that an API spec is well-formed.

Validates that capabilities list is valid.

Validates that an identity is well-formed.

Types

api_spec/0

-type api_spec() :: #{topics => [binary()], procedures => [binary()], content_types => [binary()]}.

capability/0

-type capability() :: publish | subscribe | call | register | provide_content | consume_content.

health_status/0

-type health_status() :: ok | {error, term()}.

Health check result

identity/0

-type identity() :: binary().

App identity, e.g., "io.macula.rgfaber.my-app"

Callbacks

content_received/2

-callback content_received(ContentId :: binary(), Content :: binary()) -> ok | {error, term()}.

handle_mesh_event/2

-callback handle_mesh_event(Topic :: binary(), Payload :: term()) -> ok | {error, term()}.

handle_rpc_call/2

-callback handle_rpc_call(Procedure :: binary(), Args :: list()) -> {ok, term()} | {error, term()}.

mesh_api/0

-callback mesh_api() -> api_spec().

mesh_capabilities/0

-callback mesh_capabilities() -> [capability()].

mesh_health/0

-callback mesh_health() -> health_status().

mesh_identity/0

-callback mesh_identity() -> identity().

provide_content/1

-callback provide_content(ContentId :: binary()) -> {ok, binary()} | {error, term()}.

Functions

is_valid_capability(_)

-spec is_valid_capability(term()) -> boolean().

Checks if a capability is valid.

validate_api_spec(Spec)

-spec validate_api_spec(api_spec()) -> ok | {error, term()}.

Validates that an API spec is well-formed.

validate_capabilities(Caps)

-spec validate_capabilities([capability()]) -> ok | {error, term()}.

Validates that capabilities list is valid.

validate_identity(Identity)

-spec validate_identity(identity()) -> ok | {error, term()}.

Validates that an identity is well-formed.

Valid identities: - Are non-empty binaries - Contain at least 3 dot-separated segments - Each segment contains only alphanumeric characters and hyphens