Open, IDP-agnostic agent-identity toolkit: agent + on-behalf-of tokens via RFC 8693.
Project description
hallmark-identity (Python)
Python port of Hallmark — open, IDP-agnostic identity for AI agents via OAuth 2.0 Token Exchange (RFC 8693).
Sync API, zero runtime dependencies, Python ≥3.10.
Install
pip install hallmark-identity # (PyPI publish pending)
Quick start
from hallmark_identity import create_identity, oidc
identity = create_identity(
idp=oidc(issuer="https://your-idp/", client_id="agent", client_secret="…"),
)
# "Who am I?" — the agent's own machine identity (client-credentials grant)
mine = identity.agent().token(audience="https://api.internal")
# "Who am I acting for?" — on behalf of a user (you bring the user's token)
on_behalf = identity.on_behalf_of(user_token).token(
audience="https://api.github.com", scopes=["repo"],
)
import urllib.request
req = urllib.request.Request(
"https://api.github.com/user/repos",
headers={"authorization": f"Bearer {on_behalf.raw}"},
)
Supported IDPs
Any RFC 8693-capable OIDC provider via oidc(), plus a keycloak() convenience adapter:
from hallmark_identity import oidc, keycloak
oidc(issuer="https://login.microsoftonline.com/<tenant>/v2.0", client_id=client_id, client_secret=client_secret)
keycloak(base_url="https://kc.example", realm="agents", client_id=client_id, client_secret=client_secret)
API
| Export | Purpose |
|---|---|
create_identity(idp, store=None, refresh_skew_seconds=30, http_request=None) |
Factory. |
identity.agent().token(audience=None, scopes=None) |
The agent's own identity. |
identity.on_behalf_of(subject_token, type="access_token").token(...) |
On-behalf-of a user. |
oidc(...) / keycloak(...) |
IDP adapters. |
memory_store() |
Default in-memory TokenStore; implement get/set to plug in Redis, etc. |
parse_token, is_expired, will_expire_within |
Token-claim helpers. |
HallmarkError, GrantError, TokenExchangeUnsupportedError |
Typed errors. |
A returned Token exposes .raw, .sub, .act, .aud, .scope, .exp — .raw is the string sent as a bearer token.
Development
uv sync # install deps
uv run pytest # unit tests
uv run pytest -c pytest-integration.ini # opt-in, requires a running Keycloak — see tests/integration/README.md
uv run mypy src # typecheck
uv build # build sdist + wheel
License
MIT
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 hallmark_identity-0.1.0.tar.gz.
File metadata
- Download URL: hallmark_identity-0.1.0.tar.gz
- Upload date:
- Size: 60.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dabf70632142289de48e5237d364d69025b43af62789fa54faa6b624c5faacb6
|
|
| MD5 |
643fa0fdee3a7571e9017a9dcddb87a3
|
|
| BLAKE2b-256 |
2f4804012f58878545710e7293b92e51cc1f21c3cda533667d4c41f6f3454073
|
File details
Details for the file hallmark_identity-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hallmark_identity-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d63c30956a4260613441800c29d947cf29bd9968dfc3e8858b0ee6a0a203e14d
|
|
| MD5 |
792fbb67db54090d2b06e4a9d56e36d1
|
|
| BLAKE2b-256 |
936dd6c845e8a1851e5fd70132ee6fe91ae36ad61be30c2a34145951e0676a53
|