Skip to content

xraph/vault

Repository files navigation

Vault

Composable secrets, feature flags, and runtime config for Go.

Vault is a Go library that unifies three capabilities behind a single API surface: encrypted secrets, rule-based feature flags, and hot-reloadable runtime configuration. It is a library, not a service — you import it, bring your own database and encryption key, and control the process lifecycle. Vault provides the plumbing: encryption, versioning, tenant-scoped evaluation, rotation, audit, and a plugin system for extending every subsystem.

Vault is part of the Forge ecosystem and integrates cleanly with Forge extensions, Grove ORM stores, and Confy config sources — but none of them are required to use it standalone.

Features

Secrets

  • AES-256-GCM encryption at rest, transparent decryption on read
  • Auto-versioning — every Set archives the previous value; fetch any historical version by number
  • Environment-variable key provider with hex/base64 auto-detection
  • Optional metadata (expiration, custom fields)

Feature flags

  • Five value types: bool, string, int, float, json
  • Six targeting rule types: WhenTenant, WhenTenantTag, WhenUser, Rollout (deterministic %), Schedule (time window), Custom (plugin-evaluated)
  • Priority-ordered evaluation with per-tenant overrides
  • Type-safe accessors (Bool, String, Int, Float, JSON) that return a default on error
  • LRU evaluation cache with configurable TTL (default 30s)

Runtime configuration

  • Typed entries (string, bool, int, float, json) with Duration parsing
  • Per-tenant overrides resolved ahead of the app-level value
  • Version tracking and Watch callbacks fired on mutation
  • Composable sources: memory, env, database, priority chain

Cross-cutting

  • Tenant isolation by designscope.WithTenantID(ctx, ...) propagates to every service via context.Context; cross-tenant reads are structurally impossible
  • Secret rotation — background manager with per-key Rotator callbacks, automatic versioning, and record-keeping
  • Audit logging — append-only trail of action/resource/outcome with full scope context; optional hook for forwarding to external systems
  • Plugin system — register plugins that implement any subset of eight capability interfaces (OnInit, OnShutdown, SourceProvider, EncryptionProvider, FlagEvaluator, OnSecretAccess, OnConfigChange, RotationStrategy)
  • TypeID identifiers — every entity uses type-prefixed, K-sortable UUIDv7 IDs (sec_, flag_, cfg_, …); passing the wrong prefix fails at parse time

Install

go get github.com/xraph/vault

Quick start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/xraph/vault/config"
    "github.com/xraph/vault/crypto"
    "github.com/xraph/vault/flag"
    "github.com/xraph/vault/scope"
    "github.com/xraph/vault/secret"
    "github.com/xraph/vault/store/memory"
)

func main() {
    ctx := scope.WithScope(context.Background(), "myapp", "tenant-1", "user-42", "10.0.0.1")

    store := memory.New()

    enc, err := crypto.NewEncryptor([]byte("my-32-byte-secret-key-for-vault!"))
    if err != nil {
        log.Fatal(err)
    }

    // Secrets — encrypted, auto-versioned
    secrets := secret.NewService(store, enc, secret.WithAppID("myapp"))
    meta, _ := secrets.Set(ctx, "openai-api-key", []byte("sk-abc123"), "myapp")
    sec, _ := secrets.Get(ctx, "openai-api-key", "myapp")
    fmt.Printf("secret v%d = %s\n", meta.Version, sec.Value)

    // Feature flags — evaluated against context scope
    flags := flag.NewService(flag.NewEngine(store), flag.WithAppID("myapp"))
    if flags.Bool(ctx, "new-dashboard", false) {
        fmt.Println("new dashboard enabled")
    }

    // Runtime config — typed accessors with defaults
    cfg := config.NewService(store, config.WithAppID("myapp"))
    _ = cfg.Set(ctx, "rate-limit", 100, "myapp")
    fmt.Printf("rate limit = %d\n", cfg.Int(ctx, "rate-limit", 50))
}

See docs/content/docs/getting-started.mdx for a step-by-step walkthrough covering rule-based flags, tenant overrides, rotation, and swapping in a production store.

Storage backends

Every backend satisfies the same composite store.Store interface — secrets, flags, config, overrides, rotation, and audit — so switching stores is a single type change. All expose Migrate, Ping, and Close.

Backend Import Use case
Memory github.com/xraph/vault/store/memory Tests, development, single-process demos
PostgreSQL github.com/xraph/vault/store/postgres Production, direct pgx connection pool
SQLite github.com/xraph/vault/store/sqlite Embedded deployments, local-first apps (via Grove)
MongoDB github.com/xraph/vault/store/mongo Document-oriented workloads (mongo-driver/v2)
Grove github.com/xraph/vault/store/grovestore Apps already using the Grove ORM

Architecture at a glance

Vault is organised as a root package with shared types, six service packages implementing domain logic, supporting packages for encryption/scoping/sources, and a set of store backends implementing one composite interface.

Every operation follows the same three-phase flow: scope the context → resolve the value (tenant override → rule match → default) → respond with a coerced type or the caller's default on error. See docs/content/docs/architecture.mdx for the full package diagram and request-flow breakdown.

Ecosystem integration

Forge extension. Mount Vault as a Forge extension to auto-wire the store, encryption, audit hooks, and a management dashboard into your Forge app. See extension/ and docs/content/docs/guides/forge-extension.mdx.

Confy source. Adapt Vault as a Confy ConfigSource and SecretProvider so a single confy.Load call pulls typed config and encrypted secrets through Vault alongside your other sources. See confy/ and docs/content/docs/guides/confy-integration.mdx.

Configuration

The root Config struct controls instance-wide behaviour. All fields have sensible defaults via DefaultConfig().

Field Purpose Default
AppID Application identifier used to scope secrets, flags, and config
EncryptionKey 32-byte AES-256-GCM master key
EncryptionKeyEnv Fallback environment variable holding the key (hex or base64)
FlagCacheTTL TTL for the flag evaluation cache 30s
SourcePollInterval Interval for polling database-backed config sources 30s

Matching functional options live in options.go: WithAppID, WithEncryptionKey, WithEncryptionKeyEnv, WithLogger, WithConfig.

Development

The Makefile exposes short aliases for the common workflows:

make test         # go test ./...
make test-race    # go test -race ./...
make coverage     # coverage.out + function-level summary
make coverage-html
make lint         # golangci-lint run ./...
make fmt          # gofmt + goimports
make check        # fmt + vet + lint
make docs         # serve the Next.js docs site at http://localhost:3000
make deps         # install goimports, air, golangci-lint

Requires Go 1.25+. See go.mod for the full dependency set.

Documentation

A full documentation site lives under docs/ and can be served locally with make docs. Key pages:

Status

Actively developed. Core service APIs (secret, flag, config) are stable; storage backends and the Forge/Confy integrations continue to evolve — see recent commits on main.

License

See the repository root for licensing.

About

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors