keylet -- Client library for Tillitis TKey
Keylet is a Python client library and CLI tool for the Tillitis TKey security token, and implements a ML-DSA / Ed25519 signer application for TKey.
TKeys unique feature is that it has no long-term memory: signing keys are always generated from a seed at runtime. This seed is built by combining a Unique Device Secret, a Device Application hash and an optional User Supplied Secret. Both the Device Application and User Supplied Secret are provided at runtime by keylet.
The unique design leads to some API peculiarities:
- User Supplied Secret (passphrase) is not directly validated by keylet: a "wrong" passphrase will just lead to using a different signing key. In practice the calling application should look at
TKeySign.get_pubkey(): if the key is unexpected, then potentially the wrong passphrase was used. - In long-term use (where the same signing key is expected to be used over a period of time) the calling application is responsible for always selecting the same Device Application:
keyletprovides a mechanism for this, see examples. - The only way to change the device application or passphrase after initialization is to unplug the device and start over.
- Signer initialization has an optimization where the initialization succeeds if the TKey has already been initialized with matching device application name and version. Unfortunately
keyletcannot confirm that the exact device binary is the expected one or that the passphrase is still the same one (but again, the calling application can compareTKeySign.get_pubkey()to the expected key)
Installation
pip install keylet
CLI Usage
The package installs a keylet command-line tool for signing and verification. This is primarily a test/demo application for the library.
# Sign without a passphrase, then verify
$ keylet sign README.md
$ keylet verify README.md
# Get public key, sign, and verify using the saved public key
$ keylet pubkey --output pub.key
$ keylet sign README.md
$ keylet verify --pubkey pub.key README.md
# When using keylet long-term, remember to specify device app digest (keylet default
# app version may change, but you will need a specific application to keep using the
# same key)
$ keylet --digest 2cd8741 sign README.md
Library Usage
from keylet import TKeySign, SignApp
# Load the default embedded ML-DSA signer
app = SignApp.load_mldsa()
digest = app.digest
# Initialize the signer with a passphrase
with TKeySign(app=app, secret="hunter2") as signer:
# Sign a payload
signature = signer.sign(b"my payload")
In long-term use, the device app digest should be used to ensure the same application is always used for a specific key:
# Load application with a digest stored earlier
app = SignApp.load_mldsa(digest=digest)
# Initialize the signer with a passphrase
with TKeySign(app=app, secret="hunter2") as signer:
# Sign a payload
signature = signer.sign(b"my payload")
See API Reference in documentation for more details.
Development
uv is a required development tool.
# Run keylet CLI from source
uv run keylet sign README.md
# run linters and type checker
make lint
# Fix formatting and lint issues
make fix
# run tests
make test
# run tests, including on-device tests
make test-device
Releasing
- If a major or minor version bump is needed run
uv version --bump=[major|minor] - run
make releaseto create version bump commit, release tag and dev version bump commit - Push the commits and tag to trigger release workflow:
git push --tags origin main
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 keylet-0.7.0.tar.gz.
File metadata
- Download URL: keylet-0.7.0.tar.gz
- Upload date:
- Size: 55.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a21c54b5fb4f6e818d951011f3d92939b6b85ebcc1f3ae0a3e6f315f7f653c80
|
|
| MD5 |
e3915f91e131eb4a567dedf78117c674
|
|
| BLAKE2b-256 |
7aab9f302674ef9a0f0994ec8af2685d0064ecc64f8583fbe68ba86c4217d59e
|
Provenance
The following attestation bundles were made for keylet-0.7.0.tar.gz:
Publisher:
release.yml on jku/keylet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keylet-0.7.0.tar.gz -
Subject digest:
a21c54b5fb4f6e818d951011f3d92939b6b85ebcc1f3ae0a3e6f315f7f653c80 - Sigstore transparency entry: 2434741156
- Sigstore integration time:
-
Permalink:
jku/keylet@5acdce216f82425daabaa8931c189303ab4f610c -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/jku
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5acdce216f82425daabaa8931c189303ab4f610c -
Trigger Event:
push
-
Statement type:
File details
Details for the file keylet-0.7.0-py3-none-any.whl.
File metadata
- Download URL: keylet-0.7.0-py3-none-any.whl
- Upload date:
- Size: 57.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 |
aef13c16e92152f4fbe773e60f4ce0a224827e1be6501d1bec0c1769152b704b
|
|
| MD5 |
53cfb1dcec2c196729013c50cdd996c3
|
|
| BLAKE2b-256 |
ca51937fc218a16a3d6c5915c9602033c4aace872ccb1321560441a218067a14
|
Provenance
The following attestation bundles were made for keylet-0.7.0-py3-none-any.whl:
Publisher:
release.yml on jku/keylet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
keylet-0.7.0-py3-none-any.whl -
Subject digest:
aef13c16e92152f4fbe773e60f4ce0a224827e1be6501d1bec0c1769152b704b - Sigstore transparency entry: 2434741893
- Sigstore integration time:
-
Permalink:
jku/keylet@5acdce216f82425daabaa8931c189303ab4f610c -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/jku
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5acdce216f82425daabaa8931c189303ab4f610c -
Trigger Event:
push
-
Statement type: