Skip to main content

Protocollo di comunicazione sicura tra microservizi

Project description

MESS

[ ] Un protocollo di comunicazione tra microservizi
[ ] Un esercizio di ragionamento per scrivere codice senza(*) AI e restare a contatto con il prodotto
[ ] Un modo pratico di rispolverare le logiche di rete a basso livello e la loro implementazione in python
[X] Tutte le precedenti

*in realtà per pulizia, miglioramento sintassi e test l'AI è stata usata

MESS riprende lo stile di HTTP/1.1 (header testuali separati da \r\n, body binario, Content-Length per il framing, connessioni keep-alive) ma aggiunge un meccanismo di auditing non aggirabile per costruzione crittografica: ogni Request viene cifrata con una chiave per-messaggio depositata al Compliance Collector. Il Receiver puo decifrarla solo dopo aver ottenuto la chiave dal Collector, che la rilascia solo se la Compliance e stata registrata.

Se il Collector e giu, la chiave non viene mai depositata e il ciphertext resta matematicamente indecifrabile: fail-stop, niente "best-effort" sull'audit.

Flusso end-to-end

sender                    collector                receiver
  |                          |                        |
  |-- 1. Pre-Compliance ---->|                        |
  |       (key, nonce, md)   |                        |
  |<------- 2. Ack ----------|                        |
  |                          |                        |
  |-------- 3. Encrypted Request (ciphertext) ------->|
  |                          |                        |
  |                          |<-- 4. KEY_FETCH -------|
  |                          |       (request_id)     |
  |                          |---- 5. {key,nonce} --->|
  |                          |                        |
  |                          |              [decifra + handler]
  |                          |                        |
  |<------------ 6. Response (plaintext) -------------|
  |                          |                        |
  |                          |<-- 7. Post-Compliance -|
  |                          |   (fire-and-forget)    |

Il diagramma editabile e in docs/sequence.excalidraw (apribile su excalidraw.com o nelle estensioni IDE).

Formato del messaggio

Newline \r\n, doppio \r\n tra header e body.

Request / Response / Error / KeyFetch

MESS/1.0
Mess-Event: Request | Response | Error | KeyFetch | Compliance
Mess-Sender: <servicename>
Mess-Request-Id: <uuid4>
Mess-Timestamp: <iso8601>
Content-Type: JSON | XML | TXT
Content-Length: <int>
Mess-Body-Hash: sha256=<hex>
Mess-Encrypted: aes-256-gcm        (solo per Request cifrate)
Mess-Nonce: <base64>               (solo per Request cifrate)

<body>      # ciphertext+tag se Mess-Encrypted, altrimenti plaintext

Compliance verso il Collector

Due fasi distinte (decise dal campo phase nel body):

Pre-Compliance (sender -> collector, prima di mandare al receiver):

{
  "phase": "pre",
  "key": "<hex>",
  "nonce": "<hex>",
  "request_metadata": { ...header del Mess Request originale... }
}

Post-Compliance (receiver -> collector, dopo aver risposto al sender):

{
  "phase": "post",
  "request_metadata":  { ... },
  "response_metadata": { ... }
}

Validazione di ogni messaggio in arrivo:

  • Content-Length: byte ricevuti = dichiarati.
  • Mess-Body-Hash: SHA-256 del body = dichiarato.
  • AES-GCM tag (per i ciphertext): autenticato con AAD = request_id.

Layout del codice

mess/
  protocol/
    models.py        # Mess, MessEvent, ContentType, factory compliance
    message.py       # encode/decode payload (JSON/XML/TXT)
    socket_io.py     # framing: read_message / write_message
    crypto.py        # wrapper AES-256-GCM
    pool.py          # ConnectionPool keep-alive
    exceptions.py    # MessError + sottoclassi
    sender.py        # MessSender: client TCP, two-phase send
    receiver.py      # MessReceiver: server TCP, key-fetch + post-compliance async
    collector.py     # ComplianceCollector: state machine in-memory
  helpers/
    quick.py         # send / serve / run_collector / decode (one-call)
    service.py       # Service: config persistente + from_env

examples/             # esempi end-to-end self-contained
  run_collector.py     # collector standalone (companion dei due sotto)
  echo_server.py       # server in un processo dedicato
  echo_client.py       # client che parla col server
  with_service.py      # tutti i 3 ruoli in un solo processo via Service
  compliance_failure.py # demo del fail-stop quando il collector e giu

docs/
  presentation.md / .pdf
  sequence.excalidraw

Eccezioni

Tutto eredita da MessError:

Eccezione Quando viene sollevata
MessProtocolError Versione, separator o header malformati.
MessIntegrityError Content-Length o body-hash non corrispondono.
MessEncodingError Encoding o decoding del payload fallito.
MessTransportError Errore socket: connessione chiusa, timeout, refused.
MessComplianceError Pre-compliance verso il Collector fallita (sender-side).
MessCryptoError Cifratura/decifratura fallita (incluso tag GCM non valido).
MessKeyUnavailableError Collector non ha (ancora) la chiave per il request_id.

