Skip to main content

Cross-platform credential storage — OS keyring with AES-encrypted file backup

Project description

credstore

Cross-platform credential storage — OS keyring + AES-encrypted file backup.

A standalone secret manager that ships with Slife but does not depend on it. Only two lightweight dependencies: keyring and keyrings-cryptfile.

Install

One-click (recommended)

pip install credstore

Or with uv:

uv tool install credstore

Verify

credstore status

No configuration needed — the OS keyring is used automatically. Run credstore set-password to enable encrypted backup.


CLI

Setup (first time)

credstore set-password

Creates ~/.credstore/credentials.crypt and sets a master password (dev: ./credentials.crypt). Path configurable via CREDSTORE_FILE env var.

Command Reference

Command Master key Description
set-password sets it Create/change master key, init cryptfile
set KEY enters it Atomic dual-write (cryptfile + keyring). Rolls back on keyring failure
get KEY no Keyring only, masked output (sk-5f…b722)
get KEY -p enters it Dual-query keyring + cryptfile, plaintext. Fails on mismatch
delete KEY enters it Remove from keyring + cryptfile
list enters it List all stored credential keys
inject KEY... no Persist to system env: registry (Windows) or shell profile (Unix)
uninject KEY... no Remove from system env: registry (Windows) or shell profile (Unix)
reset-keyring enters it Restore keyring from cryptfile backup
reset-backup enters it Sync system keyring → cryptfile
status no Show backend status
credstore set-password                   # first-time setup
credstore set DEEPSEEK_API_KEY           # store (masked, atomic dual-write)
credstore get DEEPSEEK_API_KEY           # retrieve, masked output
credstore get DEEPSEEK_API_KEY -p        # retrieve plaintext (dual-query)
credstore list                           # list all stored keys
credstore delete OLD_KEY                 # delete from keyring + cryptfile

# System environment injection (persistent)
credstore inject DEEPSEEK_API_KEY        # Windows → registry, Unix → shell profile
Invoke-Expression (credstore inject KEY) # PowerShell: activate in current shell
eval "$(credstore inject KEY)"           # Bash/Zsh: activate in current shell
credstore uninject DEEPSEEK_API_KEY      # remove from registry/profile

credstore reset-keyring                  # restore keyring from cryptfile backup
credstore reset-backup                   # sync keyring → cryptfile
credstore status                         # show backend status

Environment Variable Injection

inject reads a secret from the keyring and persists it to the system environment. On Windows, it writes directly to the registry (HKCU\Environment); on Unix, it appends to the shell profile. New shells load it automatically.

# Persist + activate in current shell
credstore inject DEEPSEEK_API_KEY        # persist to registry/profile
Invoke-Expression (credstore inject KEY) # PowerShell: activate now
eval "$(credstore inject KEY)"           # Bash/Zsh: activate now

# Remove
credstore uninject DEEPSEEK_API_KEY      # remove from registry/profile

Secret never appears on the terminal — inject detects TTY and prints only a hint. The actual export command flows through a pipe when wrapped in Invoke-Expression / eval.

No master password required (keyring only).

Disaster Recovery

When the OS keyring loses data (e.g. after a Windows password change):

credstore reset-keyring               # restore all from cryptfile backup

Design: Memory Safety

Secrets are immutable Python str objects — they cannot be zeroed in place. credstore mitigates memory leaks through three design rules:

Rule Mechanism
Never batch-load list collects only key names. Sync comparison fetches one value at a time and immediately del-s it
Prefer existence checks exists_credential() / list_credential_keys() never retrieve secret content
Explicit cleanup Every CLI handler del-s secret references after last use. set, get, reset, set-password all clean up on every exit path — including error branches

Operations that read/transport secrets

Operation How memory is cleaned
get Caller is responsible for del-ing the returned value
set del secret + del master_pw after dual-write (all code paths)
list Values fetched one-at-a-time, compared, del-ed immediately
inject Value read → persisted → del-ed. TTY: no secret on stdout. Pipe: secret through pipe only
uninject No secrets involved — registry/profile cleanup only
reset-keyring Each value del-ed after writing to keyring
reset-backup Batch load unavoidable, del entries + del master_pw after sync
set-password old_data dict del-ed after re-encryption; all password strings cleaned up

The masked_input() terminal helper echoes * for each keystroke — paste works but the actual value is never displayed or logged.

Python API

import credstore

# Read / check / write / delete (system keyring only, no prompt)
credstore.get_credential("myapp/api_key")      # → str | None
credstore.exists_credential("myapp/api_key")   # → bool  (NEVER returns secret)
credstore.list_credential_keys()               # → list[str]  (NEVER returns values)
credstore.set_credential("myapp/api_key", "sk-…")
credstore.delete_credential("myapp/api_key")   # → bool

# Shell formatting (for env var injection)
credstore.format_export("MY_KEY", "secret", "bash")   # → "export MY_KEY='secret'"
credstore.format_unset("MY_KEY", "bash")              # → "unset MY_KEY"

# keyring: URI resolution
credstore.is_keyring_uri("keyring:myapp/k")    # → True
credstore.resolve_uri("keyring:myapp/k")       # → the secret value

# Backend info
credstore.check_backend()       # → {"available": True, "backend": "…", …}
credstore.is_cryptfile_ready()  # → True if master key is set

Memory rule: callers of get_credential() and resolve_uri() MUST del the returned value after use. Prefer exists_credential() or list_credential_keys() when you only need to know whether a credential exists.

The Python API talks to the system keyring only — no master password, no prompt. Dual-write (keyring + cryptfile) is handled by the CLI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

credstore-0.3.7.tar.gz (36.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

credstore-0.3.7-py3-none-any.whl (25.1 kB view details)

Uploaded Python 3

File details

Details for the file credstore-0.3.7.tar.gz.

File metadata

  • Download URL: credstore-0.3.7.tar.gz
  • Upload date:
  • Size: 36.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for credstore-0.3.7.tar.gz
Algorithm Hash digest
SHA256 c8118ef4e8ba33265dfffcda5fe605aa315197ea375bf5f8736f2aafa5e07733
MD5 69e7c18580120dff75d934a138d857bf
BLAKE2b-256 54649e75722b909eb1b5c3947290cbc77227f228cdba8a8ada84ff9ffc044298

See more details on using hashes here.

File details

Details for the file credstore-0.3.7-py3-none-any.whl.

File metadata

  • Download URL: credstore-0.3.7-py3-none-any.whl
  • Upload date:
  • Size: 25.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for credstore-0.3.7-py3-none-any.whl
Algorithm Hash digest
SHA256 dfb036a800d40ebfe128a26df08db3055a7121b80b0ad63c6c9e3b6a7f61c661
MD5 c9dea174a333c6de86a4f56b9711c6c6
BLAKE2b-256 16452cbb036d30c9f2cda8f9cf1bfb5aa6440c27ebd8a44fb772436f500a66bf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page