Skip to main content

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

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

Uploaded CPython 3.11Windows ARM64

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

Uploaded CPython 3.11Windows x86-64

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

Uploaded CPython 3.11

gbp_stack-1.9.1-cp311-cp311-manylinux2014_aarch64.whl (25.2 kB view details)

Uploaded CPython 3.11

gbp_stack-1.9.1-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.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.9.1.tar.gz.

File metadata

  • Download URL: gbp_stack-1.9.1.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.1.tar.gz
Algorithm Hash digest
SHA256 685b0477b8a1af61e9e2dfab9f3abdbb3751ccc5f8dd811926aa914efdcef6ab
MD5 5d79653125561eb25bb591cad5b22439
BLAKE2b-256 dd0b30d14735c10fc9dc86db40d73c357c866a19bf059f5c49e621a5307282c4

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: gbp_stack-1.9.1-cp311-cp311-win_arm64.whl
  • Upload date:
  • Size: 25.4 kB
  • Tags: CPython 3.11, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gbp_stack-1.9.1-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 a908e4cbd02c74f966e7547b5040f96cb7dc921e85185c86deb3f52b6d58a473
MD5 933208ddbf89cf188389c8250c824dae
BLAKE2b-256 1420f6b5e3c92e375db2eda4f802a24c9687259cbcd2ca2a58cf31d1d86e2539

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: gbp_stack-1.9.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gbp_stack-1.9.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 a017d5fb6eeae7bfe0cecef8e0b5a269ee1ec17f8f34a05a0d8f033c3aaffe51
MD5 ac3f5455870a64195e0004ccff781105
BLAKE2b-256 a663ececccefe0527375ae1a7a6639fbf6bab951a730354cdd4ffa61a0873728

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.1-cp311-cp311-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 23f4b43566ca49e65f889d999f29ad76f22ae72a7d715beb5b499c2eeba0d9cc
MD5 d6e158bdfd640f354b80e29b6f328e4e
BLAKE2b-256 ee64ffc051e27eba91f189a01f878cfd491120d9137b0d3428e6a58dd5aeb245

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.1-cp311-cp311-manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7c474848f0d79fcabbe8d09f0ec6ff9ae8056b4c81a13181877ae58660bc560f
MD5 1640f3a33f600e88f42cf1992f32f4e2
BLAKE2b-256 466e8850b22ea0d244131907a4a17c3d81d8fac00cc93c4b7df6688a125325d8

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.1-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 bab73bac04777a8ffb2f819fbab6a3357f5161639f61a018ce856f8c4f27602f
MD5 d81ade4b453dadd3598524f74fea038b
BLAKE2b-256 a2f23b77f0af8eaee5369e02162651b7e1fad802b0a63cd2cf147e11904e1bf8

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for gbp_stack-1.9.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9e27318568ca120a3cbb06526a2fedf257823757a4468e92fb972ed6123dd54e
MD5 6bffae3115a11bf6490c01fd33f02b3c
BLAKE2b-256 1a59af27311544640d1deb30d46283b5de45c4904d1ce46043714139fdc92408

See more details on using hashes here.

Provenance

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

Release history Release notifications | RSS feed

This release

1.9.1 This release

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