Skip to content

Vault Format

dotsecenv vaults use a versioned JSONL format. The format includes a version field in the header JSON, allowing the format to evolve over time while maintaining backward compatibility.

The vault file consists of:

  1. Header marker line - Identifies the file as a dotsecenv vault
  2. Header JSON - Index for efficient lookups (identities, secrets)
  3. Data marker line - Separates header from data
  4. Data entries - One JSON object per line (identities, secrets, values)
# === VAULT HEADER v1 ===
{"version":1,"identities":[["fingerprint1",4],["fingerprint2",5]],"secrets":{...}}
# === VAULT DATA ===
{"type":"identity","data":{...}}
{"type":"secret","data":{...}}
{"type":"value","secret":"KEY","data":{...}}

Identities are stored as an ordered array of [fingerprint, line] pairs, sorted by line number (order added):

{
"version": 1,
"identities": [
["ABC123DEF456", 4],
["XYZ789GHI012", 5]
],
"secrets": {
"DATABASE_URL": {
"secret": 6,
"values": [7, 8]
}
}
}
FieldTypePurpose
versionintFormat version (currently 1)
identitiesarrayArray of [fingerprint, line] pairs, sorted by line number
secretsobjectMap of secret name to definition line and value lines

The array format preserves insertion order, which provides:

  • Deterministic output - Same vault always serializes identically
  • Git-friendly - Consistent ordering means cleaner diffs
  • Audit trail - Order reflects when identities were added
{
"type": "identity",
"data": {
"added_at": "2025-01-01T00:00:00Z",
"algorithm": "RSA",
"algorithm_bits": 4096,
"fingerprint": "ABC123DEF456789012345678901234567890ABCD",
"hash": "sha256:...",
"public_key": "-----BEGIN PGP PUBLIC KEY BLOCK-----...",
"signed_by": "ABC123DEF456789012345678901234567890ABCD",
"signature": "...",
"uid": "alice@example.com"
}
}
{
"type": "secret",
"data": {
"added_at": "2025-01-01T00:00:00Z",
"hash": "sha256:...",
"key": "DATABASE_URL",
"signature": "...",
"signed_by": "ABC123DEF456789012345678901234567890ABCD"
}
}
{
"type": "value",
"secret": "DATABASE_URL",
"data": {
"added_at": "2025-01-01T00:00:00Z",
"available_to": ["ABC123DEF456...", "XYZ789GHI012..."],
"hash": "sha256:...",
"signature": "...",
"signed_by": "ABC123DEF456789012345678901234567890ABCD",
"value": "base64-encoded-encrypted-blob"
}
}

dotsecenv detects the format version from the version field in the header JSON:

{"version":1,"identities":[...],"secrets":{...}}

This allows efficient version detection by parsing just the header line.

Line numbers in the header are 1-indexed (first line = 1):

LineContent
1Header marker (# === VAULT HEADER v1 ===)
2Header JSON
3Data marker (# === VAULT DATA ===)
4+Data entries (identities, secrets, values)

The header indexes point to line numbers where each entry can be found, enabling O(1) lookups.

The format version allows dotsecenv to evolve while maintaining compatibility:

  • Backward compatibility - Read older vaults without data loss
  • Forward evolution - Add new features without breaking existing vaults
  • Automatic migration - Future versions may include automatic upgrades

dotsecenv validates vault structure on read:

  1. Header marker must match expected format
  2. Header JSON must parse successfully
  3. Data marker must be present
  4. Line numbers in header must point to valid entries

Use the validate command to check vault integrity:

Terminal window
dotsecenv validate