Token Manager
Store API tokens in named profiles and print them as shell exports.
Each profile can keep tokens as plaintext JSON, or encrypt them with
gpg or openssl.
The PyPI name is lupaxa-token-manager. The import path is
lupaxa.token_manager. The console scripts are tokenctl and
token-manager.
Install
pip install lupaxa-token-manager
Requires Python 3.10 or newer. Encryption modes need the gpg or
openssl binary on PATH. Plaintext profiles do not.
Quick Start
tokenctl profile init
tokenctl add --type github --name main --value 'ghp_xxx' --env-var GITHUB_TOKEN
tokenctl list
source <(tokenctl set --type github --name main --format export)
A child process cannot change the parent shell, so source the export
line. --profile goes before the subcommand and defaults to default:
source <(tokenctl --profile ci set --type github --name main --format export)
Names are unique within a type, so main can exist for both github
and aws. Selecting by --name also needs --type. --id selects a
token on its own. --env-var defaults to TYPE_TOKEN (for example
GITHUB_TOKEN).
Command Reference
| Command | Purpose |
|---|---|
list |
Print tokens as a table, JSON, or names |
types |
Print the token types in the profile |
add |
Store a new token |
update |
Change type, name, value, or env var |
delete |
Remove a token |
show |
Print metadata, or the value if asked |
set |
Print export, dotenv, or the raw value |
profile init |
Create a profile and encryption mode |
profile show |
Print the profile name and encryption |
profile set-encryption |
Rewrite tokens in a new encryption mode |
migrate |
Copy or move tokens between profiles |
List and Show
tokenctl list
tokenctl list --type github --format names
tokenctl list --format json
tokenctl list --format json --reveal
tokenctl list --columns name,env_var,value --max-width 100
tokenctl types
tokenctl show --type github --name main
tokenctl show --type github --name main --reveal
The default list is a grouped text table. The table and JSON both hide
secret values unless you pass --reveal. show does the same.
--columns picks and orders columns. The names are name, env_var,
id, updated, created, value, and type. --max-width wraps the
table to that many characters.
Add, Update, and Delete
tokenctl add --type pypi --name publish
printf '%s' 'pypi-secret' | tokenctl add --type pypi --name publish --value -
tokenctl update --type github --name main --new-name prod --value 'ghp_new'
tokenctl delete --type pypi --name publish
Omit --value on add and the tool prompts without echoing. --value -
reads the secret from stdin, which keeps it out of shell history and the
process list. On update, omit --value to leave the secret unchanged,
or pass --value - to replace it from stdin.
Set
tokenctl set --type github --name prod --format export
tokenctl set --type pypi --name publish --format dotenv
tokenctl set --type github --name prod --format value
export is the default. Values are single-quoted for the shell.
Profiles
tokenctl profile init
tokenctl --profile ci profile init --encryption openssl
tokenctl --profile ci profile show
tokenctl --profile ci profile set-encryption gpg
set-encryption rewrites the tokens in the new mode and removes the
previous token file, so a switch to encryption does not leave plaintext
behind.
Migrate
tokenctl migrate --from-profile default --to-profile ci --dry-run
tokenctl migrate --from-profile default --to-profile ci --type github --name prod --move --overwrite
--dry-run prints the change and writes nothing. Without --move, the
source profile is left as it is. --overwrite replaces a destination
token that already uses the same type and name. A conflict without
--overwrite is still an error during a dry run.
Storage and Encryption
Tokens live under $XDG_CONFIG_HOME/tokenctl (or ~/.config/tokenctl).
Each profile is profiles/<profile>/ with a config.json encryption
mode of none, gpg, or openssl.
| Mode | File | Tool |
|---|---|---|
none |
tokens.json |
Plaintext JSON, mode 0600 |
gpg |
tokens.json.gpg |
gpg --symmetric AES256 |
openssl |
tokens.json.enc |
openssl enc -aes-256-cbc |
Set TOKENCTL_PASSPHRASE for a non-interactive shell. On a terminal the
tool prompts, and that passphrase is passed to gpg or openssl on its
own pipe. It is not written into the environment. Files are written to a
temporary path and then replaced.
Each token stores id, type, name, value, env_var, created_at,
and updated_at. Timestamps are UTC in YYYY-MM-DDTHH:MM:SSZ form.
Exit 0 is success. Exit 1 is a runtime failure (missing token,
conflict, or crypto error). Exit 2 is a usage error, such as --name
without --type.
Library
from lupaxa.token_manager import Store
store = Store(profile="default")
for token in store.load():
print(token.name, token.type)
Store(profile, config_dir=...) overrides the config root.
Documentation
Site pages live in mkdocs/ and publish to
https://token-manager.thelupaxaproject.org/.
make init
make python-install-dev
make mkdocs-serve
Metadata
Release files for lupaxa-token-manager 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 | |
|---|---|---|---|
| lupaxa_token_manager-0.1.0.tar.gz | 15.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lupaxa_token_manager-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.9 kB
Release files / lupaxa_token_manager-0.1.0.tar.gz
| Download URL | lupaxa_token_manager-0.1.0.tar.gz |
|---|---|
| Size | 15.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ed70cbc64c63ec83e4fc355ca30e5949571e71ad4c4af33cd602da4ef70df5c
|
|
BLAKE2b-256 checksum How to use checksums |
7e1e340cc9c1c0378329a9f6d13c1a36a77613ca3a5f7cbfc60a8423507ec2a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / lupaxa_token_manager-0.1.0-py3-none-any.whl
| Download URL | lupaxa_token_manager-0.1.0-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6ed3a320dc1ca348ac67945883ec4362eb2846a76ea022be94e871d21d9f41cf
|
|
BLAKE2b-256 checksum How to use checksums |
ef31fec609bc5ec45c632676846d8d7a2d9bc5fa18f00a6e8431cffe5c9eb7f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log