Quickstart

Avvia un Collector standalone:

from mess.helpers import run_collector
run_collector(port=9001)

Server:

from mess.helpers import serve

def handler(body):
    return {"echo": body}

serve(port=9000, handler=handler, name="echo-svc",
      collector=("127.0.0.1", 9001))

Client:

from mess.helpers import send, decode

response = send("127.0.0.1", 9000, {"hello": "world"},
                sender="my-client",
                collector=("127.0.0.1", 9001))
print(decode(response))

Service: configurazione persistente + keep-alive

Service raggruppa identita, indirizzo di bind e Collector. Il sender interno mantiene un pool di connessioni TCP riusate tra .send() consecutive verso lo stesso target.

from mess.helpers import Service

svc = Service(
    name="echo-svc",
    host="0.0.0.0", port=9100,
    collector=("collector", 9101),
)

svc.serve(my_handler, block=False)
svc.send("other-svc", 9100, {"msg": "ciao"})

Speedup misurato in loopback: con keep-alive 10 request usano 2 socket totali (1 verso receiver + 1 verso collector) contro ~20 in modalita one-shot, con un guadagno di latenza ~3x.

Configurazione da environment (Docker)

Service.from_env(prefix="MESS") legge la config da variabili d'ambiente, pattern naturale per servizi in Docker.

Variabile Obbligatoria Descrizione
MESS_NAME Identita del servizio (sender/service_name).
MESS_COLLECTOR Collector nel formato host:port.
MESS_HOST no Bind host del receiver. Es. 0.0.0.0.
MESS_PORT no Bind port del receiver.
MESS_TIMEOUT no Timeout sender in secondi (float, default 5).

Esempio docker-compose.yml:

services:
  echo:
    environment:
      MESS_NAME: echo-svc
      MESS_HOST: 0.0.0.0
      MESS_PORT: 9100
      MESS_COLLECTOR: collector:9101
  collector:
    environment:
      MESS_NAME: compliance-collector
      MESS_HOST: 0.0.0.0
      MESS_PORT: 9101

Nel codice:

from mess.helpers import Service
svc = Service.from_env()
svc.serve(my_handler)

Garanzie del modello encryption-gated

  • Audit non aggirabile: nessuna richiesta puo essere processata se la Compliance Pre non e stata registrata. Il Receiver, anche bacato o malevolo, non puo "saltare" la registrazione.
  • Confidenzialita in transito: il body Request viaggia cifrato AES-256-GCM. Mess-Sender e Mess-Request-Id rimangono in chiaro (servono per il routing).
  • Tamper evidence: AAD = request_id, qualsiasi alterazione di ciphertext o request-id invalida il tag GCM -> MessCryptoError.
  • Per-message key: chiave random 256-bit per ogni messaggio. La compromissione di una chiave non si propaga.
  • Fail-stop sul collector down: se il Collector e irraggiungibile, MessComplianceError immediato lato sender; nulla viene inviato al receiver; il messaggio non esiste, fine.

Test

pip install -e ".[dev]"
pytest tests/

55 test su 6 file (test_models, test_crypto, test_message, test_pool, test_service, test_e2e) coprono protocollo (round-trip, integrita, framing), cifratura (AES-GCM tag, AAD), pool keep-alive, configurazione da env, e flusso end-to-end (round-trip cifrato, pre/post compliance, collector down, tampering, refusal della plaintext).

Stato

Versione 0.0.1. Implementati: protocollo, framing, sender, receiver, collector con state machine, helpers, configurazione da env, keep-alive, encryption-gating AES-256-GCM, test automatizzati. Da fare: TLS sui socket, retry/backoff sul Collector lato sender, persistenza al Collector.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mess_protocol-0.0.3.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mess_protocol-0.0.3-py3-none-any.whl (21.9 kB view details)

Uploaded Python 3

File details

Details for the file mess_protocol-0.0.3.tar.gz.

File metadata

  • Download URL: mess_protocol-0.0.3.tar.gz
  • Upload date:
  • Size: 18.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mess_protocol-0.0.3.tar.gz
Algorithm Hash digest
SHA256 007c75fa8ec69290e197323d174d4bbc99c697a3fe16f3ef6174086753957974
MD5 bea2d731bd61e7f5fdbdd9fbc555f9ae
BLAKE2b-256 69a41160b1a2867be9979f16a424639827f3fe31ad7e6e576bac93e6ca2d79b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for mess_protocol-0.0.3.tar.gz:

Publisher: publish.yml on lorenzomoglia/mess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mess_protocol-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: mess_protocol-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 21.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mess_protocol-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0239f32410955dca4a4d777f42e23c460b5e594d76ae61ccf48904f90f15a657
MD5 5282ba9853c0b086281987ec675bd523
BLAKE2b-256 55fd55b29bcb434329a936b96cdf72168193f9942f68ce27fe4673058ae43054

See more details on using hashes here.

Provenance

The following attestation bundles were made for mess_protocol-0.0.3-py3-none-any.whl:

Publisher: publish.yml on lorenzomoglia/mess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page