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#.
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
pamoja.updatereference, every class and function in this module.- The Signed updates guide, with the same example in Rust, TypeScript, and C#.
- Every capability, and the install page.
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)
| File | Size | Uploaded | |
|---|---|---|---|
| pamoja_update-0.1.18.tar.gz | 4.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|