openvaultdb-go

module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: Apache-2.0

README

OpenVaultDB

OpenVaultDB is a small local database server with pluggable storage engines and per-database schema modes. It stores data in backends you own — a SQLite file or an inGitDB directory tree — and exposes a uniform JSON HTTP API. The primary goal of the current MVP is to prove that Sneat's business logic can switch storage backends without modification:

sneat-cli → Sneat facades → DALgo → dalgo2openvaultdb → OpenVaultDB HTTP → SQLite | inGitDB

Tagline: user-owned, portable, versioned data.

  • Records stored as human-readable YAML files (inGitDB) or SQLite rows you can inspect directly.
  • Each write batch = one git commit (inGitDB), giving you a full write history for free.
  • Schema modes let you start schemaless and tighten to strict later without changing client code.
  • The DALgo driver (dalgo2openvaultdb) means any existing DALgo application can use OpenVaultDB with no business-logic changes.

This repository is the OpenVaultDB librarypkg/* (manifest, schema, core, mount, server) plus the conformance suite. The ovdb CLI (serve, init, status, databases, token, version) has moved to its own repo, github.com/openvaultdb/ovdb.

OpenVaultDB Cloud catalogue client

The dependency-free cloud package reads safe registration metadata for databases accessible to an authenticated OpenVaultDB Cloud account. It exposes only database and Space metadata; it never reads records or credentials.

client, err := cloud.NewClient("https://cloud.openvaultdb.com")
if err != nil {
	return err
}
page, err := client.ListDatabases(ctx, accessToken, cloud.ListDatabasesRequest{
	Space: "personal",
})

The API requires the explicit databases:read scope. The client uses bounded JSON responses and never follows authenticated redirects.

Quickstart

1. Install the CLI
go install github.com/openvaultdb/ovdb@latest

Or build it from source — see github.com/openvaultdb/ovdb for instructions. That repo pins an exact tagged version of this library (currently v0.1.0).

2. Create a manifest
# inGitDB schemaless (recommended for exploration)
ovdb init --id mydb --engine ingitdb --schema-mode schemaless
# → writes mydb.yaml

# SQLite strict (requires declaring schemas upfront)
ovdb init --id mydb-sqlite --engine sqlite --schema-mode strict
# → writes mydb-sqlite.yaml (edit to add schemas.collections)
3. Start the server
ovdb serve --manifest mydb.yaml
# or point at a directory of *.yaml manifests:
ovdb serve --dir ./manifests

The server binds to 127.0.0.1:6832 by default. Override with --addr.

Authentication is off by default (local dev). Enable it with ovdb serve --auth: the owner token is taken from --owner-token / $OVDB_OWNER_TOKEN (or generated and printed), and apps obtain scoped tokens through the consent flow at /authorize + /token — see the Authentication section in docs/api.md.

4. Try the API
BASE="http://127.0.0.1:6832/v1"

# Server status
curl -s "$BASE/status" | jq .

# Put a record
curl -s -X PUT "$BASE/databases/mydb/records/contacts/c1" \
  -H 'Content-Type: application/json' \
  -d '{"data":{"name":"Alice","email":"alice@example.com"}}' 

# Get the record
curl -s "$BASE/databases/mydb/records/contacts/c1" | jq .

# Query
curl -s -X POST "$BASE/databases/mydb/query" \
  -H 'Content-Type: application/json' \
  -d '{"collection":"contacts","where":[{"field":"name","op":"==","value":"Alice"}],"limit":10}' | jq .

# Batch (atomic multi-op, single git commit on inGitDB)
curl -s -X POST "$BASE/databases/mydb/batch" \
  -H 'Content-Type: application/json' \
  -d '{
    "message": "add contacts",
    "ops": [
      {"op":"set","key":"contacts/c2","data":{"name":"Bob"}},
      {"op":"delete","key":"contacts/old"}
    ]
  }' | jq .

Manifest examples

database:
  id: mydb
  schema_mode: schemaless   # no schema declaration required

storage:
  engine: ingitdb
  path: ./data/mydb          # directory; init'd automatically

  ingitdb:
    push: none               # none (default) | sync | async
    # remote: origin         # git remote to push to (default "origin")
    # branch: HEAD           # branch to push (default: current HEAD)

push: sync waits for the git push to complete before acknowledging the write. push: async triggers a coalesced background push; failures are logged but do not fail the write. push: none (default) commits locally and never pushes — suitable for local dev and offline use.

inGitDB — strict
database:
  id: contacts-db
  schema_mode: strict

storage:
  engine: ingitdb
  path: ./data/contacts-db

  ingitdb:
    push: async

schemas:
  collections:
    contacts:
      fields:
        name:  {type: string, required: true}
        email: {type: string}
        tags:  {type: array}
SQLite — strict (MVP: strict only)
database:
  id: contacts-sqlite
  schema_mode: strict       # only mode supported by SQLite in MVP

storage:
  engine: sqlite
  path: ./data/contacts.sqlite

schemas:
  collections:
    contacts:
      fields:
        name:  {type: string, required: true}
        email: {type: string}

Schema modes

Mode SQLite (MVP) inGitDB Behaviour
strict yes yes Schema required before writes. Declared fields validated (type, required). Unknown fields rejected.
partial no yes Declared fields validated; unknown fields pass through and are recorded in the inferred catalogue.
schemaless no yes No declared schema needed. All writes observed into the inferred catalogue.

SQLite supports strict mode only in the MVP — this is an implementation choice (per-field column evolution for nested DTOs is a follow-up), not a permanent design constraint.

Schemaless does not mean no schema information: OpenVaultDB still observes and catalogues field types from every write. The inferred catalogue is readable at GET /v1/databases/{db}/inferred-schema.

Field types

string, number, integer, boolean, object, array, any.


DALgo driver

Use dalgo2openvaultdb to talk to ovdb serve from Go:

import dalgo2openvaultdb "github.com/dal-go/dalgo2openvaultdb"

db, err := dalgo2openvaultdb.NewDB("http://127.0.0.1:6832", "mydb")

// Write inside a transaction (buffered → single POST /batch on commit)
err = db.RunReadwriteTransaction(ctx, func(ctx context.Context, tx dal.ReadwriteTransaction) error {
    rec := dal.NewRecordWithData(dal.NewKeyWithID("contacts", "c1"), &MyData{Name: "Alice"})
    return tx.Set(ctx, rec)
}, dal.TxWithMessage("add Alice"))

See github.com/dal-go/dalgo2openvaultdb for the full driver README and capability table.


Documentation

  • Architecture — component overview, engine internals, schema modes, batch semantics
  • HTTP API — wire contract, all endpoints, error codes, update op format
  • Threat model — security posture, known risks, non-goals
  • Roadmap — near/medium/long-term follow-ups

Sneat end-to-end validation

The MVP is validated end-to-end by running Sneat's conversational CLI commands against an OpenVaultDB server backed by an inGitDB schemaless manifest in a real git repo.

Prerequisites
  • ovdb built and on PATH
  • sneat CLI built from sneat-go/sneat-cli
  • A git-initialised directory for the data store
Setup
# Create the data repo
mkdir -p /tmp/sneat-ovdb-data && cd /tmp/sneat-ovdb-data
git init && git commit --allow-empty -m "init"

# Write an inGitDB schemaless manifest
cat > sneat.yaml <<'EOF'
database:
  id: sneat-dev
  schema_mode: schemaless

storage:
  engine: ingitdb
  path: ./data/sneat-dev

  ingitdb:
    push: none
EOF

# Start the server
ovdb serve --manifest sneat.yaml &
Run Sneat commands through OpenVaultDB
export SNEAT_STORAGE=openvaultdb
export OPENVAULTDB_URL=http://127.0.0.1:6832

# Real facade operations (Contactus / Listus / Calendarius), persisted across processes:
sneat convo say --yes "add Jane Doe to contacts"
sneat convo say "list my contacts"
sneat convo say --yes "add milk and bread to shopping list"
sneat convo say --yes "add contact John"
sneat convo say --yes "meet John tomorrow at 5pm"
sneat convo say "list my calendar"

# Inspect the records that landed as YAML files in the git repo
find /tmp/sneat-ovdb-data/data/sneat-dev -name '*.yaml' -not -path '*/.git/*' | head -20
git -C /tmp/sneat-ovdb-data/data/sneat-dev log --oneline

Each sneat convo command results in one or more git commits in the data directory, with human-readable YAML record files and auto-generated commit messages from OpenVaultDB.


Firestore manifest example
database:
  id: myapp
  schema_mode: schemaless   # firestore supports strict | partial | schemaless

storage:
  engine: firestore
  firestore:
    project: my-gcp-project
    database: ""            # default "(default)"

Credentials come from Application Default Credentials, or set FIRESTORE_EMULATOR_HOST for the local emulator. Firestore conformance tests run when that env var is set (gcloud emulators firestore start).

PostgreSQL manifest example
database:
  id: myapp
  schema_mode: strict     # postgres: strict only in MVP

storage:
  engine: postgres
  postgres:
    dsn_env: OVDB_POSTGRES_DSN   # env var holding the DSN (default shown)

schemas:
  collections:
    contacts:
      fields:
        title: {type: string, required: true}

Set the connection string in the environment, never the manifest: export OVDB_POSTGRES_DSN='postgres://user:pass@host:5432/db?sslmode=require'. Conformance tests run when DALGO2POSTGRES_TEST_DSN points at a reachable PostgreSQL (e.g. docker run -e POSTGRES_PASSWORD=… -p 5432:5432 postgres:17).

MySQL manifest example
database:
  id: myapp
  schema_mode: strict     # mysql: strict only in MVP

storage:
  engine: mysql
  mysql:
    dsn_env: OVDB_MYSQL_DSN   # env var holding the DSN (default shown)

schemas:
  collections:
    contacts:
      fields:
        title: {type: string, required: true}

Set the connection string (go-sql-driver form) in the environment, never the manifest: export OVDB_MYSQL_DSN='user:pass@tcp(host:3306)/db?parseTime=true'. Conformance tests run when DALGO2MYSQL_TEST_DSN points at a reachable MySQL (e.g. docker run -e MYSQL_ROOT_PASSWORD=… -e MYSQL_DATABASE=ovdb -p 3306:3306 mysql:8).

GitHub-backed inGitDB manifest example

Write records straight to a GitHub repo (no local working tree; one commit per batch):

database:
  id: myapp
  schema_mode: strict     # github backend: strict | partial

storage:
  engine: ingitdb
  ingitdb:
    github:
      owner: my-user-or-org
      repo: my-data-repo
      ref: main                 # branch (default main)
      token_env: OVDB_GITHUB_TOKEN

schemas:
  collections:
    contacts:
      fields:
        title: {type: string, required: true}

Provide a token with contents:write on the repo in the environment, never the manifest: export OVDB_GITHUB_TOKEN=ghp_.... The branch must already exist (the tree writer commits onto it). Conformance runs when OVDB_GH_TEST_REPO (owner/repo) + OVDB_GITHUB_TOKEN point at a throwaway repo.

Cloud-managed PostgreSQL / MySQL

The postgres and mysql engines connect to managed cloud databases — Amazon RDS & Aurora, Azure Database for PostgreSQL/MySQL, Google Cloud SQL — unchanged: point the DSN env var at the cloud endpoint with TLS. No new engine required.

MVP boundaries

In MVP
  • ovdb CLI: serve, init, status, databases, version
  • HTTP API v1: get/exists/put/post/patch/delete per record, batch, query, inferred-schema endpoint
  • SQLite engine (strict mode only)
  • inGitDB engine (strict / partial / schemaless)
  • Database manifest (YAML): id, schema_mode, engine, path, ingitdb push options, schemas
  • Inferred schema catalogue for partial/schemaless databases
  • dalgo2openvaultdb driver (full DALgo CRUD + queries + transactions)
  • DALgo end2end conformance suite passes for all three engine/mode combinations
  • Sneat CLI validated end-to-end via SNEAT_STORAGE=openvaultdb
Not in MVP
  • Auth (no bearer tokens, no ACLs; local-dev only)
  • TLS, rate limiting, audit log
  • Firestore or other remote engines inside OpenVaultDB
  • Hosted api.openvaultdb.com
  • Multi-tenancy, billing
  • SQLite partial/schemaless schema modes
  • GraphSpec / ModelSpec integration
  • GraphQL, admin UI
  • Replication, sync, conflict resolution, migrations
  • Read-your-writes across HTTP round-trips (driver buffers writes client-side)
  • Per-field SQLite columns / indexes
  • Query cursors, offsets, projections, group-by over the HTTP API

See docs/roadmap.md for the prioritised follow-up list.

Directories

Path Synopsis
Package cloud provides a small, dependency-free client for OpenVaultDB Cloud registration metadata.
Package cloud provides a small, dependency-free client for OpenVaultDB Cloud registration metadata.
Package demo is the public OpenVaultDB client for bounded local application demos.
Package demo is the public OpenVaultDB client for bounded local application demos.
examples
layered-acl command
Command layered-acl starts a local, authenticated query demonstration with real SQLite and InGitDB storage.
Command layered-acl starts a local, authenticated query demonstration with real SQLite and InGitDB storage.
pkg
auth
Package auth implements the OpenVaultDB auth MVP: an OAuth-style connect flow (consent → one-time code → scoped bearer token), capability grants persisted with hashed tokens, and HTTP middleware enforcing them.
Package auth implements the OpenVaultDB auth MVP: an OAuth-style connect flow (consent → one-time code → scoped bearer token), capability grants persisted with hashed tokens, and HTTP middleware enforcing them.
authorizationapi
Package authorizationapi validates the DTQL authorization HTTP ingress.
Package authorizationapi validates the DTQL authorization HTTP ingress.
core
Package core is the thin OpenVaultDB layer between the HTTP API and DALgo drivers.
Package core is the thin OpenVaultDB layer between the HTTP API and DALgo drivers.
inferred
Package inferred implements the inferred schema catalogue for OpenVaultDB.
Package inferred implements the inferred schema catalogue for OpenVaultDB.
manifest
Package manifest defines the OpenVaultDB database manifest format.
Package manifest defines the OpenVaultDB database manifest format.
mount
Package mount loads database manifests and opens the corresponding DALgo drivers, producing ready-to-serve core.Database instances.
Package mount loads database manifests and opens the corresponding DALgo drivers, producing ready-to-serve core.Database instances.
policystore
Package policystore publishes immutable filesystem-owned policy generations.
Package policystore publishes immutable filesystem-owned policy generations.
schema
Package schema defines OpenVaultDB schema modes and record validation.
Package schema defines OpenVaultDB schema modes and record validation.
server
Package server exposes mounted OpenVaultDB databases over the minimal HTTP API documented in docs/api.md.
Package server exposes mounted OpenVaultDB databases over the minimal HTTP API documented in docs/api.md.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL