nomosprotocol
NOMOS for Python. It includes the reference verifiers of the NOMOS specifications and the developer layer built on them:
accept(), for the system that makes a change;act(), for the agent that carries one;witness()andissuer(), for the systems that sign the facts and publish the rules.
pip install nomosprotocol # cryptography is the only dependency
pip install "nomosprotocol[postgres]" # adds psycopg, for postgres_store()
Python 3.9+. The verifiers in this package are the same code the specification's published test vectors are generated and checked with, so there is no second Python implementation to drift from the reference.
Be the system that makes the change
import nomosprotocol as nomos
rp = nomos.accept(
relying_party_id="orders.acme.example",
root=ACME_ROOT_PEM, # the root you pin; there is no default
act_endpoint="https://orders.acme.example/nomos/acts",
authorities=[{"artifact_id": "acme-purchasing", "issuer": "https://policy.acme.example",
"actions": ["purchase"], "currency_policy": "record", "in_force_seal_hash": POLICY_SEAL_HASH}],
local_facts=lambda act, tx=None: {"vendor_blocked": is_blocked(act["action"]["params"]["vendor"])},
commit=lambda action, tx, act_id: create_order(tx, action), # your code, on the same transaction
store=nomos.postgres_store(pool.connection), # a psycopg_pool ConnectionPool
)
app = rp.wsgi # Flask, Django, gunicorn: any WSGI server
app = rp.asgi # FastAPI/Starlette mount, uvicorn: any ASGI server
Every Act is verified locally (NOMOS-SPEC-008). If it is authorized, accept() does four things
in one transaction: records the nonce, re-reads your facts, hands commit exactly the verified
action, and stores the receipt with the Act.
| Verdict | Status |
|---|---|
| AUTHORIZED, committed | 201 |
| ESCALATED | 202 |
| INCOMPLETE | 422 |
| DENIED | 403 |
| REPLAYED | 409, with the original receipt |
| Any other refusal | 400 |
| Revocations unavailable | 503 |
If any number of copies of one Act arrive at once, exactly one commits and the rest get its receipt. If revocation status can't be established, nothing commits.
Be the agent
r = nomos.act(to="http://localhost:4747",
action={"type": "purchase", "subject": "DEPT-17", "params": {"amount": 500, "vendor": "paperco"}})
print(r["status"]) # committed | escalated | incomplete | denied | refused | replayed
act() handles the whole round trip:
- discovers the system;
- fetches the rules it acts under;
- collects signed facts from the witnesses;
- presents exactly the certificates the Act relies on;
- submits;
- if a person must approve, waits for the approval and resubmits.
It uses only the standard library. To try it, run npx @nomosprotocol/cli dev.
The other roles
witness(origin=…, witness_id=…, signer=…, claims={"budget_remaining": lambda about: …}, key_certs=…)signs one fact about one subject on request.issuer(origin=…, issuer_id=…, signer=…, authorities=[policy], key_certs=…, revocations=…)publishes the sealed rules, the version in force, the certificate pool and the revocation list.
Keys are Signers: anything with kid, public_key_pem, algorithm and sign(payload) -> str.
local_signer(pem) and generate_signer() are for development; for production, wrap your KMS.
Verify directly
from nomosprotocol import verify_act, chain
v = verify_act(act, relying_party_id="…", root_pem=ROOT, now=datetime.now(timezone.utc),
seen_nonces=set(), currency_policy="record", in_force={"acme-purchasing": SEAL_HASH})
chain.verify_revocation_list(lst, ROOT, now) # NOMOS-SPEC-007 rev. 1.10
Conformance
This package is checked against:
- every vector of NOMOS-SPEC-007 (1.7.0, rev. 1.9, rev. 1.10 revocation sources), NOMOS-SPEC-008 0.6.0 and NOMOS-SPEC-010 0.2.0;
- the NOMOS-SPEC-009 selection vectors;
- the NOMOS-SPEC-009 HTTP runner, 17 of 17, with
accept()behind it (python/tests/conformance_rp.py).
act() also interoperates with the JavaScript sandbox, escalation and approval included
(python/tests/interop_sandbox.py).
MIT licensed.
Metadata
Release files for nomosprotocol 0.1.0
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 |
|---|---|---|---|---|
| nomosprotocol-0.1.0.tar.gz | 43.7 kB | Without provenance | Details for nomosprotocol-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nomosprotocol-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for nomosprotocol-0.1.0-py3-none-any.whl |
Total release size: 87.0 kB
Release files / nomosprotocol-0.1.0.tar.gz
| Download URL | nomosprotocol-0.1.0.tar.gz |
|---|---|
| Size | 43.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
12210a2ee530e913b354a6f6964aedce721cf30efec9b4fd66705f4561b2c558
|
|
BLAKE2b-256 checksum How to use checksums |
49eadedb75bd9be7a25f1d066aab48371db3d93894159ca7621f3b6e37269f25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / nomosprotocol-0.1.0-py3-none-any.whl
| Download URL | nomosprotocol-0.1.0-py3-none-any.whl |
|---|---|
| Size | 43.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ba9d19ac30acf98ebfdededfe6078127804f8634f6772ad848760d90f1b07af0
|
|
BLAKE2b-256 checksum How to use checksums |
a2b55f51392e63597226795678cc4e23856cc03d94cfbb7f6b870aa2e8e4e8a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Security for nomosprotocol 0.1.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.