BlindVault is a privacy-preserving credential issuance and redemption service built on BLS12-381 blind signatures and DLEQ proofs.
BlindVault enables clients to request unbiased blind credentials, verify that the server signed them with a derived public key, and consume them without revealing the underlying secret material.
- Blind credential issuance using BLS12-381 blind signatures
- DLEQ proof of correct signing key usage
- Epoch and credential class key derivation from a single master seed
- Replay protection using deterministic nullifiers
- Redis-backed nullifier and revocation stores for production
- JWT-protected issuance and admin endpoints
- Health and Prometheus metrics endpoints
- Optional demo endpoints for local testing and examples
- Create
configs/config.yamlfor local development or set the environment variables directly. - Set a master seed using the preferred environment variables:
export BLINDVAULT_MASTER_SEED_HEX=<32-byte-hex-seed>
# or, for file-based secret injection:
export BLINDVAULT_SEED_FILE=/path/to/seed.txt- Run the server. The server accepts an optional
.envfile via--env-fileand will apply YAML values before environment overrides unless--env-overrideis used:
go run ./cmd/server/main.go --config configs/config.yaml
# or load a local env file first
# go run ./cmd/server/main.go --config configs/config.yaml --env-file .env --env-override- Validate health:
curl http://localhost:8080/health- Optional: scrape Prometheus metrics:
curl http://localhost:8080/metricsdocs/api_reference.md— API endpoints, request and response formats, and errorsdocs/client_reference.md— Go client library and CLI usagedocs/deployment_guide.md— deployment, Docker Compose, Redis setup, and health checksdocs/crypto_spec.md— cryptographic specification, DLEQ proof details, and security assumptionsdocs/crypto_vectors.md— generated test vector placeholderCONTRIBUTING.md— contribution process and testing guidelines
BlindVault includes a high-level Go client wrapper in pkg/client and a command-line interface in cmd/bv.
Build the CLI:
go build -o bv ./cmd/bvExamples:
bv blind --message "hello" --server http://localhost:8080
bv unblind --signature <blind_signature_hex> --id <request_id>
bv redeem --signature <unblinded_signature_hex> --witness <witness_hex> --class tier_gold --epoch 2026-01The blind command returns JSON with blinded, witness, and request_id. The verify command validates a DLEQ proof locally, unblind converts a blind signature into an unblinded one using the stored request state, and redeem submits the credential to /v1/credential/consume.
Client state is persisted to ~/.blindvault/state.json.
go test ./...
go test -v ./pkg/cryptogo run scripts/generate_vectors.go --output docs/crypto_vectors.mdThe server reads the YAML config first and then applies environment overrides. The preferred secret-loading paths are:
BLINDVAULT_MASTER_SEED_HEXfor in-memory secretsBLINDVAULT_SEED_FILEfor a mounted or generated secret file
Common runtime overrides include:
BLINDVAULT_MODEACTIVE_EPOCHSUPPORTED_EPOCHSDSTAUTH_SECRETJWT_ISSUERJWT_AUDIENCEREDIS_ADDRREDIS_PASSWORDREDIS_DBREDIS_EXPIRATIONREVOCATION_REDIS_ADDRREVOCATION_REDIS_PASSWORDREVOCATION_REDIS_DBUSE_MEMORY_STOREUSE_DEMOLISTEN_ADDRRATE_LIMIT_REQUESTSRATE_LIMIT_BURSTMAX_CLIENTS
The default development config intentionally includes a local seed, in-memory storage, and demo endpoints:
mode: "development"
listen_addr: ":8080"
blindvault_master_seed_hex: "..."
active_epoch: "2026-01"
use_memory_store: true
use_demo: trueProduction mode rejects inline seed values in the YAML config, forbids use_memory_store, forbids use_demo, requires jwt_issuer and jwt_audience, and enforces stricter secret length requirements.
Use use_memory_store: true and use_demo: true only for local testing. Production deployment should use Redis, protect the master seed and JWT secret with a secrets manager, and keep admin authorization separate from application user identity flows.