Verifiable Credential Barcode (VCB) verification for DL/ID PDF417 barcodes
Project description
VCB Verify
Verify Verifiable Credential Barcodes on DL/ID PDF417 barcodes.
Background
Verifiable Credential Barcodes embed digitally signed credentials inside PDF417 barcodes on government-issued drivers licenses and identification cards. This library verifies those credentials: it parses the barcode, checks the cryptographic proof, and optionally checks revocation status.
The library is jurisdiction-agnostic. Any issuer that follows the
W3C VCB specification can be supported by adding an IssuerProfile.
Built-in profiles are included for California DMV and the W3C Utopia test
vectors. Each profile bundles DID documents for offline use, but online
resolution is recommended for production to pick up key rotations. Host
allowlists on each profile restrict which remote resources can be fetched
during verification.
The API is async (asyncio). Python 3.12+.
Install
pip install vcb-verify
Development:
git clone https://github.com/subfile-llc/vcb-verify.git
cd vcb-verify
pip install -e ".[dev]"
Usage
Basic verification
import asyncio
from vcb_verify import verify
from vcb_verify.issuers import ca_dmv_prod_profile
async def main():
scanned_data = ... # PDF417 bytes or string from barcode scanner
result = await verify(data=scanned_data, profile=ca_dmv_prod_profile())
if result.valid:
print("Valid credential")
else:
print(f"Invalid: {result.error}")
asyncio.run(main())
By default, barcodes without VCB data are returned as not-valid rather than
raising an error. Pass require_vcb=True to treat missing VCB data as a
verification failure, or use profile.vcb_required_after to require it
based on the credential's issued date.
Check revocation status
Revocation checking requires a network request to the issuer's status list endpoint:
result = await verify(
data=scanned_data,
profile=ca_dmv_prod_profile(),
verify_status=True,
)
Online key resolution
To fetch DID documents live from the issuer instead of using bundled copies:
profile = ca_dmv_prod_profile()
result = await verify(
data=scanned_data,
profile=profile,
document_loader=profile.get_loader(online=True),
)
Debug output
result = await verify(
data=scanned_data,
profile=ca_dmv_prod_profile(),
debug=True,
)
if result.debug:
print(result.debug["credential"])
print(result.debug["aamva_hash"].hex())
Issuer Profiles
An IssuerProfile configures verification for a specific jurisdiction.
Built-in profiles
| Profile | Function | Description |
|---|---|---|
| CA DMV Production | ca_dmv_prod_profile() |
California production credentials |
| CA DMV UAT | ca_dmv_uat_profile() |
California test/UAT credentials |
| W3C Utopia | utopia_test_profile() |
W3C spec test vectors (offline only) |
from vcb_verify.issuers import ca_dmv_prod_profile, ca_dmv_uat_profile, utopia_test_profile
Custom profiles
from vcb_verify import IssuerProfile
profile = IssuerProfile(
name="my-state",
issuer_identification_number="123456",
issued_state_value="XX",
vcb_subfile="ZC",
vcb_field="ZCE",
type_table={ ... }, # CBOR-LD compression table for this issuer
allowed_hosts={"did.example.com"},
static_documents={ ... }, # Bundled DID documents for offline mode
)
See the CA DMV profile for a complete example.
API
verify(data, *, profile, ...)
| Parameter | Type | Default | Description |
|---|---|---|---|
data |
bytes | str |
(required) | PDF417 barcode data |
profile |
IssuerProfile |
(required) | Issuer configuration |
require_vcb |
bool |
False |
Require VCB data to be present |
verify_status |
bool |
False |
Check revocation status online |
document_loader |
DocumentLoader |
None |
Override the default document loader |
debug |
bool |
False |
Include debug details in result |
Returns: VerifyResult
| Field | Type | Description |
|---|---|---|
valid |
bool |
True if the credential is valid |
error |
Exception | None |
Error details if invalid |
debug |
dict | None |
Debug details if requested |
IssuerProfile.get_loader(*, online=False)
Returns a document loader for this profile. When online is False
(default), DID documents are resolved from bundled static copies.
Set online=True to fetch live documents from the issuer's server.
Contribute
pip install -e ".[dev]"
pytest
ruff check src tests
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vcb_verify-1.0.0.tar.gz.
File metadata
- Download URL: vcb_verify-1.0.0.tar.gz
- Upload date:
- Size: 29.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac0376047ac2dd7eba0a9c27096f0b7612bd41168ca267959636cf8974a13098
|
|
| MD5 |
c6cb3cddfe7e7e0883a68a4c2674d7f8
|
|
| BLAKE2b-256 |
8cd4c92a01b562e5d62e65499a72e1e61aa076e6e903f43a65a564e673a0abd2
|
Provenance
The following attestation bundles were made for vcb_verify-1.0.0.tar.gz:
Publisher:
publish.yml on subfile-llc/vcb-verify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcb_verify-1.0.0.tar.gz -
Subject digest:
ac0376047ac2dd7eba0a9c27096f0b7612bd41168ca267959636cf8974a13098 - Sigstore transparency entry: 1635249317
- Sigstore integration time:
-
Permalink:
subfile-llc/vcb-verify@a0ec4acd2e826913bb21a935d0ad8b3c90f9e32f -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/subfile-llc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a0ec4acd2e826913bb21a935d0ad8b3c90f9e32f -
Trigger Event:
release
-
Statement type:
File details
Details for the file vcb_verify-1.0.0-py3-none-any.whl.
File metadata
- Download URL: vcb_verify-1.0.0-py3-none-any.whl
- Upload date:
- Size: 35.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
048bce3488f89f4d1429497ea5151685cc2576d435a4366ef8159e7a93811c3b
|
|
| MD5 |
03baef2689eeaf4a17b8a52d43067cf7
|
|
| BLAKE2b-256 |
957b1ffa47b8638527f009c9dd401afdb50ca4b945e0b7cf57d3ab9b382cf1ad
|
Provenance
The following attestation bundles were made for vcb_verify-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on subfile-llc/vcb-verify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcb_verify-1.0.0-py3-none-any.whl -
Subject digest:
048bce3488f89f4d1429497ea5151685cc2576d435a4366ef8159e7a93811c3b - Sigstore transparency entry: 1635249325
- Sigstore integration time:
-
Permalink:
subfile-llc/vcb-verify@a0ec4acd2e826913bb21a935d0ad8b3c90f9e32f -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/subfile-llc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a0ec4acd2e826913bb21a935d0ad8b3c90f9e32f -
Trigger Event:
release
-
Statement type: