Documentation
¶
Overview ¶
Package vault provides per-user encrypted SQLite shards with CRDT sync and on-chain anchoring. This is the unified local-first data SDK.
Architecture:
Cloud HSM / K-Chain ML-KEM
└── Master KEK (unwrapped via HSM or threshold decryption)
└── Org KEK = HMAC-SHA256(master, "vault:org:" + orgID)
└── User DEK = HMAC-SHA256(orgKEK, "vault:user:" + userID)
└── SQLite shard (AES-256-GCM encrypted)
└── CRDT sync via ZAP (conflict-free merge)
└── Merkle root anchored to chain
Usage:
vault.MustRegister(app, vault.Config{
DataDir: "/data/vaults",
MasterKey: masterKeyBytes, // from HSM or K-Chain
OrgID: "my-org",
ChainRPC: "http://localhost:9650/ext/bc/I", // optional anchoring
SyncEnabled: true,
})
Each authenticated user gets their own encrypted SQLite file. Reads/writes are instant (local). CRDT syncs in background. Chain stores merkle roots, never row data.
SDK exposes the 5 primitives that any app needs:
- Identity — OpenUser, bind device, resolve DID
- KeyAccess — GetShardKey, unwrap DEK, rotation
- LocalDB — OpenShard, read/write encrypted SQLite
- Sync — PushOps, PullOps, Merge (CRDT over ZAP)
- Anchor — CommitAnchor, merkle root to chain, audit proof
Usage:
v, _ := vault.Open(vault.SDKConfig{
DataDir: "/data/vaults",
MasterKEK: masterKey, // from HSM or K-Chain
OrgID: "my-org",
})
defer v.Close()
session, _ := v.OpenUser("user-123")
session.Put("prefs", []byte(`{"theme":"dark"}`))
val, _ := session.Get("prefs")
session.Sync()
receipt, _ := session.Anchor()
Index ¶
- func ExportVault(session *Session) ([]byte, error)
- func GetWithToken(token *ShareToken, store map[string][]byte, key string) ([]byte, error)
- func MustRegister(app core.App, config Config)
- func RecoverFromShares(shares [][]byte) ([]byte, error)
- func Register(app core.App, config Config) error
- type AnchorReceipt
- type AuditEntry
- type AuditLog
- type Bundle
- type BundleMetadata
- type Capability
- type ConfidentialEngine
- type ConfidentialQuery
- type ConfidentialResult
- type Config
- type DeviceKey
- type LocalConfidentialEngine
- type LocalRecoveryProvider
- type LocalStorageProvider
- func (p *LocalStorageProvider) GetBlob(hash string) ([]byte, error)
- func (p *LocalStorageProvider) GetSnapshot(vaultID string, hash string) ([]byte, error)
- func (p *LocalStorageProvider) PutBlob(key string, data []byte) (string, error)
- func (p *LocalStorageProvider) PutSnapshot(vaultID string, data []byte) (string, error)
- type LocalSyncProvider
- type Meter
- type Op
- type PolicyEngine
- type ProviderRegistry
- func (r *ProviderRegistry) GetRecovery(name string) (RecoveryProvider, error)
- func (r *ProviderRegistry) GetStorage(name string) (StorageProvider, error)
- func (r *ProviderRegistry) GetSync(name string) (SyncProvider, error)
- func (r *ProviderRegistry) RegisterRecovery(name string, p RecoveryProvider)
- func (r *ProviderRegistry) RegisterStorage(name string, p StorageProvider)
- func (r *ProviderRegistry) RegisterSync(name string, p SyncProvider)
- type RecoveryProvider
- type SDKConfig
- type Session
- func (s *Session) Anchor() (*AnchorReceipt, error)
- func (s *Session) CreateRecoveryShares(threshold, total int) ([][]byte, error)
- func (s *Session) Delete(key string)
- func (s *Session) Get(key string) ([]byte, error)
- func (s *Session) GetCollection(collection, key string) ([]byte, error)
- func (s *Session) Merge(remoteOps []Op)
- func (s *Session) Put(key string, value []byte) error
- func (s *Session) PutCollection(collection, key string, value []byte) error
- func (s *Session) ShareCollection(collection, recipientID string) *ShareToken
- func (s *Session) Sync() error
- type ShareToken
- type SharedSession
- type StorageProvider
- type SyncProvider
- type UsageReport
- type UserShard
- type Vault
- func (v *Vault) Close()
- func (v *Vault) EnrollDevice(userID, deviceID string) (*DeviceKey, error)
- func (v *Vault) OpenSharedVault(vaultID string, members []string) (*SharedSession, error)
- func (v *Vault) OpenUser(userID string) (*Session, error)
- func (v *Vault) RevokeDevice(userID, deviceID string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExportVault ¶
ExportVault exports the session's encrypted state as a portable JSON bundle. The bundle contains ciphertext only — the DEK is NOT included. The caller must supply the DEK separately to import.
func GetWithToken ¶
GetWithToken retrieves and decrypts a value using a ShareToken. Only works for keys in the token's collection.
func MustRegister ¶
MustRegister registers the vault plugin and panics on error.
func RecoverFromShares ¶
RecoverFromShares reconstructs a DEK by XOR-ing all shares together. Requires all shares (threshold == total in v2).
Types ¶
type AnchorReceipt ¶
type AnchorReceipt struct {
MerkleRoot string `json:"merkleRoot"`
UserID string `json:"userId"`
OrgID string `json:"orgId"`
Timestamp int64 `json:"timestamp"`
ChainTxID string `json:"chainTxId,omitempty"` // set after on-chain commit
OpCount int `json:"opCount"`
}
AnchorReceipt is returned by Anchor() — proof of chain commitment.
type AuditEntry ¶
type AuditEntry struct {
Timestamp time.Time `json:"timestamp"`
VaultID string `json:"vaultId"` // org:user
Actor string `json:"actor"` // DID of who performed the action
Action string `json:"action"` // "put", "get", "delete", "sync", "anchor", "grant", "revoke"
Resource string `json:"resource"` // key, capability ID, etc.
Hash string `json:"hash"` // SHA-256 of entry for chaining
PrevHash string `json:"prevHash"` // hash of previous entry (chain link)
}
AuditEntry records a single vault operation.
type AuditLog ¶
type AuditLog struct {
// contains filtered or unexported fields
}
AuditLog is an append-only log of vault operations. Entries are hash-chained: each entry's PrevHash points to the previous entry's Hash. The last hash is the audit merkle root, suitable for chain anchoring.
func (*AuditLog) GetAuditLog ¶
func (al *AuditLog) GetAuditLog(vaultID string, since time.Time) []AuditEntry
GetAuditLog returns entries for a vaultID since a given time. Pass time.Time{} (zero) to get all entries.
func (*AuditLog) MerkleRoot ¶
MerkleRoot returns the hash of the last entry, which is the root of the hash chain. This is the value anchored to chain. Returns empty string if the log is empty.
type Bundle ¶
type Bundle struct {
Version int `json:"version"`
UserID string `json:"userId"`
OrgID string `json:"orgId"`
Timestamp int64 `json:"timestamp"`
Snapshot json.RawMessage `json:"snapshot"` // encrypted store entries
Oplog []Op `json:"oplog"`
Metadata BundleMetadata `json:"metadata"`
}
Bundle is a portable vault export: JSON envelope with encrypted data + oplog + metadata.
type BundleMetadata ¶
type BundleMetadata struct {
KeyCount int `json:"keyCount"`
OpCount int `json:"opCount"`
Format string `json:"format"` // "vault-bundle-v3"
}
BundleMetadata holds non-sensitive metadata about the bundle.
type Capability ¶
type Capability struct {
ID string // deterministic: SHA-256(issuer + subject + resource + actions)
Issuer string // DID of the issuer
Subject string // DID of the subject (who can use this)
Resource string // vault ID, collection, or key pattern
Actions []string // "read", "write", "sync", "anchor", "share"
Expires time.Time // zero value = never expires
Signature []byte // signed by issuer (verified externally)
Revoked bool // set by Revoke()
}
Capability represents a delegated permission from one DID to another. Capabilities are signed by the issuer and scoped to specific resources/actions.
Example:
cap := &Capability{
Issuer: "did:lux:org:acme",
Subject: "did:lux:user:alice",
Resource: "vault:acme:*",
Actions: []string{"read", "write"},
Expires: time.Now().Add(24 * time.Hour),
}
type ConfidentialEngine ¶
type ConfidentialEngine interface {
Execute(session *Session, query *ConfidentialQuery) (*ConfidentialResult, error)
Verify(result *ConfidentialResult) (bool, error)
}
ConfidentialEngine processes queries on encrypted data. Implementations range from "decrypt locally and compute" (LocalConfidentialEngine) to full FHE/ZK backends. The interface is the same.
type ConfidentialQuery ¶
type ConfidentialQuery struct {
Operation string // "sum", "count", "match", "policy_check"
Target string // collection or key pattern
Params interface{} // query-specific parameters
}
ConfidentialQuery describes a computation to run on encrypted data.
type ConfidentialResult ¶
type ConfidentialResult struct {
Value interface{} // result (may be encrypted or plaintext depending on engine)
Proof []byte // hash-based proof of correct computation (optional)
Encrypted bool // whether Value is still encrypted
}
ConfidentialResult holds the output of a confidential computation.
type Config ¶
type Config struct {
Enabled bool `json:"enabled"`
DataDir string `json:"dataDir"` // directory for per-user SQLite shards
OrgID string `json:"orgId"` // organization identifier
MasterKey []byte `json:"-"` // 32-byte master KEK (from HSM/K-Chain)
ChainRPC string `json:"chainRpc"` // optional: I-Chain RPC for merkle anchoring
SyncEnabled bool `json:"syncEnabled"` // enable CRDT sync via ZAP
ZAPPort int `json:"zapPort"` // ZAP listen port for sync (default 9999)
}
Config configures the vault plugin.
type LocalConfidentialEngine ¶
type LocalConfidentialEngine struct{}
LocalConfidentialEngine is the baseline confidential compute engine. It decrypts data locally, runs the computation, and returns plaintext results with a hash-based proof of computation.
This is NOT FHE. It exists to exercise the ConfidentialEngine interface so callers are written correctly before a real FHE/ZK backend is plugged in. The proof is a SHA-256 hash binding the query + result — verifiable but not zero-knowledge.
func (*LocalConfidentialEngine) Execute ¶
func (e *LocalConfidentialEngine) Execute(session *Session, query *ConfidentialQuery) (*ConfidentialResult, error)
Execute runs a confidential query against a session's encrypted store. Supported operations:
- "count" — count keys matching Target prefix
- "sum" — sum numeric values for keys matching Target prefix
- "match" — check if key Target equals Params (string)
- "policy_check" — check if subject (Target) has action (Params) via PolicyEngine
func (*LocalConfidentialEngine) Verify ¶
func (e *LocalConfidentialEngine) Verify(result *ConfidentialResult) (bool, error)
Verify checks that a result's proof matches its value. For the local engine, the proof is SHA-256(json(Value)).
type LocalRecoveryProvider ¶
type LocalRecoveryProvider struct {
// contains filtered or unexported fields
}
LocalRecoveryProvider stores threshold key shares in a local directory.
func NewLocalRecoveryProvider ¶
func NewLocalRecoveryProvider(dir string) (*LocalRecoveryProvider, error)
NewLocalRecoveryProvider creates a recovery provider backed by a directory.
func (*LocalRecoveryProvider) FetchShares ¶
func (p *LocalRecoveryProvider) FetchShares(userID string, indices []int) ([][]byte, error)
FetchShares retrieves encrypted shares for a user by index.
func (*LocalRecoveryProvider) StoreShare ¶
func (p *LocalRecoveryProvider) StoreShare(userID string, shareIndex int, encryptedShare []byte) error
StoreShare stores an encrypted share for a user.
type LocalStorageProvider ¶
type LocalStorageProvider struct {
// contains filtered or unexported fields
}
LocalStorageProvider uses content-addressed file storage.
func NewLocalStorageProvider ¶
func NewLocalStorageProvider(dir string) (*LocalStorageProvider, error)
NewLocalStorageProvider creates a storage provider backed by a directory.
func (*LocalStorageProvider) GetBlob ¶
func (p *LocalStorageProvider) GetBlob(hash string) ([]byte, error)
GetBlob retrieves a blob by content hash.
func (*LocalStorageProvider) GetSnapshot ¶
func (p *LocalStorageProvider) GetSnapshot(vaultID string, hash string) ([]byte, error)
GetSnapshot retrieves a snapshot by vault ID and content hash.
func (*LocalStorageProvider) PutBlob ¶
func (p *LocalStorageProvider) PutBlob(key string, data []byte) (string, error)
PutBlob stores a blob and returns its content hash.
func (*LocalStorageProvider) PutSnapshot ¶
func (p *LocalStorageProvider) PutSnapshot(vaultID string, data []byte) (string, error)
PutSnapshot stores a snapshot and returns its content hash.
type LocalSyncProvider ¶
type LocalSyncProvider struct {
// contains filtered or unexported fields
}
LocalSyncProvider uses filesystem + channels for local/self-hosted sync.
func NewLocalSyncProvider ¶
func NewLocalSyncProvider(dir string) (*LocalSyncProvider, error)
NewLocalSyncProvider creates a sync provider backed by a directory.
func (*LocalSyncProvider) Pull ¶
func (p *LocalSyncProvider) Pull(vaultID string, since uint64) ([]Op, error)
Pull returns ops with Seq > since for the given vault.
type Meter ¶
type Meter struct {
// contains filtered or unexported fields
}
Meter tracks per-vault operation counts. Designed for pay-per-use billing but works locally too.
func (*Meter) GetUsage ¶
func (m *Meter) GetUsage(vaultID string) *UsageReport
GetUsage returns the usage report for a vault.
func (*Meter) RecordAnchor ¶
RecordAnchor increments the anchor counter for a vault.
func (*Meter) RecordSync ¶
RecordSync increments the sync counter for a vault.
type Op ¶
type Op struct {
Seq uint64 `json:"seq"`
NodeID string `json:"nodeId"`
Key string `json:"key"`
Value []byte `json:"value"` // encrypted
Time int64 `json:"time"`
}
Op is a CRDT operation in the oplog.
type PolicyEngine ¶
type PolicyEngine struct {
// contains filtered or unexported fields
}
PolicyEngine manages capability-based access control for vaults. Thread-safe. All capabilities are held in memory (persisted to vault shard in production via Put/Get).
func NewPolicyEngine ¶
func NewPolicyEngine() *PolicyEngine
NewPolicyEngine creates an empty policy engine.
func (*PolicyEngine) Check ¶
func (pe *PolicyEngine) Check(subject, resource, action string) bool
Check returns true if subject has the given action on resource. Checks expiry and revocation.
func (*PolicyEngine) Grant ¶
func (pe *PolicyEngine) Grant(cap *Capability) error
Grant issues a capability. The capability ID is computed deterministically. Returns an error if required fields are missing.
func (*PolicyEngine) List ¶
func (pe *PolicyEngine) List(subject string) []*Capability
List returns all non-revoked capabilities for a subject.
func (*PolicyEngine) Revoke ¶
func (pe *PolicyEngine) Revoke(capID string) error
Revoke revokes a capability by ID.
type ProviderRegistry ¶
type ProviderRegistry struct {
// contains filtered or unexported fields
}
ProviderRegistry discovers and manages providers.
func NewProviderRegistry ¶
func NewProviderRegistry() *ProviderRegistry
NewProviderRegistry creates an empty registry.
func (*ProviderRegistry) GetRecovery ¶
func (r *ProviderRegistry) GetRecovery(name string) (RecoveryProvider, error)
GetRecovery returns a recovery provider by name.
func (*ProviderRegistry) GetStorage ¶
func (r *ProviderRegistry) GetStorage(name string) (StorageProvider, error)
GetStorage returns a storage provider by name.
func (*ProviderRegistry) GetSync ¶
func (r *ProviderRegistry) GetSync(name string) (SyncProvider, error)
GetSync returns a sync provider by name.
func (*ProviderRegistry) RegisterRecovery ¶
func (r *ProviderRegistry) RegisterRecovery(name string, p RecoveryProvider)
RegisterRecovery registers a named recovery provider.
func (*ProviderRegistry) RegisterStorage ¶
func (r *ProviderRegistry) RegisterStorage(name string, p StorageProvider)
RegisterStorage registers a named storage provider.
func (*ProviderRegistry) RegisterSync ¶
func (r *ProviderRegistry) RegisterSync(name string, p SyncProvider)
RegisterSync registers a named sync provider.
type RecoveryProvider ¶
type RecoveryProvider interface {
}
RecoveryProvider assists with key recovery via threshold shares.
type SDKConfig ¶
type SDKConfig struct {
DataDir string // directory for per-user SQLite shards
MasterKEK []byte // 32-byte master key (from HSM or K-Chain)
OrgID string // organization identifier
// Optional: chain anchoring
ChainRPC string // I-Chain RPC for merkle root commits
// Optional: sync
SyncPeers []string // ZAP peer addresses for CRDT sync
}
SDKConfig configures a Vault instance (standalone, no Base app required).
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is a per-user encrypted data context. It holds the user's DEK and provides all 5 SDK primitives.
func ImportVault ¶
ImportVault imports a vault from a portable bundle. The caller must provide the correct DEK to decrypt values.
func (*Session) Anchor ¶
func (s *Session) Anchor() (*AnchorReceipt, error)
Anchor computes a merkle root over the current state and returns a receipt suitable for on-chain commitment. The chain stores ONLY the root hash — never row data, never keys.
func (*Session) CreateRecoveryShares ¶
CreateRecoveryShares splits the user DEK into `total` shares using XOR-based secret sharing. Any `threshold` shares can reconstruct the DEK when threshold == total (all shares needed). Proper Shamir SSS in v3.
func (*Session) GetCollection ¶
GetCollection retrieves a value encrypted with the collection-scoped DEK.
func (*Session) Merge ¶
Merge applies remote ops into local state. Each op carries encrypted values — merge does not require DEK.
func (*Session) Put ¶
Put stores an encrypted key-value pair. Value is encrypted with the user's DEK before storage.
func (*Session) PutCollection ¶
PutCollection stores a value encrypted with the collection-scoped DEK.
func (*Session) ShareCollection ¶
func (s *Session) ShareCollection(collection, recipientID string) *ShareToken
ShareCollection creates a ShareToken that lets recipientID decrypt only the named collection. Collection DEK = HMAC-SHA256(userDEK, "collection:" + collectionName).
type ShareToken ¶
type ShareToken struct {
}
ShareToken carries a re-encrypted DEK scoped to a single collection.
type SharedSession ¶
type SharedSession struct {
// contains filtered or unexported fields
}
SharedSession is a multi-member vault derived from the org KEK + vaultID. Members list controls who can access. Each member decrypts with the shared DEK.
func (*SharedSession) GetAs ¶
func (ss *SharedSession) GetAs(userID, key string) ([]byte, error)
GetAs retrieves a value only if the caller is a member.
func (*SharedSession) IsMember ¶
func (ss *SharedSession) IsMember(userID string) bool
IsMember returns true if the given userID is in the members list.
type StorageProvider ¶
type StorageProvider interface {
PutSnapshot(vaultID string, data []byte) (string, error) // returns content hash
GetSnapshot(vaultID string, hash string) ([]byte, error)
PutBlob(key string, data []byte) (string, error)
GetBlob(hash string) ([]byte, error)
}
StorageProvider stores encrypted snapshots and blobs.
type SyncProvider ¶
type SyncProvider interface {
Push(vaultID string, ops []Op) error
Pull(vaultID string, since uint64) ([]Op, error)
Subscribe(vaultID string, callback func([]Op)) error
}
SyncProvider relays encrypted CRDT ops between devices/users.
type UsageReport ¶
type UsageReport struct {
VaultID string `json:"vaultId"`
Puts int64 `json:"puts"`
Gets int64 `json:"gets"`
Syncs int64 `json:"syncs"`
Anchors int64 `json:"anchors"`
}
UsageReport holds operation counts for a vault.
type UserShard ¶
type UserShard struct {
UserID string
Path string // filesystem path to the .db file
DEK []byte // 32-byte data encryption key for this user
}
UserShard is an encrypted per-user SQLite database.
type Vault ¶
type Vault struct {
// contains filtered or unexported fields
}
Vault is the top-level SDK handle. One per app process.
func (*Vault) EnrollDevice ¶
EnrollDevice creates a device-specific wrapping key for the given user. Device key = HMAC-SHA256(userDEK, "device:" + deviceID). The device key wraps the user DEK for local storage on that device.
func (*Vault) OpenSharedVault ¶
func (v *Vault) OpenSharedVault(vaultID string, members []string) (*SharedSession, error)
OpenSharedVault creates a shared vault accessible by the listed members. The DEK is derived from orgKEK + vaultID (not any single user).
func (*Vault) OpenUser ¶
OpenUser opens (or creates) a session for a user. Derives the per-user DEK and opens the encrypted SQLite shard.
func (*Vault) RevokeDevice ¶
RevokeDevice removes a device key. The user DEK is unaffected — other devices continue to work. In production, the revoked device's wrapped DEK copy becomes useless because its wrapping key is discarded.