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.0

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.0.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.0-cp311-cp311-win_arm64.whl (24.8 kB view details)

Uploaded CPython 3.11Windows ARM64

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

Uploaded CPython 3.11Windows x86-64

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

Uploaded CPython 3.11

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

Uploaded CPython 3.11

gbp_stack-1.5.0-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.0-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.0.tar.gz.

File metadata

  • Download URL: gbp_stack-1.5.0.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.0.tar.gz
Algorithm Hash digest
SHA256 4f55e08ed8470d64c49762a6af8bcb8d8852ba6666643b79965a49a507a30d90
MD5 da30ebf2eac9b7ff9cc1e63c0e14c550
BLAKE2b-256 0a0fda4afb66541dfcb42a66dd246f7c9f936b91dea324111e66bb8d71170af5

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0.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.0-cp311-cp311-win_arm64.whl.

File metadata

  • Download URL: gbp_stack-1.5.0-cp311-cp311-win_arm64.whl
  • Upload date:
  • Size: 24.8 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.0-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 299c411460f9006964109ad59252e32b5e50217d1b84f1999123c1b8b5539656
MD5 c5efbf07c301e5702ee6880feef9f084
BLAKE2b-256 6aeb4628d869daba8a74198f4528e2d272d41b9f181cb47d79f32b7905257544

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0-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.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: gbp_stack-1.5.0-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.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 f284fed0c0bf9fdcc83f7da9a1361d7c817ca2c95ce6df7144e64063d808d27d
MD5 a4e00ce75f6d54fd563e4cf2712be34a
BLAKE2b-256 a5ca867b404120b8b373b95e8f1b65de7846326657513558beae93f121ecc278

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0-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.0-cp311-cp311-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.0-cp311-cp311-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 014416f414572057f094a2dde9c72283fd3b3122d4fa7ea8d80cd675d5bab619
MD5 53a797d34463010ce34e67fc15df9648
BLAKE2b-256 018857bbc68215fbfa2cd034b4542f507e63c3b4ac37311a1a216051267cec4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0-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.0-cp311-cp311-manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.0-cp311-cp311-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5aff86c8026248a540734b2f35d9729c6041c279bd6a305ee4a27b258d88f79d
MD5 2fc9d152f3b61b7cd63d10c987948e34
BLAKE2b-256 66ed123772685e001933b1af078853e4920fd065084502fd6e45078d28b00acb

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0-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.0-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.0-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 d6504c49ca0bd046cab4c717894d883a82d4c672532e14df3a2f02f7104b0576
MD5 3e24491f4bb3c1ff56ddade438e874e5
BLAKE2b-256 a718a80b70e15ea4f1ac0748d1d77529ffd1f6cbac072ef4de8e487fffc73799

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0-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.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gbp_stack-1.5.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6735dfcfd6c4d9893a3cdd73fa211c29980fe33470711013868602c4b1da60ab
MD5 35505c483fc7201d38080df373677600
BLAKE2b-256 aaf4e6c85ae6eb8e5bbb6f7b2cc9dd0e343ef97084e031a45f68628333484a44

See more details on using hashes here.

Provenance

The following attestation bundles were made for gbp_stack-1.5.0-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