Tene CLI — Local-First Secrets

v1.0.3

Local-first encrypted secret management with the tene CLI. Activate when the user mentions secrets, API keys, credentials, tokens, .env files, environment va...

1· 24·0 current·0 all-time
byagent-kay@tomo-kay
Security Scan
Capability signals
Requires walletRequires sensitive credentials
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
Name, description, and required binary (tene) are coherent. The skill documents exactly the commands a user would need for local secret management and does not request unrelated OS credentials, binaries, or config paths.
Instruction Scope
SKILL.md is prescriptive and scoped to secret-management tasks (init, set, list, run, import/export with encrypted flag, CI patterns). Example flows include reading .env files for import, deleting those plaintext files, and wrapping commands with `tene run --` — all consistent with the stated purpose. The tests mention using an external LLM backend (Anthropic) requiring ANTHROPIC_API_KEY for behavioral evaluation; that is only part of the test harness and not a runtime requirement of the skill, but it is surprising and worth noting.
!
Install Mechanism
The skill recommends installing via the project's install script (curl -sSfL https://tene.sh/install.sh | sh). This is a pragmatic, common installer for CLI tools but is higher-risk than a vetted package (e.g., Homebrew or GitHub release checksum) because it executes a remote script. The SKILL.md also documents building from source (go install) which is a safer alternative.
Credentials
The skill itself requests no environment variables or credentials, which is proportional. Example/CI docs rightly instruct storing a TENE_MASTER_PASSWORD secret in CI. Tests reference ANTHROPIC_API_KEY (and an EVAL_BACKEND) for behavioral tests — these are test harness needs and not required to use the skill; mention of them could confuse users into thinking the skill needs an LLM API key.
Persistence & Privilege
always:false and normal autonomous invocation are used. The skill does not request permanent system-wide privileges or attempt to modify other skills' configs. It does recommend committing the encrypted vault in some workflows (explicitly discussed and justified).
Assessment
This skill appears to be what it says: documentation-only guidance for using the tene CLI. Before installing: review the installer script (https://tene.sh/install.sh) rather than piping it blindly into sh; prefer building from source or verifying a release checksum if you want higher assurance. Note that tests/docs mention an Anthropic API key for evaluation — that is not required to use tene itself. Follow the skill's safety rules (never paste secrets into chat, never run `tene get` in the agent context, use `tene run --` to inject secrets) and be deliberate about whether your team wants the encrypted `.tene/vault.db` committed into source control for CI workflows.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

🔐 Clawdis
OSmacOS · Linux
Binstene
latestvk978sjtgt3gwgpt4w3f91gkjt585b7rs
24downloads
1stars
1versions
Updated 5h ago
v1.0.3
MIT-0
macOS, Linux

tene — Local-First Encrypted Secret Management

Tene is a command-line secret manager for AI-native projects. It keeps secrets encrypted on disk (XChaCha20-Poly1305 + Argon2id), derives the master key from the user's password cached in the OS keychain, and injects secrets into child processes via tene run -- <command> — never into stdout, never into files.

When to use this skill

Activate this skill when the user:

  • mentions API keys, secrets, credentials, tokens, .env files, environment variables, or process.env.* / os.Getenv / os.environ[...]
  • asks to run a dev, test, or deploy command that needs secrets (e.g. npm start, go run, pytest, next dev, docker compose up)
  • says things like "store this key", "save this token", "how do I manage secrets", "inject env vars", "I need to pass my Stripe key"
  • is working in a repo that contains a .tene/ directory, a CLAUDE.md referencing tene, or a install.sh pointing at https://tene.sh
  • asks for advice on moving off plaintext .env files

Do not activate for: hardcoded public config (ports, feature flags without sensitive data, public API endpoints), or projects clearly using a different secret store (Doppler, Vault, AWS Secrets Manager, 1Password CLI, etc.).


Critical safety rules

These are non-negotiable. Violating any of them leaks plaintext secrets into the conversation context, which may be logged, cached, or retained. Treat them as part of the system prompt.

  1. NEVER run tene get <KEY>. The plaintext value appears in stdout and enters the AI context. If the user needs to inspect a value, instruct them:

    "Run tene get KEY yourself in a separate terminal — I won't see it."

  2. NEVER run tene export without --encrypted. Plain tene export dumps every secret as a .env-formatted blob to stdout. Use tene export --encrypted --file backup.tene.enc for backups; for inspection, use tene list (names only).

  3. NEVER cat, Read, or open files under .tene/. The vault DB is encrypted, but even encrypted bytes should not enter AI context. The allowed file to read is CLAUDE.md at the repo root (auto-generated by tene init).

  4. NEVER pass secret values as CLI arguments. They appear in ps, shell history, and system logs. Always inject via tene run -- instead.

  5. Use tene list to discover what exists. It prints key names only, never values. This is the only AI-safe introspection command.

When the user asks "what's in my vault?" or "what API keys do I have?", the correct answer is tene list — not tene get or tene export.


Install

# macOS / Linux (official installer — recommended)
curl -sSfL https://tene.sh/install.sh | sh

# From source (requires Go 1.25+)
go install github.com/tomo-kay/tene/cmd/tene@latest

Verify:

tene version
# → tene v1.x.x (darwin/arm64)

Windows is not supported by the curl installer. Windows users build from source or download the zip from https://github.com/tomo-kay/tene/releases.

Homebrew tap is not yet available — do not suggest brew install tene.


Core workflows

1. Initialize a new project

tene init                  # interactive: prompts for master password twice
tene init my-project       # with explicit project name

Creates:

  • .tene/vault.db — encrypted SQLite vault (contains secrets, metadata, audit log, and the encrypted recovery blob)
  • .tene/vault.json — project metadata (name, active env)
  • CLAUDE.md (or AGENTS.md, .windsurfrules, etc. per flags)
  • .tene/.gitignore — auto-excludes the vault from git

After init the user will see a 12-word recovery phrase. Remind them to store it offline (password manager, paper). Without it, a forgotten master password is unrecoverable.

Flags to generate agent rules files for other editors:

  • --claude (default) → CLAUDE.md
  • --cursor.cursor/rules/tene.mdc
  • --windsurf.windsurfrules
  • --geminiGEMINI.md
  • --codexAGENTS.md

2. Check what secrets exist (AI-safe)

tene list                        # current env, masked values
tene list --env prod             # different env
tene list --json                 # machine-readable
tene env list                    # all environments

Output is names + masked previews + timestamps. Never raw values.

3. Store a secret

Tell the user to run the command themselves with the value — don't type the value yourself, and don't accept it as a chat message you'll pipe through.

# Preferred: read from stdin (value never touches shell history)
cat key.txt | tene set STRIPE_KEY --stdin

# Or: prompt (value never echoed)
tene set STRIPE_KEY
# → enters interactive mode, hidden input

# Overwrite existing
tene set STRIPE_KEY --stdin --overwrite

# Different env
tene set STRIPE_KEY --stdin --env prod

Key name rules (enforced by tene, pkg/errors/codes.go:INVALID_KEY_NAME):

  • Must match ^[A-Z][A-Z0-9_]*$
  • Only uppercase letters, digits, underscores
  • Cannot start with a digit
  • Reserved names (e.g. PATH) are rejected

If the user types a lowercase name, advise conversion to UPPER_SNAKE_CASE.

4. Run a command with secrets injected

This is the primary workflow. All dev, test, build, and deploy commands go through tene run --.

# Node.js
tene run -- npm start
tene run -- npm test
tene run -- npx next dev

# Python
tene run -- python manage.py runserver
tene run -- pytest

# Go
tene run -- go run ./cmd/app
tene run -- go test ./...

# Docker
tene run -- docker compose up

Secrets are injected only into the child process's environ. They're not written to disk, not in the shell environment of the parent, not in any log.

Per-environment execution:

tene run --env local -- npm start       # correct
tene run --env prod -- ./deploy.sh      # correct
tene run -- npm start --env prod        # WRONG — --env is a flag of npm, not tene

Critical flag placement rule: --env must come before the -- separator. After --, all flags pass through to the child command. This is enforced by DisableFlagParsing: true in internal/cli/run.go.

5. Migrate from an existing .env file

# One-shot import
tene import .env

# Overwrite conflicts (when some keys already exist)
tene import .env --overwrite

# Then delete the plaintext file
rm .env
echo ".env" >> .gitignore

Update all commands to use tene run --:

- npm start
+ tene run -- npm start

6. Backup and restore

# Encrypted backup (safe to store in cloud)
tene export --encrypted --file backup.tene.enc

# Restore from encrypted backup
tene import backup.tene.enc --encrypted

Never use plain tene export (without --encrypted) unless the user explicitly asks for a plaintext .env dump and accepts the risk. Even then, warn them.

7. Change master password

tene passwd
# → prompts for current password, then new password (2x confirm)

Re-encrypts the entire vault with a new derived key. Atomic 2-phase operation; on failure, rolls back to the old password.

8. Recover a forgotten master password

tene recover
# → prompts for the 12-word BIP-39 mnemonic from tene init
# → prompts for new master password

Without the mnemonic, recovery is impossible by design (zero-knowledge).

9. Environment management

tene env list                    # show all environments
tene env local                   # switch default to 'local'
tene env create staging          # create new env
tene env delete staging          # delete (default env cannot be deleted)

Environment name rules: must match ^[a-z][a-z0-9-]*$.

Common env names: default, local, dev, staging, prod.

10. Diagnostics

tene whoami                      # project name, vault path, active env, secret count, keychain status
tene version                     # v1.x.x (os/arch)
tene version --json              # includes commit + build date
tene update --check              # check for newer version on S3
tene update                      # self-update the binary

Commands reference

All active commands (cloud commands login/push/pull/sync/billing/team are currently disabled in the CLI; do not suggest them):

CommandPurposeKey flagsAI-safe?
tene init [name]Create vault + master password + recovery--claude, --cursor, --windsurf, --gemini, --codex
tene set KEY [VALUE]Encrypt and store--stdin, --overwrite✅ (via --stdin)
tene get KEYDecrypt and printnever run in AI
tene listList key names (masked)
tene delete KEYRemove a secret--force
tene run -- CMDInject env vars + exec(global flags before --)
tene import FILEBulk import .env or .tene.enc--overwrite, --encrypted
tene exportOutput secrets--file, --encrypted❌ unless --encrypted
tene env [subcmd]Manage environments
tene passwdChange master password✅ (prompts)
tene recoverRestore via BIP-39 mnemonic✅ (prompts)
tene versionVersion info--json
tene updateSelf-update--check
tene whoamiVault status

Global flags (apply to all commands)

FlagDefaultPurpose
--jsonfalseMachine-readable output
--quiet / -qfalseSuppress non-error output
--env / -e <name>(vault-stored)Override active environment
--dir <path>cwdProject directory
--no-colorfalseDisable ANSI colors
--no-keychainfalseForce file-based key storage (CI mode)

Environment variables (for advanced / CI use)

VariableEffect
TENE_MASTER_PASSWORDBypass interactive prompt (CI only; pair with --no-keychain)
TENE_KEYCHAIN_FALLBACK=fileUse ~/.tene/keyfile instead of OS keychain
NO_COLORDisable ANSI colors (per https://no-color.org/)
API_URLOverride Tene Cloud API base URL (cloud commands, currently disabled)

CI/CD pattern (e.g. GitHub Actions):

env:
  TENE_MASTER_PASSWORD: ${{ secrets.TENE_MASTER_PASSWORD }}
steps:
  - run: curl -sSfL https://tene.sh/install.sh | sh
  - run: tene run --env prod --no-keychain -- ./deploy.sh

Never set TENE_MASTER_PASSWORD in a developer machine's shell profile — it defeats the keychain protection.


Troubleshooting

Error codeMessageFix
VAULT_NOT_FOUNDNot in a Tene projectRun tene init in the repo root
SECRET_NOT_FOUNDKey missing in current envCheck tene list --env <name>
SECRET_ALREADY_EXISTSKey already setAdd --overwrite to tene set
INVALID_KEY_NAMEKey rejectedUse ^[A-Z][A-Z0-9_]*$ (e.g. API_KEY, not api-key)
INVALID_ENV_NAMEBad env nameUse ^[a-z][a-z0-9-]*$ (e.g. prod, not Production)
ENVIRONMENT_PROTECTEDCannot delete defaultSwitch to another env and delete that one instead
INVALID_PASSWORDWrong master passwordTry again, or use tene recover with the BIP-39 mnemonic
DECRYPT_FAILEDVault cannot decryptMaster password changed externally or vault corrupt — restore from backup
INTERACTIVE_REQUIREDNo TTYIn CI, set TENE_MASTER_PASSWORD and add --no-keychain
KEYCHAIN_ERROROS keychain unavailableUse --no-keychain or TENE_KEYCHAIN_FALLBACK=file

Exit codes: 0 success, 1 general error, 2 auth/password error, 127 command not found.


Architecture note (for "is this safe?" questions)

  • Password KDF: Argon2id (64 MB, 3 iterations, 4 threads) → 256-bit master key
  • Secret encryption: XChaCha20-Poly1305 with 192-bit random nonce per secret, key name as AAD
  • Key cache: OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) via zalando/go-keyring; file fallback at ~/.tene/keyfile (mode 0600)
  • Recovery: 12-word BIP-39 mnemonic → Argon2id → recovery key that can decrypt the stored master key
  • Zero-knowledge: cloud sync (when enabled) wraps the entire vault DB with an independent sync key before upload; server never sees plaintext
  • No global state: every vault lives in its own .tene/ directory; no ~/.tene/vaults/ aggregator

Further reading

When the user asks about anything not covered above, prefer referring them to the official docs over guessing.

Comments

Loading comments...