Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

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.9.2rc1

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

Persisting MLS state

Serialise a context so it survives a restart, then restore it later — the restored context is at the same epoch and can send / receive again. The blob holds private key material, so store it encrypted at rest.

blob = mls.export_state()                   # persist (encrypted) to disk
# ... later / after restart ...
with MlsContext.restore_state(blob, "alice") as restored:
    assert restored.epoch == mls.epoch
    assert restored.group_id == mls.group_id

License

Licensed under Apache License, Version 2.0.

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.9.2rc1.tar.gz (27.9 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.9.2rc1-cp311-cp311-win_arm64.whl (25.5 kB view details)

Uploaded CPython 3.11Windows ARM64

gbp_stack-1.9.2rc1-cp311-cp311-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.11Windows x86-64

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

Uploaded CPython 3.11

gbp_stack-1.9.2rc1-cp311-cp311-manylinux2014_aarch64.whl (25.3 kB view details)

Uploaded CPython 3.11

gbp_stack-1.9.2rc1-cp311-cp311-macosx_11_0_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

gbp_stack-1.9.2rc1-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.9.2rc1.tar.gz.

File metadata

  • Download URL: gbp_stack-1.9.2rc1.tar.gz
  • Upload date:
  • Size: 27.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gbp_stack-1.9.2rc1.tar.gz
Algorithm Hash digest
SHA256 9764633b341c065322c178b9bbdea3b9e835a0a99e7d62d64e1eafbada41cba7
MD5 6fa096545d68d64e8bf9ec8df02b4cab
BLAKE2b-256 ba3d415ae1980a648ceda41692088d4457474e84f96025a76a942b02a3fbb4f8

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.2rc1-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 95518cb7de8abe48dee7a82beb229e2e8ef9866cee999c4beecf56526f98c0fc
MD5 8ff40a83e9507cfeca3675633f107dc5
BLAKE2b-256 73dff9feff7331deb8c9de08de2e365a5a290f544e9c9bc23c63600526f51071

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.2rc1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 889a83f26da5f7bfa488036dcee7e6d5157467ad8ccb1a801148c71cf6ad7f47
MD5 328188cb378e205c13a6b1d1a88eda06
BLAKE2b-256 7d06105b80cde0b60e3b740b158e39e4d492bbbb213939e57456a684a6820e9b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.2rc1-cp311-cp311-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 afc796e1095b1f42696f65ef5211f32b1bfc65fded6d6352a1095317d389e455
MD5 e57038b27c96a996b5da40f49112bcdb
BLAKE2b-256 885ed79dfcb2c230d16b05a30ab7e798a3364bf544ecd97312f2de7f51894ac3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.2rc1-cp311-cp311-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 027f43779260fd3c1f3fe6323d3718f26f7dec5f906b572f890893daa4064d1b
MD5 2177429cb6be5233de5548e0ee2c6335
BLAKE2b-256 2345ce1f5b53866b2c8427513bece576b41ec18dfaaea2e590066d585edc1169

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.2rc1-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 d7f8beb9d38d4cace4bc739b4b872ea16d91e5d8bce45dc6aa03e4e94f1e22b6
MD5 5f5d689bef7d42efc582b1805cf4aeb3
BLAKE2b-256 fac7c85d2f19fd8daf6dc00343acda5a692049b9869b43917567fa41e80cd489

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.2rc1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d787cd1f1f310bfc6e09159fcc71dfd83c8906c3c97dc19f5b39b5f7f17a91cb
MD5 1867c95f91b2f897db287f5e0a5a69e1
BLAKE2b-256 d0e35a5f85cedf707580fe43ccbc0c1998eb6bddc4fbf03ad841bbae4656304b

See more details on using hashes here.

Provenance

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

Release history Release notifications | RSS feed

This release

1.9.2rc1 This release

7 files

1.9.1

7 files

1.9.0

7 files

1.8.2

7 files

1.8.1

7 files

1.8.0

7 files

1.7.0

7 files

1.6.0

7 files

1.5.5

7 files

1.5.4

7 files

1.5.3

7 files

1.5.2

7 files

1.5.1

7 files

1.5.0

7 files

1.4.2

7 files

1.4.1

7 files

1.4.0

7 files

1.3.0

7 files

1.2.3

7 files

1.2.2

7 files

1.2.1

7 files

1.2.0

7 files

1.1.4

7 files

1.1.3

7 files

1.1.2

7 files

1.1.1

7 files

1.1.0

7 files

1.0.1

7 files

1.0.0

7 files

0.2.0

7 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page