← Docs

OpenCreds

Status: 0.1 draft · reference implementation available (@logicsrc/opencreds)

Slug: opencreds

OpenCreds is a LogicSRC OpenSpec for credential records and portable vaults. It defines what a credential item is, how a vault is encrypted, and what a vault looks like as a file — so that moving a vault between two products is a supported operation rather than a plaintext CSV export.

It exists because leaving a password manager currently means writing every secret you own to disk in the clear, and losing whatever the spreadsheet had no column for.

What it defines

One record, six types. Logins, cards, identities, notes, keys and accounts are not six features — they are one record with a type and a named field group. Everything the user typed lives inside a single encrypted blob, which is what makes password history free: it is an array in that blob, encrypted by construction rather than needing its own protected table.

{
  "v": 1,
  "id": "6f1e7b3a-1f4e-4f0f-9a1d-6a2f0b6f8d21",
  "type": "login",
  "name": "GitHub",
  "folderId": null,
  "notes": "",
  "login": {
    "username": "anthony",
    "password": "…",
    "totp": "otpauth://totp/GitHub:anthony?secret=…",
    "uris": [{ "uri": "https://github.com", "match": "domain" }]
  },
  "history": [],
  "createdAt": "2026-08-29T00:00:00.000Z",
  "updatedAt": "2026-08-29T00:00:00.000Z"
}

One envelope. AES-256-GCM over that JSON, with the item id bound in as additional authenticated data. A ciphertext moved from one row to another fails to decrypt rather than quietly showing the wrong credential — without that, anyone with database write access could swap a low-value login's ciphertext into a high-value one and watch what the user does next.

One key hierarchy. The master password is stretched once by PBKDF2-SHA256 into a master key, and everything else is derived from it by HKDF with a distinct label. The only password-derived value that ever reaches a server comes out of a different label than the wrapping key, so holding it does not help decrypt anything.

One file. A vault exports as a single .opencreds JSON document, encrypted by default, carrying a manifest — item count, type histogram, digest over the item ids — that is authenticated by the same tag as the data. A truncated import fails instead of looking like a complete one.

What it does not define

Sync. Storage. Autofill. A conforming vault is a file and a key; how two devices reconcile, where the ciphertext lives, and how a browser fills a form are all left to the implementation.

Implementations

Implementation Profile Namespace Notes
@logicsrc/opencreds user, team opencreds Reference implementation; local store and CLI
logicsrc credentials team opencreds .env secrets and SSH keys as key items
@marksyncr/vault user marksyncr Pre-dates the spec; conformant via its declared namespace

MarkSyncr's vault shipped before OpenCreds and has domain-separation labels baked into every ciphertext already written. Labels cannot be edited — changing one makes every existing vault undecryptable — so the spec carries the label prefix as a declared per-vault namespace rather than mandating a single string. See crypto.md.

Quick start

# Create a vault (asks for a master password; prints a recovery key once)
logicsrc vault init

# Add items
logicsrc vault add login --name GitHub --username anthony --url https://github.com
logicsrc vault add card --name "Visa ending 4242"
logicsrc vault add key --name "deploy key" --key-type ssh --file ~/.ssh/id_ed25519

# List (never prints secret values)
logicsrc vault list --type login

# Move the vault somewhere else, encrypted
logicsrc vault export --out vault.opencreds
logicsrc vault import vault.opencreds --dry-run

# Import from another product
logicsrc vault import bitwarden-export.csv --source bitwarden --dry-run

The same commands ship as the standalone opencreds binary, so logicsrc vault validate and opencreds validate are the same contract.

Relationship to the other LogicSRC specs

  • Credential Sharing (credential-sharing.md) moves secrets between providers.env, Doppler, Railway, GitHub, SSH. It models a key/value pair and a sync plan. OpenCreds models the record and the vault file. A key item is what a synced .env entry becomes when it is stored rather than moved.
  • OpenContext (opencontext.md) governs what an agent may read. An agent that resolves a context bundle may be entitled to one OpenCreds item and not the vault; the permission decision is OpenContext's, the record shape is OpenCreds'.
  • OpenOntology (openontology.md) names the entities a credential belongs to. An account item's provider is an ontology entity, not a free string, where an ontology is in use.