Skip to main content

pamoja-update

Signed firmware manifests, streaming image verification, and A/B slots that fall back on their own. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.

read the guide documentation API reference

Install

pip install pamoja-update
from pamoja import update

This pulls in pamoja-native, the compiled engine, and pamoja-security. pip install pamoja is the whole framework in one package.

Example

The script the test suite runs, spliced here as it ran.

From bindings/python/guides/update.py:

from pamoja.core import PamojaError
from pamoja.security import DeviceIdentity
from pamoja.update import (
    BootAction,
    Manifest,
    SlotState,
    Updater,
    image_digest,
    sign_manifest,
    verify_envelope,
)

# The publisher's key signs releases; devices in the field are anchored to its public half
# and will take firmware from nobody else.
publisher = DeviceIdentity.from_seed(bytes([7]) * 32)
vendor = bytes([0x0A]) * 16
device_class = bytes([0x0B]) * 16

# The release. A manifest says who the image is for, which slot it belongs in, how big it
# is and what it hashes to; nothing about the image itself is taken on trust.
image = b"firmware for a flow meter, version two"
manifest = Manifest(
    sequence=2,
    vendor_id=vendor,
    class_id=device_class,
    storage=1,
    digest=image_digest(image),
    size=len(image),
)
envelope = sign_manifest(manifest, publisher)
print(f"published sequence {manifest.sequence} in a {len(envelope)}-byte envelope")

# On the device. It checks the envelope against the key it was anchored to before it
# accepts a single byte of the image.
opened = verify_envelope(envelope, publisher.public_key)
print(f"accepted  a release for slot {opened.storage}")

# It left the factory running sequence 1 from slot 0, so the release goes to the spare slot
# and the image it is running stays where it is.
fleet = Updater(vendor, device_class, publisher.public_key, 2, 4096)
fleet.provision(0, 1)
fleet.begin(envelope)
for at in range(0, len(image), 16):
    fleet.write(image[at : at + 16])
print(f"staged    {fleet.progress().written} of {len(image)} bytes")
slot = fleet.finish()
print(f"written   to slot {slot}, leaving the running image alone")

# The first boot into a new image is a trial. It reverts on the next boot unless the device
# confirms that it came up, which is what makes a bad release survivable.
print(f"booting   {fleet.on_boot().action}")
fleet.confirm()
print(f"confirmed slot {slot} is now {fleet.slot_record(slot).state}")

# The same release signed by a key this device is not anchored to gets nowhere.
impostor = DeviceIdentity.from_seed(bytes([90]) * 32)
try:
    fleet.stage(sign_manifest(manifest, impostor), image)
    print("a forged release was accepted, which should never happen")
except PamojaError as error:
    print(f"forged    refused: {error}")

The same capability in every language

Language Package Reference
Rust pamoja-update reference, docs.rs, install
TypeScript @pamoja/update reference, install
Python pamoja-update reference, install
C# Pamoja.Update reference, install

Documentation

License

MIT

Release files for pamoja-update 0.1.18

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pamoja-update 0.1.18
File Size Uploaded
pamoja_update-0.1.18.tar.gz 4.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pamoja-update 0.1.18
File Interpreter ABI Platform
pamoja_update-0.1.18-py3-none-any.whl Python 3 none any Details

Total release size: 10.5 kB

Release files / pamoja_update-0.1.18.tar.gz

Download URL pamoja_update-0.1.18.tar.gz
Size 4.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c68365a5d19de4de283e7d5c915d27da583211f466a2ce9b153e66ce3922bcfc
BLAKE2b-256 checksum
How to use checksums
16c2f21ed78cb9478239a43420c0f94d486eff07b1289a6670dd16af12977e35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / pamoja_update-0.1.18-py3-none-any.whl

Download URL pamoja_update-0.1.18-py3-none-any.whl
Size 5.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6e56740abdb864465721b2c2861a72d74ee748b3d197b26434e5a5fb98a0d751
BLAKE2b-256 checksum
How to use checksums
db8d5ef733a7d684cf89740ca9134691ea3eb6bcbbf98f379d318895091a8d72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.18 This release

2 release 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