dumbtv
dumbtv takes the ads, screen tracking and update nags out of your Fire TV over ADB. No root, none of your apps touched, every step can be undone. Free and open source.
Master your digital identity. Switch freely with one click.
SecurityRust · TypeScriptGitHub @cuihairuOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Master your digital identity. Switch freely with one click.
AI translation
Master your digital identity. Switch freely with one click.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Persona
Local-First Identity Material Manager
Manage your digital selves. Switch identity material with confidence.
Persona is a local-first, zero-knowledge manager for one person operating multiple digital selves. Each identity is a distinct key-and-credential context used in a different environment, such as work, personal browsing, infrastructure access, or automation.Read the full README ↗English | 中文
Manage your digital selves. Switch identity material with confidence.
Persona is a local-first, zero-knowledge manager for one person operating multiple digital selves. Each identity is a distinct key-and-credential context used in a different environment, such as work, personal browsing, infrastructure access, or automation.
The product focuses on identity-scoped credentials and developer workflows: passwords, API keys, TOTP, SSH keys, browser autofill, and active identity switching. Wallet material fits the same conceptual model, but is currently a deferred priority rather than part of the main product track.
suggest/shell-hook/use propose the right identity from cwd/repo/host — suggestions only, never silent authorizationThe desktop vault after the 1Password-style sidebar redesign: items, categories, vaults, tags, and tools in one sidebar, with the item detail pane on the right.
Unlock screen, credential list, tools, and settings — captured on Android with the default (zh-CN) locale, dark theme.
persona/
├── core/ # Rust core library: models, crypto, storage, service layer
├── cli/ # Persona CLI: init/add/list/show/switch/export/import/ssh/...
├── agents/ssh-agent/ # Built-in SSH agent (UNIX socket; ed25519/RSA/ECDSA)
├── desktop/ # Tauri + React desktop client (sync, passkeys, conflict UI)
├── browser/ # Browser clients (Chromium extension, Safari extension)
├── mobile/ # Mobile clients (iOS, Android, HarmonyOS)
├── connect-server/ # Local automation endpoint (127.0.0.1 HTTP, scope token)
├── server/ # Optional sync/automation service (Rust + Axum + SQLite)
├── website/ # Marketing site (UmiJS)
└── docs/ # Documentation and roadmap
Persona builds on established open-source foundations — Tauri, React, Axum, sqlx, rust-bitcoin, alloy — rather than replacing them; the product layer (identity model, policy engine, pairing protocol, vault hierarchy) is where this repo's own work lives.
known_hosts validationrust-toolchain.toml for reproducible builds)# Clone the repository
<p align="center">
<a href="https://github.com/cuihairu/persona/releases"><img alt="Status" src="https://img.shields.io/badge/status-in%20development-orange"></a>
</p>
git clone [email protected]:cuihairu/persona.git
cd persona
# Build CLI and SSH agent
cargo build --workspace
# Optional: run local CI checks
make ci
# Install workspace dependencies (desktop + browser extension + website)
pnpm install
# Run the desktop client in dev mode
pnpm --filter desktop run dev
# Build the browser extension bundle
pnpm --filter persona-chromium-extension run build
# Run the website in dev mode
pnpm --filter persona-website run dev
# Initialize an unencrypted workspace
persona init --path ~/PersonaDemo --yes
# Initialize an encrypted workspace with a master password
persona init --path ~/PersonaSecure --yes --encrypted --master-password "your_password"
# Add / show / list identities
persona add
persona show <name>
persona list
# Switch the active identity (Workspace v2 persists the state)
persona switch <name>
# Switch back to the previous identity (resolved from the audit trail)
persona switch --previous
# Run migrations to keep the schema up to date
persona migrate
# Credential management (passwords, API keys, etc.)
persona credential add --identity alice --name "GitHub" --credential-type password --prompt-secret
persona credential list --identity alice --format table
persona credential show --id <UUID> --reveal
persona credential remove --id <UUID>
# Item history (1Password-style): every create/update/delete is recorded with
# field-level diffs; encrypted payloads only ever show as "<encrypted>"
persona credential history --id <UUID>
# Attachments (1Password-style): files are encrypted with the owning item's
# key and stay decryptable across master-password rotation
persona credential attach --id <UUID> --file ~/Documents/recovery-codes.txt
persona credential attachments --id <UUID>
persona credential save-attachment --attachment-id <UUID> --output ~/Downloads/recovery-codes.txt
persona credential remove-attachment --attachment-id <UUID>
# Custom fields (1Password-style): typed fields (text/concealed/date) with
# optional sections; the whole table is sealed under the item's per-item key.
# set-fields replaces the entire table; --clear removes all fields
persona credential set-fields --id <UUID> --field concealed:Bank:PIN=999999 --field text::Recovery=abc123
persona credential fields --id <UUID> # concealed values masked
persona credential fields --id <UUID> --reveal # confirm, then print values
# Secure Note (1Password-style): the body is stored fully encrypted under the
# per-item key — unlike the plain notes column on other item types
persona credential add --identity alice --name "Recovery codes" --credential-type note --note "1111-2222
3333-4444"
# Identity / Software License (1Password standard categories): document numbers
# and license keys are sealed under the item's key; unspecified fields stay empty
persona credential add --identity alice --name "Passport (main)" --credential-type identity \
--first-name Alice --last-name Zhang --id-number 110101199001310011 --passport-number E12345678
persona credential add --identity alice --name "JetBrains All Products" --credential-type software-license \
--license-key AAAA-BBBB-CCCC-DDDD --version 2024.2 --seats 3 --valid-until 2027-05-01
# TOTP (two-factor authentication) workflows
persona totp setup --identity alice --qr ~/Downloads/github.png
persona totp code --id <UUID>
persona totp code --id <UUID> --watch
# Steam Guard (game token; shared_secret is the base64 from the Steam authenticator export)
persona totp setup-steam --identity alice --account alice_steam --secret <base64-shared-secret>
persona totp code --id <UUID> # game token credentials share the same code command
# Or import straight from a Steam Desktop Authenticator export (.maFile) —
# a single file or a whole directory; only verifier fields are stored, the
# Session/access_token credentials are listed and never imported
persona totp import-steam --identity alice --file ~/Downloads/maFiles/alice.maFile
persona totp import-steam --identity alice --file ~/Downloads/maFiles --yes
# Battle.net authenticator: export via a community tool (serial + restore code ->
# standard TOTP secret), then import like any TOTP with 8 digits
persona totp setup --identity alice --secret <base32-secret> --issuer Battle.net --digits 8
# HOTP (RFC 4226) counter-based tokens: add --hotp to the same setup path.
# otpauth://hotp/ URIs and QR codes are detected and stored automatically
persona totp setup --identity alice --secret <base32-secret> --issuer LegacyOTP --hotp --counter 0
persona totp code --id <UUID> # uses the stored starting counter
persona totp code --id <UUID> --counter 5 # explicit counter (HOTP entries only)
# Vendor-bound game tokens (Tencent Game Security Center, NetEase Da Shen,
# miHoYo security token, ...): recorded as vault entries only — their seeds live
# inside the vendor's app, so codes must be generated there
persona totp setup-game-token --identity alice --provider tencent_security --account qq_123456 --url https://gamesafe.qq.com
# Passkeys (WebAuthn, software authenticator): ES256/P-256 keys sealed under
# the per-item key hierarchy; credential IDs are unique across the vault
persona passkey create --identity alice --rp github.com --user [email protected]
persona passkey list --identity alice
persona passkey show <UUID>
persona passkey self-test <UUID> # local register + assert round trip
persona passkey remove --id <UUID>
# Password generator with custom sets
persona password generate --length 32 --set lowercase --set uppercase --set digits --set symbols
persona password generate --pronounceable --length 18 --set lowercase --set uppercase
# Diceware-style passphrase from the EFF large wordlist (3-10 words, `-`-separated)
persona password generate --words 6
# TUI dashboard (ratatui + crossterm)
persona tui --identity alice # optional: preselect identity
q to quit, r to reload, ↑/↓ or j/k to navigate
# Connect local automation (secrets automation): read-only HTTP API on
# 127.0.0.1 for scripts/CI — token plaintext is shown exactly once
persona connect token create --label "my CI script"
persona connect serve
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:$PORT/api/v1/connect/items
# Secrets automation, CLI direct read (refs are IDENTITY/ITEM/FIELD)
persona secrets resolve work/deploy/api_key # one value per line
persona secrets run --env GH_TOKEN=work/ci/api_key -- gh repo view
persona secrets k8s --name deploy --key password=work/deploy/password | kubectl apply -f -
persona secrets external # Terraform external provider: stdin JSON -> stdout JSON
# Export to JSON with sensitive content (requires unlock)
persona export --include-sensitive --output backup.json
# Enable gzip compression and passphrase-based encryption
persona export --format yaml --compression 9 --encrypt --output backup.yaml
# Import (.json/.yaml/.csv); --decrypt prompts for the passphrase
persona import backup.enc --decrypt --mode merge --backup
Export an unencrypted .1pux file from 1Password (Settings → Export),
then preview and import it:
persona import-1pux export.1pux --dry-run # show the plan, touch nothing
persona import-1pux export.1pux # confirm, then import
Each 1Password vault becomes one identity (same-name identities are reused); Login items map to password credentials with TOTP secrets split into their own credentials, and API Credential / SSH Key items map to their persona equivalents. Unsupported categories, archived items, and attachments are reported and skipped — nothing is silently dropped or forced into a lossy shape.
# Generate an SSH key (ed25519) and store it in the vault
persona ssh generate --identity <name> --name "GitHub Key"
# Start the built-in agent and print the export command
persona ssh start-agent --print-export
export SSH_AUTH_SOCK=... # Copy to the current shell
# Provide the destination host and run a command
persona ssh run --host github.com -- ssh -T [email protected]
# Optional agent policies
export PERSONA_AGENT_REQUIRE_CONFIRM=1 # Prompt before every signature
export PERSONA_AGENT_MIN_INTERVAL_MS=1000 # Rate limit in milliseconds
export PERSONA_AGENT_ENFORCE_KNOWN_HOSTS=1 # Enforce known_hosts checks
export PERSONA_AGENT_CONFIRM_ON_UNKNOWN=1 # Ask before unknown hosts
# Status and shutdown
persona ssh agent-status
persona ssh stop-agent
# git commit signing (SSHSIG): install a copy of the binary named
# persona-ssh-sign, then point git at it
cp "$(command -v persona)" ~/.local/bin/persona-ssh-sign
git config gpg.format ssh
git config gpg.ssh.program ~/.local/bin/persona-ssh-sign
git config user.signingkey "persona:ssh:<credential-uuid>"
git commit -S # signed with the vault key
# Distribute a vault public key to a host's authorized_keys (idempotent;
# --dry-run previews, --list reads, --remove revokes)
persona ssh authorize --identity work --host [email protected]
Context signals (cwd, repository, target host) feed an advisory suggestion — context only ever proposes an identity, never authorizes one:
# Print the suggested identity for the current directory/repo
persona suggest # human-readable
persona suggest --json # machine-readable
persona suggest --short # one candidate name (feeds shell-hook)
# Show the candidate inline in your shell prompt
# (prints a snippet; append it to your shell rc)
persona shell-hook bash # or zsh
# Confirm the suggestion (alias of switch; audits the suggestion reason)
persona use
# Manage static context-to-identity mappings (pattern: host/owner/repo,
# or a host regex with --host)
persona context map github.com/acme/api --identity work
persona context status
The same signal reaches more surfaces: persona ssh run --host <host> prints a
one-line identity suggestion on stderr before connecting, and the browser
extension popup ranks the suggested identity's credentials first. Set
PERSONA_NO_CONTEXT=1 to disable the whole layer. Local learning of
cwd→identity candidates is off by default (persona context learn status).
# Password generator (also: --pronounceable, or --words N for a passphrase)
persona password generate --length 24
persona password generate --words 5 --count 3
# Vault health scan: weak / reused / expired / stale credentials, metadata only
persona watchtower
persona watchtower --check-breaches # + HIBP k-anonymity check (5-char hash prefix only)
persona watchtower --json # machine-readable report
# Auto-lock policies (list/show/create/update/delete/assign/set-default/stats)
persona auto-lock list
persona auto-lock stats
# Rotate the workspace master password (re-wraps keys; wallets use their own
# independent password via `persona wallet passwd`)
persona passwd
# Travel mode: move marked identities off this device and restore them back
persona travel mark <identity> # flag identities to travel with you
persona travel enter # pack marked identities into an encrypted sidecar
persona travel exit # restore them from the sidecar (needs travel passphrase)
persona travel status
# Encrypted server backups (custody endpoints; push needs no unlock)
persona backup push
persona backup list
persona backup pull <id> --out vault.enc
persona backup restore <id>
Crypto wallet management is on the deferred M5 track — treat it as experimental until that track graduates:
# Create a wallet (BIP-39 mnemonic; BTC / ETH / Solana derivation)
persona wallet generate --name "Main" --network bitcoin --hd
# Watch-only: an xpub, no private key material on this device
persona wallet create-watch-only --name "Cold" --network bitcoin --xpub <XPUB>
# Addresses and transactions (identifier = wallet ID or name; amounts in the
# chain's smallest unit — satoshis, wei, ...)
persona wallet list-addresses "Main"
persona wallet create-transaction "Main" --to <address> --amount 50000 --sign
# PSBT workflow (offline signing round trip; PSBTs travel as base64)
persona wallet export-psbt "Main" <address> 50000 140 --inputs <outpoint>
persona wallet sign-psbt "Main" <base64-psbt>
persona wallet finalize-psbt <base64-psbt>
# Wallets have their own password, independent from the master password
persona wallet passwd "Main"
Signing confirmations verify recipient, amount, and chain id with an address-poisoning heuristic; see WALLET_DESIGN.
Priority policy: the password-manager track targets 1Password parity first; wallet work stays experimental and deferred until that foundation is proven (wallet security requirements are higher and get a dedicated design pass).
docs/CONTRIBUTING.md for Conventional Commits and PR expectations.git checkout -b feat/cli-edit).feat(cli): add credential filters.make lint-all and make test-all both pass.This project is released under the MIT License. See LICENSE for details.
Security note: Persona is evolving quickly, and APIs/storage formats may change. Avoid using it with production secrets until the interfaces stabilize.
Manage your digital selves. Switch identity material with confidence.