Skip to content

Secrets Vault Sync

Build Status Integration Tests Coverage Latest Release Go Version License

A versatile, multi-vault secret synchronization daemon with OAuth 2.0 support for seamless integration between Vaultwarden, Azure Key Vault, HashiCorp Vault, AWS Secrets Manager, and custom vault backends.

Features

Multi-Vault Support

  • Vaultwarden
  • HashiCorp Vault
  • Azure Key Vault
  • AWS Secrets Manager
  • Generic HTTP-based vaults

🔐 Flexible Authentication

  • OAuth 2.0 with Vaultwarden support
  • Bearer Token
  • Basic Authentication
  • API Key
  • Custom Headers

🔄 Powerful Sync

  • Unidirectional and bidirectional sync
  • Concurrent processing (configurable workers)
  • Scheduled execution (cron format)
  • Configurable retry policies
  • Pattern-based filtering (include/exclude)

📊 Monitoring & Observability

  • HTTP REST API for operations
  • Prometheus metrics export
  • Structured JSON logging
  • Health check endpoints

🏗️ Production Ready

  • SQLite state database
  • Transaction support
  • Error recovery and retry logic
  • Docker & Kubernetes ready

Common Use Cases

Backup & Replication

Synchronize secrets from your production vault to a backup vault for disaster recovery.

syncs:
  - id: prod_to_backup
    source: production
    targets:
      - backup
    sync_type: unidirectional
    schedule: "0 */4 * * *"  # Every 4 hours

Multi-Cloud Deployment

Keep secrets in sync across different cloud providers.

syncs:
  - id: aws_to_azure
    source: aws-vault
    targets:
      - azure-vault
    sync_type: bidirectional

Development Environment Sync

Maintain synchronized secrets across dev, staging, and production.

syncs:
  - id: to_development
    source: production
    targets:
      - development
      - staging
    filter:
      patterns:
        - "non-prod-*"
        - "shared-*"

Architecture Overview

graph TB
    subgraph daemon["AKV Sync Daemon"]
        direction TB

        subgraph vaults["Vaults"]
            vw["Vaultwarden"]
            akv["Azure KV"]
            aws["AWS SM"]
            hc["HashiCorp"]
        end

        subgraph backends["Backends"]
            http["Generic HTTP"]
            vault["Vault"]
            awsb["AWS"]
            azure["Azure"]
        end

        vaults -->|OAuth2| backends

        engine["Sync Engine<br/>• Scheduling<br/>• Filtering<br/>• Retries"]

        vaults --> engine
        backends --> engine

        db[("State Database<br/>(SQLite)")]
        engine --> db

        api["REST API & Monitoring<br/>• Sync Control & Status<br/>• Prometheus Metrics<br/>• Health Checks"]
    end

    style daemon fill:none,stroke:#4a9eff,stroke-width:3px
    style engine fill:none,stroke:#4a9eff,stroke-width:2px
    style vaults fill:none,stroke:#ff6b35,stroke-width:2px
    style backends fill:none,stroke:#a64dff,stroke-width:2px
    style api fill:none,stroke:#00cc66,stroke-width:2px

Getting Started

Installation

docker run -d \
  --name akv-sync \
  -v $(pwd)/config.yaml:/etc/sync/config.yaml:ro \
  -v $(pwd)/data:/app/data \
  -p 8080:8080 \
  -p 9090:9090 \
  ghcr.io/pacorreia/vaults-syncer:latest
# Download latest release
wget https://github.com/pacorreia/vaults-syncer/releases/download/v1.0.0/sync-daemon-linux-amd64
chmod +x sync-daemon-linux-amd64

# Run
./sync-daemon-linux-amd64 -config config.yaml
git clone https://github.com/pacorreia/vaults-syncer
cd vaults-syncer
go build -o sync-daemon .
./sync-daemon -config config.yaml

Minimal Configuration

Create config.yaml:

vaults:
  - id: source
    name: Source Vault
    type: vaultwarden
    endpoint: https://vault.example.com/api/ciphers
    auth:
      method: oauth2
      oauth:
        token_endpoint: https://vault.example.com/identity/connect/token
        client_id: your-client-id
        client_secret: your-client-secret
        scope: api

  - id: target
    name: Target Vault
    type: vaultwarden
    endpoint: https://backup.example.com/api/ciphers
    auth:
      method: bearer
      headers:
        token: your-bearer-token

syncs:
  - id: backup-sync
    source: source
    targets:
      - target
    sync_type: unidirectional
    schedule: "0 */4 * * *"  # Every 4 hours

server:
  port: 8080

logging:
  level: info
  format: json

Then run:

./sync-daemon -config config.yaml

Check status:

curl http://localhost:8080/health

Development

This project is written in Go 1.22 with a modular architecture:

  • Zero backward compatibility compromises - removed all legacy code paths after generalization
  • Interface-driven design - pluggable vault backends
  • Production-ready - comprehensive error handling and retry logic
  • Well-tested - unit tests, integration tests, and real vault testing

Build

# Build with default version (dev)
go build -o sync-daemon .

# Build with complete version information
VERSION=$(git describe --tags --always --dirty)
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
GIT_COMMIT=$(git rev-parse HEAD)

go build \
  -ldflags "-X main.Version=${VERSION} -X main.BuildDate=${BUILD_DATE} -X main.GitCommit=${GIT_COMMIT}" \
  -o sync-daemon .

# Check version
./sync-daemon --version

Test

# Unit tests
go test ./...

# Integration tests
./e2e/test-integration.sh

Support Us

If you find this project useful, please consider:

  • ⭐ Starring the repository
  • 🐛 Reporting issues
  • 💡 Contributing features
  • 📚 Improving documentation

License

MIT License - See LICENSE for details.

Contributing

We welcome contributions! Visit CONTRIBUTING for guidelines.