Learn-skills.dev credentials
Encrypted credential store — add, retrieve, list, and delete named secrets (API keys, tokens, passwords) stored AES-256-GCM encrypted at ~/.aibtc/credentials.json. Each write operation requires the master password; listing metadata does not.
git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/aibtcdev/skills/credentials" ~/.claude/skills/neversight-learn-skills-dev-credentials && rm -rf "$T"
data/skills-md/aibtcdev/skills/credentials/SKILL.mdCredentials Skill
Manages arbitrary named secrets — API keys, tokens, passwords, URLs — encrypted at rest using AES-256-GCM with per-credential PBKDF2 key derivation. Values are stored as encrypted blobs in
~/.aibtc/credentials.json; only identifiers, labels, categories, and timestamps are stored in plaintext. No wallet is required — the credential store uses its own master password independent of the wallet system.
Usage
bun run credentials/credentials.ts <subcommand> [options]
Subcommands
add
Add a new credential or update an existing one. The value is encrypted with AES-256-GCM using a key derived from the master password via PBKDF2 (100,000 iterations, per-credential salt).
bun run credentials/credentials.ts add --id <id> --value <value> --password <pass> [--label <text>] [--category <cat>]
Options:
(required) — Normalized credential identifier (e.g.--id
,hiro-api-key
)openrouter-token
(required) — Plaintext secret value (sensitive — not stored)--value
(required) — Master password for encryption (sensitive)--password
(optional) — Human-readable label (default: same as id)--label
(optional) — Category tag such as--category
,api-key
,token
, orurl
(default:secret
)secret
Output:
{ "success": true, "id": "hiro-api-key", "label": "Hiro API Key", "category": "api-key", "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-01-01T00:00:00.000Z" }
get
Decrypt and return a credential value. The plaintext value appears in the output — handle with care.
bun run credentials/credentials.ts get --id <id> --password <pass>
Options:
(required) — Credential identifier--id
(required) — Master password for decryption (sensitive)--password
Output:
{ "id": "hiro-api-key", "label": "Hiro API Key", "category": "api-key", "value": "hiro_api_key_xxxxxxxxxxxxxxxx", "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-01-01T00:00:00.000Z" }
Tip: Extract the value in scripts with
$(bun run credentials/credentials.ts get --id hiro-api-key --password $CRED_PASS | jq -r .value)
list
List all credential identifiers and metadata. No decryption is performed and no secret values are returned.
bun run credentials/credentials.ts list
Output:
{ "count": 2, "credentials": [ { "id": "hiro-api-key", "label": "Hiro API Key", "category": "api-key", "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-01-01T00:00:00.000Z" } ] }
delete
Permanently delete a credential. Requires the master password (to verify ownership) and an explicit confirmation string.
bun run credentials/credentials.ts delete --id <id> --password <pass> --confirm DELETE
Options:
(required) — Credential identifier to delete--id
(required) — Master password for verification (sensitive)--password
(required) — Must be exactly--confirmDELETE
Output:
{ "success": true, "deleted": "hiro-api-key", "message": "Credential \"hiro-api-key\" has been permanently deleted." }
rotate-password
Change the master password by atomically re-encrypting all credentials. Decrypts every credential with the old password and re-encrypts with the new one. If any credential fails to decrypt, the operation is aborted before any changes are written.
bun run credentials/credentials.ts rotate-password --old-password <pass> --new-password <pass>
Options:
(required) — Current master password (sensitive)--old-password
(required, min 8 chars) — New master password (sensitive)--new-password
Output:
{ "success": true, "message": "Password rotated. 3 credentials re-encrypted.", "count": 3 }
Security Notes
- Credentials are AES-256-GCM encrypted with a unique salt and IV per credential — a compromised credential does not weaken others
- PBKDF2-SHA256 with 100,000 iterations makes brute-force attacks expensive
- The master password is never written to disk — pass it via
flag or environment variable substitution--password
is written with mode 0o600 (owner read/write only)~/.aibtc/credentials.json- The credential store is independent of the wallet system — a separate master password is recommended
anddelete
verify the password by decrypting before mutating the storerotate-password