gbp-stack — Python bindings for the Group Protocol Stack
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 bymedia_source_id, withpush,pop_in_order,pop_forceand late-frame detection.RoleRegistry+Permissions— bind numeric role ids to permission bit-masks and check them withrequire/has.CapabilitiesNegotiator— track per-member advertisements and query theintersection,union,group_supportsandmissingviews.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 CBORErrorObjectfor 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.
Metadata
Release files for gbp-stack 1.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| gbp_stack-1.9.1.tar.gz | 27.9 kB | With provenance | Details for gbp_stack-1.9.1.tar.gz |
Built distributions (wheels)
Total release size: 5.5 MB
Release files / gbp_stack-1.9.1.tar.gz
| Download URL | gbp_stack-1.9.1.tar.gz |
|---|---|
| Size | 27.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
685b0477b8a1af61e9e2dfab9f3abdbb3751ccc5f8dd811926aa914efdcef6ab
|
|
BLAKE2b-256 checksum How to use checksums |
dd0b30d14735c10fc9dc86db40d73c357c866a19bf059f5c49e621a5307282c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / gbp_stack-1.9.1-cp311-cp311-win_arm64.whl
| Download URL | gbp_stack-1.9.1-cp311-cp311-win_arm64.whl |
|---|---|
| Size | 25.4 kB |
| Tags | CPython 3.11 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
a908e4cbd02c74f966e7547b5040f96cb7dc921e85185c86deb3f52b6d58a473
|
|
BLAKE2b-256 checksum How to use checksums |
1420f6b5e3c92e375db2eda4f802a24c9687259cbcd2ca2a58cf31d1d86e2539
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / gbp_stack-1.9.1-cp311-cp311-win_amd64.whl
| Download URL | gbp_stack-1.9.1-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
a017d5fb6eeae7bfe0cecef8e0b5a269ee1ec17f8f34a05a0d8f033c3aaffe51
|
|
BLAKE2b-256 checksum How to use checksums |
a663ececccefe0527375ae1a7a6639fbf6bab951a730354cdd4ffa61a0873728
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / gbp_stack-1.9.1-cp311-cp311-manylinux2014_x86_64.whl
| Download URL | gbp_stack-1.9.1-cp311-cp311-manylinux2014_x86_64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 |
|
SHA-256 checksum How to use checksums |
23f4b43566ca49e65f889d999f29ad76f22ae72a7d715beb5b499c2eeba0d9cc
|
|
BLAKE2b-256 checksum How to use checksums |
ee64ffc051e27eba91f189a01f878cfd491120d9137b0d3428e6a58dd5aeb245
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / gbp_stack-1.9.1-cp311-cp311-manylinux2014_aarch64.whl
| Download URL | gbp_stack-1.9.1-cp311-cp311-manylinux2014_aarch64.whl |
|---|---|
| Size | 25.2 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 |
|
SHA-256 checksum How to use checksums |
7c474848f0d79fcabbe8d09f0ec6ff9ae8056b4c81a13181877ae58660bc560f
|
|
BLAKE2b-256 checksum How to use checksums |
466e8850b22ea0d244131907a4a17c3d81d8fac00cc93c4b7df6688a125325d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / gbp_stack-1.9.1-cp311-cp311-macosx_11_0_x86_64.whl
| Download URL | gbp_stack-1.9.1-cp311-cp311-macosx_11_0_x86_64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.11 macOS 11.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
bab73bac04777a8ffb2f819fbab6a3357f5161639f61a018ce856f8c4f27602f
|
|
BLAKE2b-256 checksum How to use checksums |
a2f23b77f0af8eaee5369e02162651b7e1fad802b0a63cd2cf147e11904e1bf8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logRelease files / gbp_stack-1.9.1-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | gbp_stack-1.9.1-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
9e27318568ca120a3cbb06526a2fedf257823757a4468e92fb972ed6123dd54e
|
|
BLAKE2b-256 checksum How to use checksums |
1a59af27311544640d1deb30d46283b5de45c4904d1ce46043714139fdc92408
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logSecurity for gbp-stack 1.9.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 7 files in this release have been uploaded with provenance metadata.
Attestation for gbp_stack-1.9.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 4, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.