Skip to main content

Developers Toolbox

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
The Lupaxa Project Footer

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)

Source distribution for lupaxa-token-manager 0.1.0
File Size Uploaded
lupaxa_token_manager-0.1.0.tar.gz 15.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lupaxa-token-manager 0.1.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page