nimvault/gpg

GPG encryption/decryption and recipient resolution.

Types

GpgConfig = object
  recipient*: string
  root*: string ## When non-empty, paths are relative to this dir (not ~/...)
                ## Which primitive encrypts blobs and the manifest. "gpg" keeps the
                ## long-standing behaviour where signing and encryption are one operation.
                ## "age" separates them: age has no signing, so authenticity moves to a
                ## detached signature over the manifest, whose recorded hashes already
                ## cover every blob.
  backend*: string           ## "gpg" (default) | "age"
  identity*: string          ## age identity file; required when backend is age
  signer*: string            ## "gpg" (default) | "ssh" | "none"
  signKey*: string           ## ssh private key used to sign the manifest
  allowedSigners*: string    ## ssh allowed-signers file used to verify it
  signerIdentity*: string    ## principal to match within allowed_signers
NimvaultError = object of CatchableError
VaultConfigFile = tuple[recipient, root, backend, identity, signer, signKey,
                        allowedSigners, signerIdentity: string]

Vars

nvQuiet {.threadvar.}: bool
When true, suppress banners/echo (C ABI / MCP in-process)

Procs

proc gpgDecrypt(inPath, outPath: string; verifySig = false) {.
    ...raises: [OSError, IOError, ValueError, NimvaultError], tags: [ExecIOEffect,
    ReadEnvEffect, RootEffect, ReadIOEffect, TimeEffect, WriteIOEffect],
    forbids: [].}
Decrypt a GPG-encrypted file to a target path.
proc gpgDecryptToString(inPath: string; verifySig = false): string {.
    ...raises: [OSError, IOError, ValueError, NimvaultError], tags: [ExecIOEffect,
    ReadEnvEffect, RootEffect, ReadIOEffect, TimeEffect, WriteIOEffect],
    forbids: [].}
proc gpgEncrypt(cfg: GpgConfig; inPath, outPath: string) {.
    ...raises: [OSError, IOError, ValueError, NimvaultError], tags: [ExecIOEffect,
    ReadEnvEffect, RootEffect, ReadIOEffect, TimeEffect, WriteIOEffect],
    forbids: [].}
Encrypt and sign a file using GPG with the configured recipient.
proc gpgParallelism(): int {....raises: [], tags: [ReadEnvEffect], forbids: [].}
proc initGpgConfig(cliRecipient: string; repo: string): GpgConfig {.
    ...raises: [IOError, NimvaultError],
    tags: [ReadDirEffect, ReadIOEffect, ReadEnvEffect], forbids: [].}
Build a GpgConfig by resolving recipient and root from the 3-tier chain.
proc nvRaise(msg: string) {....raises: [NimvaultError], tags: [], forbids: [].}
Library-safe failure (no process exit). CLI catches and quits.
proc resolveRecipient(cli, env, configRecipient: string): string {.
    ...raises: [NimvaultError], tags: [ReadEnvEffect], forbids: [].}
3-tier recipient lookup:
  1. CLI --recipient flag
  2. NIMVAULT_GPG_RECIPIENT env var
  3. value from .vault/config
proc sha256sum(path: string): string {....raises: [NimvaultError, IOError],
                                       tags: [ReadIOEffect], forbids: [].}
proc sha256sumBytes(data: string): string {....raises: [], tags: [], forbids: [].}