
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
PAK (Password Age Kit) - A simple, secure password manager in JavaScript using age encryption
A simple, secure password manager in JavaScript using age encryption. This is a TypeScript port of the shell script from https://github.com/tonidy/pa-cli, providing cross-platform compatibility and modern features.
npm install -g @kdbx/pak
Or use directly with npx:
npx @kdbx/pak --help
Note: The
pakcommand is available after installation. In Indonesia, using "Pak" isn’t just about calling someone "sir" — it’s about showing respect, building community, and being part of a culture that values kindness and humility.
So whether you're asking for help or giving a command, saying "Pak" makes everything sound more friendly and respectful — just like how locals do it.
And now, you're using pak as a command-line tool 😄.
# Add a password (will prompt to generate or enter manually)
pak add mysite
# Show a password
pak show mysite
# List all passwords
pak list
# Edit a password with your $EDITOR
pak edit mysite
# Delete a password
pak del mysite
# Search passwords with fzf
pak find
# Search and perform action
pak find show # or edit, del
# Git operations
pak git log
pak git status
# Version information
pak version
# Secure Enclave information (macOS only)
pak se-info
# Convert recipients between formats
pak convert age1se1qfn44rsw... yubikey
pak convert age1yubikey1qfn44rsw... se
PAK provides comprehensive support for Apple's Secure Enclave through age-plugin-se, offering hardware-backed encryption with biometric authentication.
# Install age-plugin-se
brew install age-plugin-se
# Verify installation
pak se-info
# Auto-select access control (non-interactive)
export PA_SE_ACCESS_CONTROL=any-biometry-or-passcode
# Auto-confirm Secure Enclave usage (non-interactive)
export PA_SE_AUTO_CONFIRM=1
# Check Secure Enclave support
pak se-info
# Generate identity with custom access control
PA_SE_ACCESS_CONTROL=any-biometry pak add mysite
# Convert between plugin formats
pak convert age1se1qfn44rsw0xvmez3pky46nghmnd5up0jpj97nd39zptlh83a0nja6skde3ak yubikey
# Output: age1yubikey1qfn44rsw0xvmez3pky46nghmnd5up0jpj97nd39zptlh83a0nja6skde3ak
# Use converted recipient for encryption on systems without age-plugin-se
echo "secret" | age -r age1yubikey1qfn44rsw0xvmez3pky46nghmnd5up0jpj97nd39zptlh83a0nja6skde3ak
Use the SE integration programmatically:
const { AgeManager, AppleSecureEnclave } = require('@kdbx/pak');
// Initialize with SE support
const config = {
useAgeBinary: false, // Use native SE integration
seAccessControl: 'any-biometry-or-passcode'
};
const ageManager = new AgeManager(config);
// Check SE availability
const isAvailable = await ageManager.isSecureEnclaveAvailable();
// Generate SE identity
const identity = await ageManager.generateSecureEnclaveIdentity('any-biometry');
// Use direct SE module
const secureEnclave = new AppleSecureEnclave({
accessControl: 'any-biometry-or-passcode',
recipientType: 'piv-p256',
useNative: true
});
const keyPair = await secureEnclave.generateKeyPair('any-biometry');
const capabilities = await secureEnclave.getCapabilities();
PAK can be configured through environment variables, a config.json file, or programmatically.
Configure the password manager behavior with these environment variables:
# Data directory (default: ~/.local/share/pa)
export PA_DIR=~/.local/share/pa
# Default password length (default: 50)
export PA_LENGTH=50
# Password character pattern (default: A-Za-z0-9-_)
export PA_PATTERN=A-Za-z0-9-_
# Disable git tracking
export PA_NOGIT=1
# Disable system credential storage
export PA_NO_KEYRING=1
# Editor command (default: vi)
export EDITOR=nano
# Force age binary usage (instead of JS library)
export PA_USE_AGE_BINARY=1
# Custom age binary path
export PA_AGE_BINARY_PATH=/opt/homebrew/bin/age
# Secure Enclave access control
export PA_SE_ACCESS_CONTROL=any-biometry-or-passcode
# Auto-confirm Secure Enclave usage
export PA_SE_AUTO_CONFIRM=1
Create a config.json file in your working directory:
{
"paDir": "~/.local/share/pa",
"paLength": 50,
"paPattern": "A-Za-z0-9-_",
"paNoGit": false,
"paNoKeyring": false,
"editor": "vi",
"useAgeBinary": true,
"ageBinaryPath": "/opt/homebrew/bin/age",
"seAccessControl": "any-biometry-or-passcode",
"seAutoConfirm": false
}
Configuration is applied in this order (highest priority first):
config.json filePAK supports three age encryption backends:
For CLI-based Secure Enclave usage, you need to install the age-plugin-se:
# Install age-plugin-se for CLI backend
brew install age-plugin-se
The age binary is automatically used when:
useAgeBinary: true is set in configPA_USE_AGE_BINARY=1 environment variable is set# Force age binary usage for full plugin support
export PA_USE_AGE_BINARY=1
pak add mysite # Will use age binary with Touch ID support
~/.local/share/pa/
├── identities # Age private keys
├── recipients # Age public keys
└── passwords/ # Encrypted password files
├── .git/ # Git repository (optional)
├── .gitattributes # Git diff configuration
└── *.age # Encrypted password files
You can also use PAK programmatically:
import { PasswordManager } from '@kdbx/pak';
const pm = new PasswordManager();
// Add a password
await pm.add('mysite', { generate: true, length: 32 });
// Retrieve a password
const password = await pm.show('mysite');
// List all passwords
const passwords = await pm.list();
// Delete a password
await pm.delete('mysite');
git clone https://github.com/tonidy/pak-cli.git
cd pak-cli
npm install
npm run build
npm test
npm run dev -- add mysite
If you're migrating from the original pa shell script:
PA_DIR to your existing password directoryIf you're already using age-plugin-se with pa-cli:
npm install -g @kdbx/pak
brew install age-plugin-se
export PA_DIR=/path/to/your/existing/pa/directory
pak se-info
If you have recipients in different formats, you can convert them:
# Convert Secure Enclave recipient to YubiKey format
pak convert age1se1qfn44rsw0xvmez3pky46nghmnd5up0jpj97nd39zptlh83a0nja6skde3ak yubikey
# Convert YubiKey recipient to Secure Enclave format
pak convert age1yubikey1qfn44rsw0xvmez3pky46nghmnd5up0jpj97nd39zptlh83a0nja6skde3ak se
MIT License - see LICENSE file for details.
If you discover a security vulnerability, please report it through GitHub Security Advisories instead of using the issue tracker or email. This ensures proper handling and responsible disclosure of security issues.
FAQs
PAK (Password Age Kit) - A simple, secure password manager in JavaScript using age encryption
We found that @kdbx/pak demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.