Skip to main content

Python bindings for the Group Protocol Stack: a layered, end-to-end encrypted group-messaging protocol family built on top of MLS (RFC 9420).

Project description

gbp-stack — Python bindings for the Group Protocol Stack

License: Apache 2.0

Python bindings for the Group Protocol Stack: a layered, end-to-end encrypted group-messaging protocol family built on top of MLS (RFC 9420).

This package wraps the native gbp_stack shared library through ctypes. The wheel for each supported platform bundles the appropriate native binary under gbp_stack/_native/<rid>/.

Layers

┌── application ──────────────────────────────────────────────────────┐
│   GtpClient · GapClient · GspClient   (TCP / UDP / SCTP-like)       │
├─────────────────────────────────────────────────────────────────────┤
│   GroupNode (GBP — IP-like base)                                    │
├─────────────────────────────────────────────────────────────────────┤
│   MlsContext (RFC 9420)                                             │
└─────────────────────────────────────────────────────────────────────┘

Payload codec

Each sub-protocol payload can be encoded as CBOR (default), Protobuf, or FlatBuffers. Pass PayloadCodec to send and accept; the chosen codec is surfaced in ev.codec on payload_received events.

from gbp_stack import GtpClient, PayloadCodec

frame = gtp_alice.send(alice, alice_mls, target=2, message_id=1,
                       text="hello", codec=PayloadCodec.FLATBUFFERS)
for ev in bob.on_wire(bob_mls, frame.wire):
    if ev.kind == "payload_received":
        codec = ev.codec or PayloadCodec.CBOR
        result = gtp_bob.accept(ev.plaintext, bob_mls.epoch, codec=codec)
        print(result.text)
Value Name Description
0 PayloadCodec.CBOR Default; pf field omitted from wire
1 PayloadCodec.PROTOBUF Protobuf via gbp-proto
2 PayloadCodec.FLATBUFFERS FlatBuffers via gbp-flat; lowest latency

Sub-protocol toolkits

Beyond the protocol clients, the package ships ready-made helpers:

  • MessageHistory + Watermark — bounded GTP message log + per-sender high-water mark for serving and consuming resync requests.
  • JitterBuffer — bounded GAP reorder window keyed by media_source_id, with push, pop_in_order, pop_force and late-frame detection.
  • RoleRegistry + Permissions — bind numeric role ids to permission bit-masks and check them with require / has.
  • CapabilitiesNegotiator — track per-member advertisements and query the intersection, union, group_supports and missing views.
  • SFrameSession + SFrameEncryptor — SFrame (draft-ietf-sframe-enc) E2EE for GAP audio frames; per-sender AES-GCM keys derived from MLS exporter, 1024-entry sliding-window replay protection.
  • encode_gbp_frame — low-level helper to construct a raw CBOR GBP frame.
  • lookup_error — return the CBOR ErrorObject for a known error code.

Coordinator events

NodeEvent surfaces three new event kinds for coordinator election:

kind Extra fields Meaning
coordinator_election_needed The local node should initiate GSP COORDINATOR_CLAIM
became_coordinator This node won the election
coordinator_claim claimant A peer sent COORDINATOR_CLAIM with this member id

Install

pip install gbp-stack==1.5.1

Quick start

from gbp_stack import MlsContext, GroupNode, GtpClient

with MlsContext.create("alice") as alice_mls, \
     MlsContext.create("bob")   as bob_mls:

    bob_kp  = bob_mls.export_key_package()
    welcome = alice_mls.invite(bob_kp)       # alice auto-finalizes; epoch advances to 1
    bob_mls.accept_welcome(welcome)

    group_id = alice_mls.group_id
    with GroupNode.create(member_id=1, group_id=group_id) as alice, \
         GroupNode.create(member_id=2, group_id=group_id) as bob, \
         GtpClient.create() as gtp_alice, \
         GtpClient.create() as gtp_bob:

        alice.bootstrap_as_creator(alice_mls.epoch)
        bob.bootstrap_as_joiner(bob_mls.epoch)

        frame = gtp_alice.send(alice, alice_mls, target=2,
                                message_id=0xCAFE_F00D, text="hello")
        for ev in bob.on_wire(bob_mls, frame.wire):
            if ev.kind == "payload_received" and ev.stream_type == 2:  # StreamType.Text
                result = gtp_bob.accept(ev.plaintext, bob_mls.epoch)
                print(result.text)   # → "hello"
                # result.status is "new" (first message from this sender)
                # subsequent messages → "new"; duplicates → "duplicate"

GSP signals with per-signal arguments

Signals that target a specific member or resource require CBOR-encoded args. The send method accepts an optional args: bytes keyword argument.

import struct
from gbp_stack import GspClient, SignalType

# Minimal CBOR helpers
def cbor_uint(n: int) -> bytes:
    if n <= 23:     return bytes([n])
    if n <= 0xFF:   return bytes([0x18, n])
    if n <= 0xFFFF: return bytes([0x19, n >> 8, n & 0xFF])
    return bytes([0x1A, (n>>24)&0xFF, (n>>16)&0xFF, (n>>8)&0xFF, n&0xFF])

def cbor_map1(k: int, v: int) -> bytes:
    return bytes([0xA1]) + cbor_uint(k) + cbor_uint(v)

def cbor_map2(k0: int, v0: int, k1: int, v1: int) -> bytes:
    return bytes([0xA2]) + cbor_uint(k0) + cbor_uint(v0) + cbor_uint(k1) + cbor_uint(v1)

# Signal-specific args schemas:
#   MUTE / UNMUTE  → {0: target_member_id}
#   ROLE_CHANGE    → {0: target_member_id, 1: new_role_id}
#   STREAM_START / STREAM_STOP → {0: stream_type}
#   CODEC_UPDATE   → {0: codec_id}
#   JOIN / LEAVE   → no args required

with GspClient.create() as gsp_alice:
    # Mute member 3 (no role_claim needed for self-moderation)
    frame = gsp_alice.send(
        alice_node, alice_mls,
        target=0,  # 0 = broadcast
        signal=SignalType.MUTE,
        role_claim=0,
        request_id=1,
        args=cbor_map1(0, 3),  # {0: target_member_id=3}
    )

MLS multi-member group pattern

When inviting a member to an existing group (not the first invite), use invite_full so that existing members can process the commit:

# Alice adds Carol to an alice+bob group
commit, welcome = alice_mls.invite_full(carol_mls.export_key_package())
alice_mls.finalize_commit()          # alice's epoch advances
bob_mls.process_message(commit)      # bob stages the commit
bob_mls.finalize_commit()            # bob's epoch advances to match alice
carol_mls.accept_welcome(welcome)    # carol joins
assert alice_mls.epoch == bob_mls.epoch == carol_mls.epoch

License

Licensed under Apache License, Version 2.0.

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

gbp_stack-1.5.1.tar.gz (27.0 kB view details)

Uploaded Source

Built Distributions

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

gbp_stack-1.5.1-cp311-cp311-win_arm64.whl (24.9 kB view details)

Uploaded CPython 3.11Windows ARM64

gbp_stack-1.5.1-cp311-cp311-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.11Windows x86-64

gbp_stack-1.5.1-cp311-cp311-manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11

gbp_stack-1.5.1-cp311-cp311-manylinux2014_aarch64.whl (24.7 kB view details)

Uploaded CPython 3.11

gbp_stack-1.5.1-cp311-cp311-macosx_11_0_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

gbp_stack-1.5.1-cp311-cp311-macosx_11_0_arm64.whl (1.2 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file gbp_stack-1.5.1.tar.gz.

File metadata

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

File hashes

Hashes for gbp_stack-1.5.1.tar.gz
Algorithm Hash digest
SHA256 2d60c94ee77778a1d0d8823a42d38bac2ce08bd41de6db4e37f3f596a9a1e17b
MD5 a8af3ef4baf4c019c98fa7f1d5ee89e8
BLAKE2b-256 3e306375dc03a30e2c15bfcd0f08ef4137984b5d94a98690084f45ed0665421b

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1.tar.gz:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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

File details

Details for the file gbp_stack-1.5.1-cp311-cp311-win_arm64.whl.

File metadata

  • Download URL: gbp_stack-1.5.1-cp311-cp311-win_arm64.whl
  • Upload date:
  • Size: 24.9 kB
  • Tags: CPython 3.11, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gbp_stack-1.5.1-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 6947a73c75e4a7f0b56919772015ae59647aa72722ca28ddd8eb65c375b84276
MD5 4a337826e4fe0228057b62b08f42d17f
BLAKE2b-256 6cb2762b3e8c1d7ea0ef33877c60aa3851be9fdfbd09b6ec3dec284853811af1

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1-cp311-cp311-win_arm64.whl:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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

File details

Details for the file gbp_stack-1.5.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: gbp_stack-1.5.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gbp_stack-1.5.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 156aff676ada16b8426a73f77fc5dfce165c733527da0b8c1bd0184da41041a7
MD5 f37bd8b7a4f55007b8b47f166ae1863c
BLAKE2b-256 8f3059943cdd6725839c0ec0d57f48b3a061c1fe649974e062939a586204ff4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1-cp311-cp311-win_amd64.whl:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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

File details

Details for the file gbp_stack-1.5.1-cp311-cp311-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.1-cp311-cp311-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4059c59606b7069c67439720a36bfc57a31b76a35233f28de35b733e8cf4b4df
MD5 e03ab239197a103076c0216b87dbb8b5
BLAKE2b-256 c8c22d668be3a2215dc8db53d82ebeb5e32812402c4a0afa6095e87394b7d08b

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1-cp311-cp311-manylinux2014_x86_64.whl:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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

File details

Details for the file gbp_stack-1.5.1-cp311-cp311-manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.1-cp311-cp311-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6e91f0e2a31fe251d07e3eb45765df62fd11fe9f22410ac34553f109c40b8997
MD5 9310635390bc55e7c95415ffad6980c2
BLAKE2b-256 1fca4002eb0747582c4f0e979b04c80bae7e499cdd31e22b4d8e0fe6ad61f6bc

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1-cp311-cp311-manylinux2014_aarch64.whl:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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

File details

Details for the file gbp_stack-1.5.1-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.1-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 f840c4b0b0f8a267aa18f896eabc9a1ecf6f67583b94137a6a60fe957a4afd13
MD5 9abbb39b97a73522972c01f3129d56c1
BLAKE2b-256 aa09ec57948e82be694e9d7e57841cbdb593de2422617df194f26bef5ddceca4

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1-cp311-cp311-macosx_11_0_x86_64.whl:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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

File details

Details for the file gbp_stack-1.5.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9f0ed5ae08faa27451b1bdc4b6a333069b0d12ec7d0ee8ea5f261dde98cf530d
MD5 096cc33bda0441b4371b2bb7190731b2
BLAKE2b-256 44b8bc3f11588efebbbfa52f51dbac3a4be1396bc573bdeff885a825a97d35f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.1-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on F000NKKK/Group-Protocol-Stack

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