Python library to access Notepad++ Secrets Manager encrypted secrets
Project description
Notepad++ Secrets Manager - Python Library
A Python library to access secrets stored by the Notepad++ Secrets Manager plugin. Read encrypted secrets directly from Python scripts without opening Notepad++.
Features
- ✅ Read encrypted secrets - Access secrets stored by Notepad++ plugin
- ✅ Password protected - Verifies master password using SHA-256
- ✅ Strong encryption - Uses PBKDF2 + Windows DPAPI (same as C++ plugin)
- ✅ Simple API - Easy-to-use Python interface
- ✅ Type hints - Full type annotations for better IDE support
- ✅ Search & filter - Find secrets by name or category
- ✅ Environment variables - Export secrets as env vars
Installation
From PyPI
pip install npp-secrets
From source
cd python_library
pip install .
Development install
cd python_library
pip install -e ".[dev]"
Requirements
- Python 3.7+
- Windows (uses Windows DPAPI)
- pywin32 - For Windows Cryptography API access
Quick Start
Basic Usage
from npp_secrets import SecretsManager
# Initialize manager
manager = SecretsManager()
# Check if password is set
if manager.has_password():
# Unlock with your master password
manager.unlock("your_master_password")
# Get a specific secret
api_key = manager.get_secret("GitHub API Key")
print(f"API Key: {api_key}")
# List all secrets
for secret in manager.list_secrets():
print(f"{secret.name}: {secret.value}")
# Lock when done
manager.lock()
Using as Environment Variables
from npp_secrets import SecretsManager
import os
manager = SecretsManager()
manager.unlock("your_password")
# Get secrets as environment variables
env_vars = manager.get_as_env_dict()
os.environ.update(env_vars)
# Now use them
github_token = os.environ["GITHUB_API_KEY"] # From "GitHub API Key"
Search and Filter
from npp_secrets import SecretsManager
manager = SecretsManager()
manager.unlock("your_password")
# Search by name
results = manager.search_secrets("github")
for secret in results:
print(f"Found: {secret.name}")
# Get secrets by category
api_keys = manager.get_secret_by_category("API Keys")
for secret in api_keys:
print(f"{secret.name} = {secret.value}")
Error Handling
from npp_secrets import (
SecretsManager,
InvalidPasswordError,
SecretsFileNotFoundError,
SecretsManagerError
)
manager = SecretsManager()
try:
manager.unlock("wrong_password")
except InvalidPasswordError:
print("Incorrect password!")
except SecretsFileNotFoundError:
print("Secrets file not found. Create secrets in Notepad++ first.")
except SecretsManagerError as e:
print(f"Error: {e}")
Context Manager (Future)
from npp_secrets import SecretsManager
# Automatically locks when exiting context
with SecretsManager() as manager:
manager.unlock("your_password")
api_key = manager.get_secret("My API Key")
# Use the API key...
# Automatically locked here
API Reference
SecretsManager
Methods
__init__(config_dir: Optional[str] = None)
Initialize the secrets manager.
Parameters:
config_dir(optional): Custom config directory. Defaults to%APPDATA%\Notepad++\plugins\config
has_password() -> bool
Check if a master password has been set.
Returns: True if password exists, False otherwise
verify_password(password: str) -> bool
Verify if the provided password is correct.
Parameters:
password: Password to verify
Returns: True if correct, False otherwise
unlock(password: str) -> None
Unlock the secrets manager.
Parameters:
password: Master password
Raises:
InvalidPasswordError: If password is incorrectSecretsFileNotFoundError: If secrets file doesn't exist
lock() -> None
Lock the secrets manager and clear secrets from memory.
get_secret(name: str) -> Optional[str]
Get a secret by name.
Parameters:
name: Secret name
Returns: Secret value or None if not found
Raises:
SecretsManagerError: If not unlocked
get_secret_by_category(category: str) -> List[Secret]
Get all secrets in a category.
Parameters:
category: Category name
Returns: List of secrets
list_secrets() -> List[Secret]
Get all secrets.
Returns: List of all secrets
search_secrets(query: str) -> List[Secret]
Search secrets by name (case-insensitive).
Parameters:
query: Search query
Returns: List of matching secrets
get_as_dict() -> Dict[str, str]
Get all secrets as a dictionary.
Returns: Dictionary mapping secret names to values
get_as_env_dict() -> Dict[str, str]
Get secrets as environment variable dictionary.
Returns: Dictionary with UPPER_SNAKE_CASE names
Properties
is_unlocked: bool
Check if currently unlocked.
secret_count: int
Get the number of loaded secrets.
Secret (dataclass)
Attributes:
name(str): Secret namevalue(str): Secret valuecategory(str): Category (optional)
Exceptions
SecretsManagerError: Base exceptionInvalidPasswordError: Wrong passwordSecretsFileNotFoundError: Missing secrets file
Command-Line Usage
The library includes a CLI tool:
# Run interactive demo
npp-secrets
# Or use Python
python -m npp_secrets.secrets_manager
Output:
Enter master password: ********
✓ Unlocked! Found 5 secrets.
Available secrets:
• GitHub API Key [API Keys]
• AWS Access Key [API Keys]
• Database Password [Credentials]
Environment variable mapping:
GITHUB_API_KEY=***
AWS_ACCESS_KEY=***
DATABASE_PASSWORD=***
Use Cases
1. CI/CD Scripts
from npp_secrets import SecretsManager
manager = SecretsManager()
manager.unlock(os.environ["NPP_MASTER_PASSWORD"])
# Deploy using secrets
deploy_api_key = manager.get_secret("Deploy Key")
deploy_to_server(api_key=deploy_api_key)
2. Database Connections
from npp_secrets import SecretsManager
import psycopg2
manager = SecretsManager()
manager.unlock("master_pass")
db_password = manager.get_secret("Database Password")
conn = psycopg2.connect(
host="localhost",
user="admin",
password=db_password
)
3. API Testing
from npp_secrets import SecretsManager
import requests
manager = SecretsManager()
manager.unlock("master_pass")
api_key = manager.get_secret("Test API Key")
response = requests.get(
"https://api.example.com/data",
headers={"Authorization": f"Bearer {api_key}"}
)
4. Configuration Files
from npp_secrets import SecretsManager
import json
manager = SecretsManager()
manager.unlock("master_pass")
config = {
"api_key": manager.get_secret("API Key"),
"secret": manager.get_secret("App Secret"),
"token": manager.get_secret("Auth Token")
}
with open("config.json", "w") as f:
json.dump(config, f)
Security Considerations
✅ What This Library Does
- Encrypts secrets using Windows DPAPI (tied to your user account)
- Uses PBKDF2 with 10,000 iterations for key derivation
- Requires master password to decrypt
- Clears secrets from memory when locked
⚠️ Important Notes
- Secrets are tied to your Windows user account - Can't be decrypted on another machine or by another user
- Master password is required - Store it securely
- Auto-lock after 60 minutes - Plugin auto-locks, but Python library doesn't (call
lock()when done) - No recovery - If you forget the master password, secrets are lost
- Windows only - Uses Windows DPAPI
🔒 Best Practices
- Lock after use: Always call
manager.lock()when done - Don't hardcode passwords: Use environment variables or getpass
- Limit scope: Only unlock when needed
- Use strong passwords: For your master password
- Secure your scripts: Don't commit scripts with passwords
File Format
The library reads two binary files:
secrets_hash.dat
[4 bytes: hash_size]
[hash_size bytes: SHA-256 hash of password]
secrets.dat
[4 bytes: count]
For each secret:
[4 bytes: name_size]
[name_size bytes: encrypted name (salt + size + dpapi_data)]
[4 bytes: value_size]
[value_size bytes: encrypted value]
[4 bytes: category_size]
[category_size bytes: encrypted category]
Encrypted Field Format
[16 bytes: salt]
[4 bytes: data_size]
[data_size bytes: DPAPI encrypted data]
Development
Running Tests
pytest tests/
Type Checking
mypy npp_secrets/
Code Formatting
black npp_secrets/
Compatibility
| Component | Version |
|---|---|
| Python | 3.7+ |
| Windows | 7+ |
| Notepad++ Plugin | v1.0+ |
| pywin32 | 300+ |
License
This library is licensed under the GNU General Public License v2.0 or later, matching the Notepad++ plugin license.
See LICENSE for details.
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
Changelog
1.0.0 (2024)
- Initial release
- Read encrypted secrets from Notepad++ plugin
- Password verification
- Search and filtering
- Environment variable export
- CLI tool
Support
For issues or questions:
- Open an issue on GitHub
- Check the main plugin README
Related Projects
- Notepad++ Secrets Manager Plugin - The C++ plugin for Notepad++
Made with ❤️ for secure secret management in Notepad++
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file npp_secrets-1.0.0.tar.gz.
File metadata
- Download URL: npp_secrets-1.0.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
342f33f8badd05bf56e9da2946ca2a560779f07d8a47337be45d5159073b6478
|
|
| MD5 |
189b4688c3208257008bc47e47d6cd36
|
|
| BLAKE2b-256 |
23febe2473c6d6fd16c537bcf9e4a8044c2816d79eaafab7969a9c12cac5c427
|
File details
Details for the file npp_secrets-1.0.0-py3-none-any.whl.
File metadata
- Download URL: npp_secrets-1.0.0-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b6af045e7819a2c852b5d1f1e46ab49447a3173496b0f0df7de80508b804d63
|
|
| MD5 |
988845bbc351ab68ddf5163beab67b87
|
|
| BLAKE2b-256 |
46210d0568474e06acf68245b5aa8edd1db64f12e6a0513318d5afcb6be43f24
|