Skip to main content

A library to sign and verify OpenBadges

Project description

OpenBadgesLib

CI PyPI Python License

A Python library and CLI for signing and verifying Open Badges embedded in SVG and PNG image files. It supports strict OpenBadges 2.0 (JWS / hosted assertions) and OpenBadges 3.0 (W3C Verifiable Credentials / JWT-VC), plus a frozen OpenBadges 1.0 legacy format — selected with -V {1,2,3} (default 3).

Features

  • Sign badge images (SVG and PNG) as strict OB 2.0 JWS / hosted assertions (with a frozen OB 1.0 legacy format)
  • Issue and verify OpenBadges 3.0 JWT-VC credentials
  • Bake OB 3.0 JWT tokens into SVG and PNG badge images
  • RSA 2048-bit (RS256), ECC NIST P-256 (ES256), and Ed25519 (EdDSA) key support
  • SHA-256 hashed recipient identity with salt (OB 2.0)
  • Expiration and revocation checking
  • Five command-line tools included

Requirements

Installation

pip install openbadgeslib

All dependencies are installed automatically. For a development checkout with the test suite and linters:

pip install -e ".[dev]"

Quick Start

# 1. Initialize a configuration directory
openbadges-init ./config/

# 2. Generate a key pair for a badge
openbadges-keygenerator -c ./config/config.ini -g 1

# 3a. Sign a badge — OpenBadges 3.0 (default)
openbadges-signer -c ./config/config.ini -b 1 -r recipient@example.com -o /tmp/ -E

# 3b. Sign a badge — strict OpenBadges 2.0
openbadges-signer -c ./config/config.ini -b 1 -r recipient@example.com -o /tmp/ -E -V 2

# 4a. Verify — OpenBadges 3.0
openbadges-verifier -i /tmp/badge_1_recipient@example.com.svg \
    -r recipient@example.com -V 3 -k ./config/keys/verify_rsa_key_1.pem

# 4b. Verify — strict OpenBadges 2.0 (pin a trusted key with -l/--local or -k/--pubkey)
openbadges-verifier -i /tmp/badge_1_recipient@example.com.svg \
    -r recipient@example.com -V 2 -l 1

See the Quick Start and CLI Reference wiki pages for the full walkthrough and every flag.

Using the library — OpenBadges 2.0 (strict)

from datetime import datetime, timezone
from openbadgeslib.ob2 import OB2Signer, Assertion, IdentityObject, Verification

with open('sign.pem', 'rb') as f:
    priv_pem = f.read()
with open('badge.svg', 'rb') as f:
    image = f.read()

assertion = Assertion(
    recipient=IdentityObject.create('recipient@example.com', salt='s4lt3d'),
    badge='https://example.com/badge_1/badge.json',
    verification=Verification(type='SignedBadge',
                              creator='https://example.com/badge_1/key.json'),
    issued_on=datetime(2026, 1, 1, tzinfo=timezone.utc),
)

signer = OB2Signer(privkey_pem=priv_pem, algorithm='RS256')
baked_svg = signer.sign_into_svg(assertion, image)
with open('/tmp/signed_badge.svg', 'wb') as f:
    f.write(baked_svg)

For the frozen OpenBadges 1.0 legacy API (Badge / Signer / Verifier), import from openbadgeslib.ob1 instead.

Using the library — OpenBadges 3.0 (JWT-VC)

from openbadgeslib.ob3 import (
    Issuer, Achievement, OpenBadgeCredential, OB3Signer, OB3Verifier,
)

issuer = Issuer(id='https://example.com/issuer', name='Example Org')
achievement = Achievement(
    id='https://example.com/achievements/python',
    name='Python Developer',
    description='Awarded for Python proficiency',
    criteria_narrative='Must pass the Python assessment',
)
credential = OpenBadgeCredential(
    issuer=issuer,
    recipient_id='mailto:recipient@example.com',
    achievement=achievement,
)

with open('sign.pem', 'rb') as f:
    priv_pem = f.read()
signer = OB3Signer(privkey_pem=priv_pem, algorithm='RS256')

# Bake the signed JWT-VC into a badge image
with open('badge.svg', 'rb') as f:
    baked_svg = signer.sign_into_svg(credential, f.read())

# Verify
with open('verify.pem', 'rb') as f:
    verifier = OB3Verifier(pubkey_pem=f.read())
token = OB3Verifier.extract_token_from_svg(baked_svg)
restored = verifier.verify(token, expected_recipient='recipient@example.com')
print('Recipient:', restored.recipient_id)

Documentation

  • User & developer guide — the project Wiki: installation, configuration, concepts, the security model, CLI reference and how-to guides.
  • API reference — generated from the docstrings and published at luisgf.github.io/openbadgeslib.

Running the test suite

pytest
pytest --cov=openbadgeslib      # with coverage report
flake8 openbadgeslib tests      # lint
mypy                            # type check (config in pyproject.toml)

Changelog

See Changelog.txt for the full history, and the GitHub Releases page for release notes.

License

The library (openbadgeslib/ package) is licensed under the GNU Lesser General Public License v3 (LGPLv3). The command-line wrapper tools are licensed under the BSD 2-Clause license.

Authors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openbadgeslib-3.0.1.tar.gz (148.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openbadgeslib-3.0.1-py3-none-any.whl (88.9 kB view details)

Uploaded Python 3

File details

Details for the file openbadgeslib-3.0.1.tar.gz.

File metadata

  • Download URL: openbadgeslib-3.0.1.tar.gz
  • Upload date:
  • Size: 148.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openbadgeslib-3.0.1.tar.gz
Algorithm Hash digest
SHA256 3d143b8a919aa2848413a0e766128722db0eb8e25cffa2519d93684c47ba78ab
MD5 d1fa386fd7d0b58b86c2021567120eb0
BLAKE2b-256 2605f45855f50e19f8153f8fafdb18b43600737b322b7644bfa1263b9fad3872

See more details on using hashes here.

File details

Details for the file openbadgeslib-3.0.1-py3-none-any.whl.

File metadata

  • Download URL: openbadgeslib-3.0.1-py3-none-any.whl
  • Upload date:
  • Size: 88.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for openbadgeslib-3.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cfc0c1a15e0a8e342d0307cfe60fdbe3600b9731187641bc3d3f859074b8a65c
MD5 13e072f044d0d09f81be366938cdbe3d
BLAKE2b-256 4ab6b13d0410845b0e0c34150c25d66beb93f6223be573cd49fbcc2330646830

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page