Skip to main content

Secure storage vault for secrets in git repositories (SOPS alike)

Project description

XVault

Python License Security KDF PyPI

XVault is a portable encrypted vault designed for developers to securely store secrets, tokens, certificates, and sensitive files while keeping encrypted vaults safe to store in Git repositories.

XVault is built around a simple idea:

Keep encrypted secrets versioned in Git while protecting the keys locally.

XVault supports modern cryptography, OS keyring integration, and flexible project configuration to make secret management safe and developer-friendly.

Single Source of Truth

XVault acts as a single source of truth for all sensitive configuration a project needs (secrets, tokens, passwords, certificates, and file blobs). From this encrypted vault, you can derive/export the exact formats your tooling expects (e.g., .env, JSON config, certificate files) without duplicating plaintext secrets across multiple files or repositories.

To minimize cognitive load, XVault keeps the workflow intentionally simple: one encrypted store, secure defaults, and straightforward commands—no servers to run, no KMS to configure, and no complex policy systems. It’s optimized for solo developers and small teams who want a local-first vault that integrates cleanly with Git.


Contents


Motivation

Many developers store secrets in .env files or private folders. These files are frequently committed accidentally to Git repositories. Tools such as Hashicorp Vault or Mozilla SOPS solve this problem for infrastructure environments, but they often require external key management systems.

XVault was created to provide a lightweight developer-focused vault that works locally, integrates with Git workflows, and requires no external infrastructure.

XVault focuses on a different niche than most secret-management tools:

  • Local-first — works without external infrastructure
  • Git-friendly — encrypted files are safe to version in repositories
  • Developer-oriented — designed for development workflows
  • Portable — no dependency on cloud KMS providers

The focus is developer ergonomics: fewer moving parts, fewer decisions, and a predictable workflow that works the same across projects.

Comparison with SOPS and git-crypt

XVault, SOPS (Secrets OPerationS), and git-crypt share a similar goal: storing encrypted secrets safely inside version-controlled files. They allow developers to keep encrypted configuration in Git while protecting the decryption keys locally. However, their design philosophies differ. SOPS focuses on infrastructure and DevOps workflows (Kubernetes, Terraform, cloud KMS integration), whereas XVault is designed primarily as a developer-centric vault, emphasizing simplicity, local password-based encryption, and flexible secret storage for development environments and personal projects.

Feature XVault SOPS git-crypt
Primary goal Developer secret vault Infrastructure secret management Encrypt selected files in a Git repo
Encryption model Password-derived key (Argon2id) External key management (KMS, GPG, Age) Key-based (GPG) / shared symmetric key for collaborators
Encryption algorithm AES-256-GCM AES-256-GCM AES (transparent file encryption)
Key derivation Argon2id Not applicable (external keys) Not a focus (GPG-managed keys)
Key storage OS keyring (optional cache) External key providers GPG keychain
File format XVault file YAML / JSON / ENV Original file formats (encrypted blobs in Git)
Git-friendly storage Yes Yes Yes (encrypted blobs in Git)
CLI workflow Developer-oriented DevOps / infrastructure-oriented Git workflow oriented
External dependencies None required Often requires KMS / GPG / Age Requires GPG (for multi-user)
Secret import/export dotenv, JSON YAML/JSON editing Not built-in
Typical use case Developer secrets, local environments, personal vaults Kubernetes, CI/CD, infrastructure configuration Team repos where only some files should be readable to authorized users

In short: XVault is a local-first, developer-oriented vault optimized for keeping a single source of truth and deriving/exporting the formats your projects need. SOPS is best when you want infrastructure-focused workflows and integration with KMS/GPG/Age key management. git-crypt is ideal when you want transparent encryption of specific files inside a Git repo, without a structured secrets store or import/export pipeline.

Example workflow

D:\Reps\myrepos> xvault create dev
Enter password: ********
Confirm password: ********
Store created: dev
Path: D:\Reps\myrepos\.secrets\xvault-dev.xvault
Status: unlocked

D:\Reps\myrepos> xvault set dev API_KEY
Enter secret value:   ********
Confirm secret value: ********
API_KEY created

D:\Reps\myrepos> xvault get dev API_KEY
12345678

D:\Reps\myrepos> xvault export dev --format env
API_KEY=12345678

XVault includes an interactive editor (similar to SOPS) that decrypts values in-memory, opens an editor view, and re-encrypts on save.

XVault demo

Design Philosophy

XVault prioritizes developer ergonomics: a predictable workflow, minimal setup, and secure defaults (password → key → keyring → encrypt/decrypt).

This makes XVault particularly well-suited for:

  • developer environments
  • local secret management
  • small teams encrypted vaults
  • Git-friendly secret storage without external infrastructure
  • personal encrypted vaults

Features

  • AES-256-GCM authenticated encryption
  • Argon2id password-based key derivation
  • Cross-platform keyring integration
  • Git-friendly .xvault files (JSON-based)
  • dotenv and JSON import/export
  • Multiple vault stores per project
  • Flexible vault location configuration
  • Designed for automation and developer workflows
  • Integrated interactive editor (SOPS-style) to edit vault contents safely

Security Model

XVault is designed to protect secrets stored in version-controlled repositories.

Threats mitigated

  • accidental disclosure of secrets committed to Git
  • unauthorized access to vault files without the password
  • offline brute-force attacks through strong password-based key derivation

Cryptographic design

Component Algorithm
Key derivation Argon2id
Encryption AES-256-GCM
Nonce 96-bit random nonce
Authentication GCM tag

Argon2id parameters:

time_cost = 5
memory_cost = 128 MB
parallelism = 4

These parameters significantly increase the cost of offline password brute-force attacks.

High-level encryption flow diagram

flowchart TD
  U[User enters password] --> KDF[Argon2id<br/>password + salt -> 32-byte key]
  KDF -->|optional| KR[Store derived key in OS keyring<br/>Windows DPAPI / macOS Keychain / Linux Secret Service]
  KDF --> AES[AES-256-GCM encryption/decryption]
  KR --> AES

  AES --> ENC[Encrypt secret value<br/>random nonce + ciphertext + tag]
  ENC --> FILE[Write to .xvault file<br/>value stored as enc:v1:...]
  FILE --> DEC[Read encrypted value from .xvault file]
  DEC --> AES
  AES --> OUT[Decrypt -> plaintext value]

Limitations

XVault does not protect against:

  • compromised host machines
  • malicious code execution
  • memory extraction attacks
  • weak user passwords

Example Vault File

Vault files are JSON documents containing encrypted values.

{
  "meta": {
    "schema_version": 1,
    "crypto_version": 1,
    "salt": "0a24afe64ea0b73bee45f1ad31fcbd2e",
    "check": "enc:v1:DtZmJqBmJbL+uvvojo4DmCs5+qhQUb80LiwV9mVqqy2VFfh5"
  },
  "secrets": {
    "API_KEY": {
      "type": "password",
      "description": "API key for external service",
      "meta": {},
      "services": [],
      "value": "enc:v1:..."
    }
  }
}

The vault file can safely be stored in Git because all secret values are encrypted.


Installation

Install from PyPI:

pip install xvault

Install from source (development)

Clone the repository:

# clone the repository:
git clone https://github.com/marcdp/xvault.git
# install dependencies:
pip install -r requirements.txt
# run the CLI:
python -m xvault
# or install as a command:
pip install .

Quick Start

Create a vault

xvault create dev

After creating a new vault, it is unlocked (key cached in the OS keyring)

List vaults

xvault list

Example output:

default   3 keys  unlocked
dev       1 key   locked

Store a secret

xvault set dev API_KEY

Retrieve a secret

xvault get dev API_KEY

Remove a secret

xvault remove dev API_KEY

Import Secrets

XVault can import from common formats.

Import .env

xvault import dev .env

Example .env:

DATABASE_URL=postgres://localhost/db
API_KEY=abcdef123

Import JSON

xvault import dev config.json

Example:

{
  "API_KEY": "123456",
  "SERVICE_TOKEN": "abcdef"
}

Export Secrets

Derive Project Secrets from the Vault

A common problem in real projects is secret sprawl: the same values end up duplicated across .env, CI variables, deployment scripts, and certificate files.

XVault avoids this by storing everything in one place and generating the rest on demand:

  • Store secrets once in XVault
  • Export to the format your project needs (.env, JSON, etc.)
  • (Optional) export file entries (certs/keys) back to real files when needed

Export vault contents:

xvault export dev

Formats supported:

--format env
--format json
--format xvault

Vault Unlocking

XVault caches vault keys securely using the system keyring.

Unlock a store:

xvault unlock dev

Lock it again:

xvault lock dev

Supported keyring backends:

  • Windows DPAPI
  • macOS Keychain
  • Linux Secret Service

Project Configuration

Vault location can be configured per Git repository.

Create a .xvault file in the project root:

file = ../dev/secrets/{project}-{name}.xvault

Variables:

Variable Meaning
{project} Git repository name
{name} vault store name

Example resulting file:

../dev/secrets/myproject-dev.xvault

This allows multiple repositories to share a centralized secrets directory.


Roadmap

Planned improvements:

  • rekey password: xvault repassword MYSTORE
  • VSCode extension (to manage xvault contents as a virtual filesystem)

License

MIT License

See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xvault-0.0.32.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xvault-0.0.32-py3-none-any.whl (22.6 kB view details)

Uploaded Python 3

File details

Details for the file xvault-0.0.32.tar.gz.

File metadata

  • Download URL: xvault-0.0.32.tar.gz
  • Upload date:
  • Size: 25.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for xvault-0.0.32.tar.gz
Algorithm Hash digest
SHA256 ed4373fbd88ed57dbd9a2ffd8675a61855a51209ff15f4848facffc0a33141d0
MD5 66d0630eacf927a4710de53a9bb61f08
BLAKE2b-256 2fc9b9de289b50a760c698cfd77f042b935203ed96c2a407cf999b5c92357a31

See more details on using hashes here.

File details

Details for the file xvault-0.0.32-py3-none-any.whl.

File metadata

  • Download URL: xvault-0.0.32-py3-none-any.whl
  • Upload date:
  • Size: 22.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for xvault-0.0.32-py3-none-any.whl
Algorithm Hash digest
SHA256 74c9f0e771519661e54c66c5121da117391cda9f4b148c66d93b2432fd563930
MD5 fc01d9f8b173c5fdb719dac9337e1e6b
BLAKE2b-256 314f99d71223dd5199bb3cbbaf2b092d54b4401cc46ee1bd7da6476734b2374d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page