This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.1.3 instead.
Agience Origin
Identity, authority.
Origin says who. It is the identity and authorization authority — the trust anchor the rest of the system verifies against, and the entity everything else asks "who is this, and may they?"
As the OIDC issuer it mints and verifies tokens, publishes the JWKS that peer services check signatures against, and owns the passkey/OTP account and setup flows.
The shared foundation is agience-prism-py — Origin's only workspace dependency.
Layout
| Path | Purpose |
|---|---|
src/origin/ |
The FastAPI service: api/, routers/, services/ (auth, verifier, key custody via Shamir + key-oracle), models/, db/, scripts/ (operator commands), plus alembic/ (migrations) and tests/. |
src/origin/web/ |
The static auth UI (login / passkey / setup), served at /, /login, /account, /reset-password and /verify-email, and mounted for its assets at /web. |
web/ lives inside the package, beside the module that serves it. main.py resolves it as
Path(__file__).resolve().parent / "web", which gives one answer in both places the code runs: a
checkout and an installed distribution. A path that climbs out of the package resolves against the
repository layout, which only a checkout has.
src/origin/tests/test_the_package_ships_what_it_serves.py holds it there.
Running it
Origin is an ordinary Python package. It needs no container, and installing it pulls its own pinned dependencies:
pip install ../agience-prism/py # the trust floor
pip install . # or -e ".[test]" to work on it
KEYS_DIR=/path/to/keys python -m uvicorn origin.main:app --host 127.0.0.1 --port 8080
It applies its own migrations at startup, so the first boot creates the database. Requires Python 3.11 or newer.
Bind loopback and put a reverse proxy in front for anything public. A service on the public interface answers past whatever header and path rules the proxy applies.
KEYS_DIR must already contain origin.private.pem, origin.public.pem, encryption.key and
inbound_nonce.secret. Origin ships no key generator — every loader in
prism.trust.key_manager raises rather than inventing a key it did not write, which is correct for
an authority and means an empty directory is a hard stop. Key material comes from the platform
installer (agience-observe), a KMS, or a one-shot key-init step. .env.example documents the
full set.
For a managed install, agience-observe/package/manager does all of the above: it finds a Python,
builds the virtualenv, installs Origin into it and supervises the process.
Letting a peer verify Origin
Publishing /.well-known/jwks.json is not what makes a peer able to verify an Origin-signed
token. Agience peers read their trust inline, from trust_anchors in the
authority.manifest.json of their own keyset, and never fetch. Until Origin's public JWK is
physically present there under trust_anchors.origin, two healthy, mutually reachable services
answer 401 for every user token and nothing logs a reason: from the peer's side there is no
mismatch, there is simply no such issuer.
A peer's own key init writes only its own anchor — asserting a public key for a service whose private key is elsewhere is a trust statement, not a convenience. Origin emits its half:
origin-emit-anchor # the mergeable fragment
origin-emit-anchor --format anchor --uri https://origin.example.com
origin-emit-anchor --format jwks --keys-dir /path/to/keys
python -m origin.scripts.emit_trust_anchor # no install needed
--format chooses fragment (a mergeable {"trust_anchors": {"origin": …}}, the default), anchor
(the value alone, for placing at trust_anchors.origin), or jwks (the JWKS alone). --keys-dir
defaults to $KEYS_DIR, and --uri to config.AUTHORITY_ISSUER.
It reads KEYS_DIR/origin.public.pem, produces the JWK through the same get_jwk_public() that
serves /.well-known/jwks.json — so what you place is byte-identical to what Origin publishes,
kid included — and writes nothing. Placement is the operator's decision; a command that
installed trust in itself on a peer would be the one direction a trust anchor must never travel.
To place it, merge into the peer's manifest:
origin-emit-anchor --format anchor > /tmp/origin-anchor.json
python - <<'EOF'
import json, pathlib
m = pathlib.Path("/path/to/peer/keys/authority.manifest.json")
doc = json.loads(m.read_text())
doc.setdefault("trust_anchors", {})["origin"] = json.load(open("/tmp/origin-anchor.json"))
m.write_text(json.dumps(doc, indent=2) + "\n")
EOF
Then restart the peer. A wrong kid or a re-encoded modulus fails as the same silent 401, which is
why the JWK is emitted rather than transcribed.
Configuration
.env.example is the template — copy it to .env. It states the in-code default for every value
and warns where an unset variable is itself a decision: KEYS_DIR unset means the process does not
boot, and ORIGIN_ALLOWED_ORIGINS unset derives the CORS allow-list from the issuer, ORIGIN_URI
and the facet bases rather than falling back to a wildcard.
License
Dual-licensed: AGPL-3.0-only or commercial. See LICENSE and NOTICE;
commercial and white-label terms in COMMERCIAL_LICENSE.md. Contributing:
CONTRIBUTING.md and CLA.md.
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 agience_origin-0.1.2.tar.gz.
File metadata
- Download URL: agience_origin-0.1.2.tar.gz
- Upload date:
- Size: 604.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6464ef22b34af478cb4df6cb2aabfb75839cad858ef7c6affa248fcca86600de
|
|
| MD5 |
73b5a1c74aee9b30ad1c58b1103c2191
|
|
| BLAKE2b-256 |
8839c477222242566cce587f4b519e3ec83b955ef666570dcdb45c2e3a532ef7
|
Provenance
The following attestation bundles were made for agience_origin-0.1.2.tar.gz:
Publisher:
publish.yml on Agience/agience-origin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agience_origin-0.1.2.tar.gz -
Subject digest:
6464ef22b34af478cb4df6cb2aabfb75839cad858ef7c6affa248fcca86600de - Sigstore transparency entry: 2707525609
- Sigstore integration time:
-
Permalink:
Agience/agience-origin@9a3583fa246c5b2c2364970b1a0a423f4039dc9c -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/Agience
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9a3583fa246c5b2c2364970b1a0a423f4039dc9c -
Trigger Event:
push
-
Statement type:
File details
Details for the file agience_origin-0.1.2-py3-none-any.whl.
File metadata
- Download URL: agience_origin-0.1.2-py3-none-any.whl
- Upload date:
- Size: 652.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86fe3016c9c564dc45fcac85b79bc814013fbc640da2390a30515269e33468cc
|
|
| MD5 |
dd067ee9f1402e3b4acc5666a3252abe
|
|
| BLAKE2b-256 |
85a5fbc720c336aa5ea8b61fdf36fabca9fccf0745b45c6f2c74c6661e95b2ba
|
Provenance
The following attestation bundles were made for agience_origin-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on Agience/agience-origin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agience_origin-0.1.2-py3-none-any.whl -
Subject digest:
86fe3016c9c564dc45fcac85b79bc814013fbc640da2390a30515269e33468cc - Sigstore transparency entry: 2707525647
- Sigstore integration time:
-
Permalink:
Agience/agience-origin@9a3583fa246c5b2c2364970b1a0a423f4039dc9c -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/Agience
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9a3583fa246c5b2c2364970b1a0a423f4039dc9c -
Trigger Event:
push
-
Statement type: