This application is an MVP that watches directories for files, encrypts them using HashiCorp Vault Transit Engine with envelope encryption, and stores the encrypted files in a separate folder. Works with both HCP Vault (cloud) and Vault Enterprise (self-hosted).
Warning
v1.0.0 Breaking Changes: This version introduces a new encrypted file format using the go-fileencrypt library. Files encrypted with previous versions are not compatible. See MIGRATION_GUIDE.md for upgrade instructions.
graph TD
subgraph Inputs
FW[File Watcher]
CLI[CLI]
end
FW -->|Service Mode| Q[FIFO Queue]
Q --> PROC[Processor]
CLI -->|CLI Mode| PROC
PROC --> VA[Vault Agent<br/>local listener]
VA --> VTE[Vault Transit<br/>Engine]
- File appears in source directory
- Watcher detects and queues file
- Processor generates data key via Vault
- File encrypted with AES-256-GCM using data key
- Data key encrypted with Vault Transit key
- Encrypted file and key saved to destination
- Original file archived or deleted
The diagram below shows both the continuous Service Mode path (through watcher + queue) and the one-off CLI Mode path (direct to processor). The processor handles both encryption and decryption via strategy pattern. Re-wrap and key version audit operations are shown separately as they only work with .key files.
flowchart TB
subgraph ServiceMode[Service Mode - watch]
SRC["Source Directory (plaintext for encryption or .enc+.key pairs for decryption)"]
SRC --> W[File Watcher fsnotify + startup scan]
W --> D[Stability Check size settle detection]
D --> Q[FIFO Queue retries + persistence]
end
subgraph CLIMode[CLI Mode - one-off]
CLI["CLI Command encrypt | decrypt"]
end
Q --> PROC
CLI --> PROC
PROC[Processor strategy: Encrypt or Decrypt]
PROC -->|Encryption| ENC_FLOW{Encryption Flow}
PROC -->|Decryption| DEC_FLOW{Decryption Flow}
ENC_FLOW -->|1. Request DEK| V1[(Vault Transit/datakey/plaintext)]
V1 -->|plaintext + ciphertext DEK| ENC_FLOW
ENC_FLOW -->|2. Encrypt with DEK| ENC_OUT["Output Files"]
ENC_OUT --> ENC_FILE["file.enc AES-256-GCM chunks"]
ENC_OUT --> KEY_FILE["file.key ciphertext DEK"]
ENC_OUT -->|optional| HASH_FILE["file.sha256 checksum"]
DEC_FLOW -->|1. Read ciphertext DEK| KEY_FILE
DEC_FLOW -->|2. Decrypt DEK| V2[(Vault Transit/decrypt)]
V2 -->|plaintext DEK| DEC_FLOW
DEC_FLOW -->|3. Decrypt file| PLAIN["file plaintext"]
ENC_FILE -.->|becomes source for decryption| SRC
KEY_FILE -.->|paired with .enc| SRC
PROC -->|Success| CLEANUP[Post-Process archive or delete originals]
subgraph KeyMaint[Key Maintenance - separate operations]
REWRAP[rewrap command rotate to newer key version]
AUDIT[key-versions command offline audit, no Vault]
end
REWRAP -->|read| KEY_FILE
REWRAP -->|call| V3[(Vault Transit/rewrap)]
V3 -->|update| KEY_FILE
AUDIT -->|read only| KEY_FILE
classDef vault fill:#502d7f,stroke:#333,stroke-width:2px,color:#fff;
class V1,V2,V3 vault;
classDef files fill:#0b5d8a,stroke:#0b5d8a,stroke-width:2px,color:#fff;
class ENC_FILE,KEY_FILE,HASH_FILE,PLAIN files;
classDef process fill:#176c3a,stroke:#0b4a26,stroke-width:2px,color:#fff;
class PROC,Q,W,D,CLEANUP process;
classDef decision fill:#d97706,stroke:#92400e,stroke-width:2px,color:#fff;
class ENC_FLOW,DEC_FLOW decision;
classDef cli fill:#aa5a00,stroke:#6d3a00,stroke-width:2px,color:#fff;
class CLI,REWRAP,AUDIT cli;
Key points:
- Service Mode always passes through the watcher and queue, ensuring ordering, retries, and persistence.
- CLI Mode bypasses watcher/queue for immediate single-file processing.
.keyfiles store only ciphertext DEKs; plaintext keys never hit disk.- Re-wrap updates
.keyfiles to newer Vault key versions without touching.encdata. - Key version auditing (
key-versions) runs offline (no Vault calls).
- File System Watching: Automatic detection of new files with
fsnotify - Envelope Encryption: Uses Vault Transit Engine for secure key management
- Bidirectional: Support for both encryption and decryption modes
- Progress Logging: Real-time progress updates every 20%
- Retry Logic: FIFO queue with exponential backoff
- Integrity Verification: Optional SHA256 checksum validation
- Hot Reload: Configuration changes without restart (SIGHUP on Unix)
- Enhanced Security (via
go-fileencrypt):- Constant-time memory zeroing (prevents compiler optimization)
- Memory locking (prevents key swapping to disk)
- Authenticated encryption with AES-256-GCM
- Secure, versioned file format with magic headers and salt
- Chunk size validation (prevents DOS attacks)
- Cross-Platform: Binaries for macOS, Windows, Linux (64-bit)
- Comprehensive Logging: Plaintext or JSON format with audit support
- CLI Mode: One-off encryption/decryption operations
- Configurable Chunk Size: Optimize encryption for file size (64KB-10MB)
- Key Re-wrapping: Rotate encrypted DEKs to newer Vault key versions without re-encrypting data
- Flexible Vault Authentication: Multiple auth methods supported - Token, AppRole, Kubernetes, JWT, TLS Certificate, or using Vault Agent
- Go 1.25.0+ (for building from source)
- Vault: One of the following:
- HCP Vault cluster with Transit Engine enabled, OR
- Vault Enterprise (or Community Edition) for local development
- Authentication: Choose one of:
- Vault Agent (recommended for production) - handles authentication automatically
- Direct authentication - Token, AppRole, Kubernetes, JWT, or TLS Certificate
- See Vault Authentication section for configuration details
git clone https://github.com/gitrgoliveira/vault-file-encryption.git
cd vault-file-encryption
make buildChoose your Vault deployment:
Option A: HCP Vault (Cloud)
# Follow the HCP Vault setup guide
# See: docs/guides/VAULT_SETUP_GUIDE.md
cd scripts/vault-setup
terraform init
terraform applyOption B: Vault Enterprise (Local Dev Mode)
# Follow the Vault Enterprise setup guide
# See: docs/guides/VAULT_ENTERPRISE_SETUP_GUIDE.md
cd scripts/vault-setup-enterprise
./01-start-vault-dev.sh # Terminal 1
./02-configure-vault.sh # Terminal 2For HCP Vault:
# Unix/Linux/macOS
vault agent -config=configs/vault-agent/vault-agent-hcp-token.hcl# Windows
vault agent -config=configs\vault-agent\vault-agent-hcp-token.hclFor Vault Enterprise:
# Unix/Linux/macOS
vault agent -config=configs/vault-agent/vault-agent-enterprise-dev.hcl# Windows
vault agent -config=configs\vault-agent\vault-agent-enterprise-dev.hclHCP Vault:
# Unix/Linux/macOS
./bin/file-encryptor encrypt \
-i myfile.txt \
-o myfile.txt.enc \
-c configs/examples/example.hcl# Windows
.\bin\file-encryptor-windows-amd64.exe encrypt `
-i myfile.txt `
-o myfile.txt.enc `
-c configs\examples\example.hclVault Enterprise:
# Unix/Linux/macOS
./bin/file-encryptor encrypt \
-i myfile.txt \
-o myfile.txt.enc \
-c configs/examples/example-enterprise.hcl# Windows
.\bin\file-encryptor-windows-amd64.exe encrypt `
-i myfile.txt `
-o myfile.txt.enc `
-c configs\examples\example-enterprise.hclThis creates:
myfile.txt.enc- Encrypted filemyfile.txt.key- Encrypted data key
# Unix/Linux/macOS
./bin/file-encryptor watch -c configs/examples/example.hcl# Windows (hot-reload not available - restart to reload config)
.\bin\file-encryptor-windows-amd64.exe watch -c configs\examples\example.hclThe service will:
- Scan and process any pre-existing files in configured directories on startup
- Monitor configured directories for new files (using fsnotify)
- Queue files for processing with retry logic
- Encrypt/decrypt files automatically
- Save queue state on shutdown
Download the latest release for your platform from the Releases page:
- Windows (64-bit):
file-encryptor-windows-amd64.exe - macOS (64-bit):
file-encryptor-darwin-amd64 - Linux (64-bit):
file-encryptor-linux-amd64
Prerequisites:
- Go 1.25.0 or later
- Make (Unix/Linux/macOS) or use
go builddirectly on Windows
# Unix/Linux/macOS
git clone https://github.com/gitrgoliveira/vault-file-encryption.git
cd vault-file-encryption
make build
# Build for all platforms
make build-all# Windows (using Git Bash or WSL for Make)
git clone https://github.com/gitrgoliveira/vault-file-encryption.git
cd vault-file-encryption
make build-windows
# Or build directly with go
go build -o bin\file-encryptor.exe cmd/file-encryptor/main.goSee configs/examples/example.hcl for a complete configuration example.
vault {
agent_address = "http://127.0.0.1:8200"
transit_mount = "transit"
key_name = "file-encryption-key"
}
encryption {
source_dir = "/data/source"
dest_dir = "/data/encrypted"
source_file_behavior = "archive"
chunk_size = "2MB" # Optional: 64KB-10MB, default 1MB
}
queue {
state_path = "/var/lib/file-encryptor/queue-state.json"
}
logging {
level = "info"
output = "stdout"
}The application supports multiple Vault authentication methods. Choose the approach that best fits your deployment:
- Vault Agent (recommended) - Automatic authentication, no config needed
- Direct Authentication - Token, AppRole, Kubernetes, JWT, or TLS Certificate
Vault Agent handles authentication automatically. Simply point to the agent's listener:
vault {
agent_address = "http://127.0.0.1:8200" # Vault Agent listener
transit_mount = "transit"
key_name = "file-encryption-key"
# No auth block needed
}For environments without Vault Agent, configure one of the following methods:
Use case: Development and testing only
Configuration:
vault {
agent_address = "https://vault.example.com:8200"
transit_mount = "transit"
key_name = "file-encryption-key"
auth {
method = "token"
token {
token = "hvs.CAES..." # Or set VAULT_TOKEN env var
}
}
}Environment variables:
VAULT_TOKEN- Vault tokenVAULT_NAMESPACE- Vault namespace (optional)
Use case: Production applications and services
Configuration:
vault {
agent_address = "https://vault.example.com:8200"
transit_mount = "transit"
key_name = "file-encryption-key"
auth {
method = "approle"
approle {
role_id = "your-role-id" # Or set VAULT_ROLE_ID env var
secret_id = "your-secret-id" # Or set VAULT_SECRET_ID env var
mount_path = "auth/approle" # Optional, defaults to "auth/approle"
}
}
}Environment variables:
VAULT_ROLE_ID- AppRole role IDVAULT_SECRET_ID- AppRole secret ID
Use case: Kubernetes deployments
Configuration:
vault {
agent_address = "https://vault.example.com:8200"
transit_mount = "transit"
key_name = "file-encryption-key"
auth {
method = "kubernetes"
kubernetes {
role = "file-encryptor"
token_path = "/var/run/secrets/kubernetes.io/serviceaccount/token" # Optional
mount_path = "auth/kubernetes" # Optional
}
}
}Environment variables: None (uses service account token file)
Use case: CI/CD pipelines, OIDC providers
Configuration:
vault {
agent_address = "https://vault.example.com:8200"
transit_mount = "transit"
key_name = "file-encryption-key"
auth {
method = "jwt"
jwt {
role = "file-encryptor"
path = "/path/to/jwt/token"
mount_path = "auth/jwt" # Optional
}
}
}Environment variables: None (uses JWT file specified in config)
Use case: Mutual TLS environments
Configuration:
vault {
agent_address = "https://vault.example.com:8200"
transit_mount = "transit"
key_name = "file-encryption-key"
auth {
method = "cert"
cert {
client_cert = "/path/to/client.crt"
client_key = "/path/to/client.key"
mount_path = "auth/cert" # Optional
name = "file-encryptor" # Optional, defaults to cert common name
}
}
}Environment variables: None (uses certificate files specified in config)
Security:
- Use environment variables for sensitive credentials instead of hardcoding in config files
- Rotate credentials regularly
- Use least-privilege Vault policies for each authentication method
Production recommendations:
- Preferred: Vault Agent or platform identity authentication
- Avoid: Token authentication (development/testing only)
Configuration rules:
- Only one authentication method can be configured at a time
- Environment variables override configuration file values
Example with environment variables:
# Token authentication
export VAULT_TOKEN="hvs.CAES..."
./bin/file-encryptor watch -c config.hcl
# AppRole authentication
export VAULT_ROLE_ID="your-role-id"
export VAULT_SECRET_ID="your-secret-id"
./bin/file-encryptor encrypt -i file.txt -o file.enc -c config.hclControl memory usage and performance by configuring the encryption chunk size:
In Configuration File (config.hcl):
encryption {
# ... other settings ...
chunk_size = "2MB" # Options: 64KB-10MB, default 1MB
}CLI Override:
./bin/file-encryptor encrypt -i file.txt -o file.txt.enc --chunk-size 512KBSupported Formats:
- Standard:
"64KB","512KB","1MB","2MB","10MB" - Decimal:
"1.5MB","0.5GB" - With spaces:
"1 MB","512 KB" - Case insensitive:
"1mb","1MB","1Mb" - Plain numbers:
"1024"(bytes)
Size Recommendations:
- Small files (<1MB):
256KB- Lower memory usage - Medium files (1-100MB):
512KB-2MB- Balanced (default: 1MB) - Large files (100MB-1GB):
2MB-4MB- Better throughput - Very large files (>1GB):
4MB-8MB- Maximum performance
Note: Service mode processes one file at a time, so choose chunk size based on your typical file size, not concurrent operations.
See docs/guides/CHUNK_SIZE_TUNING.md for detailed tuning guide with benchmarking and troubleshooting.
The application supports configuration hot-reload without restart on Unix systems (Linux, macOS, BSD).
Unix/Linux/macOS:
# Find the process ID
ps aux | grep file-encryptor
# Send SIGHUP signal
kill -HUP <pid>
# or
pkill -SIGHUP file-encryptorWindows:
Note: Hot-reload via signals is not supported on Windows due to OS limitations. To reload configuration, you must restart the service/application.
To reload configuration on Windows:
- Stop the application (Ctrl+C or Stop-Service)
- Update the configuration file
- Restart the application
For Production: Use a Windows Service wrapper like NSSM or WinSW that can be easily stopped/started via service commands.
file-encryptor [command] [flags]
Commands:
watch Run as a service watching directories for files
encrypt Encrypt a single file
decrypt Decrypt a single file
rewrap Re-wrap encrypted data keys to newer versions
key-versions Display encryption key version statistics
help Help about any command
Global Flags:
-c, --config string Configuration file path (default "config.hcl")
-l, --log-level string Log level (debug, info, error) (default "info")
-o, --log-output string Log output (stdout, stderr, or file path) (default "stdout")
-h, --help Help for file-encryptor
-v, --version Version information
Start file watcher:
./bin/file-encryptor watch -c config.hclStart with debug logging:
./bin/file-encryptor watch -c config.hcl --log-level debugLog to file:
./bin/file-encryptor watch -c config.hcl --log-output /var/log/file-encryptor.logEncrypt a file:
./bin/file-encryptor encrypt -i sensitive.pdf -o sensitive.pdf.encEncrypt with custom key file:
./bin/file-encryptor encrypt -i data.txt -o data.txt.enc -k my-key.keyEncrypt with checksum:
./bin/file-encryptor encrypt -i file.dat -o file.dat.enc --checksumDecrypt a file:
./bin/file-encryptor decrypt -i file.dat.enc -k file.dat.key -o decrypted-file.datDecrypt with checksum verification:
./bin/file-encryptor decrypt -i file.dat.enc -k file.dat.key -o decrypted-file.dat --verify-checksumRe-wrap encryption keys to newer version:
# Re-wrap all keys in a directory to minimum version 2
./bin/file-encryptor rewrap --dir /path/to/keys --recursive --min-version 2
# Dry-run to preview what would be re-wrapped
./bin/file-encryptor rewrap --dir /path/to/keys --dry-run --min-version 2
# Export results as JSON
./bin/file-encryptor rewrap --dir /path/to/keys --min-version 2 --format jsonDisplay key version statistics:
# Show version distribution for all keys in a directory (no config needed)
./bin/file-encryptor key-versions --dir /path/to/keys --recursive
# Output as JSON for analysis
./bin/file-encryptor key-versions --dir /path/to/keys --format json
# Output as CSV for spreadsheets
./bin/file-encryptor key-versions --dir /path/to/keys --format csvNote: The key-versions command works offline and does not require Vault configuration.
For detailed rewrap documentation, see REWRAP_GUIDE.md.
For detailed architecture documentation, see ARCHITECTURE.md.
The application requires specific Vault Transit Engine capabilities depending on the operation mode. Three separate policies are recommended for least-privilege access:
Required for encrypting files (generating and encrypting data keys):
# Policy name: file-encryptor-encrypt
path "transit/datakey/plaintext/file-encryption-key" {
capabilities = ["update"]
}Capabilities:
datakey/plaintext/*- Generate a new data encryption key (DEK) in both plaintext and ciphertext forms
Used by:
- Service mode encryption operations
- CLI
encryptcommand
Required for decrypting files (decrypting data keys):
# Policy name: file-encryptor-decrypt
path "transit/decrypt/file-encryption-key" {
capabilities = ["update"]
}Capabilities:
decrypt/*- Decrypt the ciphertext DEK to obtain the plaintext DEK
Used by:
- Service mode decryption operations
- CLI
decryptcommand
Required for key rotation (re-wrapping encrypted DEKs to newer key versions):
# Policy name: file-encryptor-rewrap
path "transit/rewrap/file-encryption-key" {
capabilities = ["update"]
}Capabilities:
rewrap/*- Re-encrypt an existing ciphertext DEK with the latest key version without exposing plaintext
Used by:
- CLI
rewrapcommand
For development or testing environments, you can use a combined policy with all capabilities:
# Policy name: file-encryptor-combined (NOT recommended for production)
path "transit/datakey/plaintext/file-encryption-key" {
capabilities = ["update"]
}
path "transit/decrypt/file-encryption-key" {
capabilities = ["update"]
}
path "transit/rewrap/file-encryption-key" {
capabilities = ["update"]
}Production Recommendation:
- Use separate policies for each operation type
- Assign policies based on the specific role (encryption-only systems, decryption-only systems, key rotation operators)
- Apply the principle of least privilege
HCP Vault (Token Auth):
# Create policies
vault policy write file-encryptor-encrypt encrypt-policy.hcl
vault policy write file-encryptor-decrypt decrypt-policy.hcl
vault policy write file-encryptor-rewrap rewrap-policy.hcl
# Generate tokens with specific policies
vault token create -policy=file-encryptor-encrypt -period=24h
vault token create -policy=file-encryptor-decrypt -period=24h
vault token create -policy=file-encryptor-rewrap -period=1hVault Enterprise (Certificate Auth):
# Map certificate common names to policies
vault write auth/cert/certs/file-encryptor-encrypt \
certificate=@client-encrypt.crt \
policies=file-encryptor-encrypt
vault write auth/cert/certs/file-encryptor-decrypt \
certificate=@client-decrypt.crt \
policies=file-encryptor-decrypt
vault write auth/cert/certs/file-encryptor-rewrap \
certificate=@client-rewrap.crt \
policies=file-encryptor-rewrapNote: The key-versions command does not require any Vault access as it operates offline on local .key files.
For complete Vault setup instructions including policy configuration, see:
- Architecture - System architecture and design
- CLI Mode Guide - CLI usage (Unix/Linux/macOS)
- CLI Mode Guide (Windows) - CLI usage for Windows
- Rewrap Guide - Key re-wrapping documentation
- Chunk Size Tuning - Performance optimization guide
Unix/Linux/macOS:
- Vault Setup Guide (HCP) - HCP Vault setup instructions
- Vault Enterprise Setup - Vault Enterprise setup
Windows:
- Vault Setup Guide (HCP) - Windows - HCP Vault setup for Windows
Note: Vault Enterprise setup guide for Windows follows the same patterns as the Unix guide with PowerShell commands instead of bash. See the Unix guide and adapt commands for Windows.
The application fully supports Windows with the following considerations:
Installation:
# Download the Windows binary from releases
# Extract to C:\Program Files\file-encryptor\
# Add to PATH for easy access
$env:PATH += ";C:\Program Files\file-encryptor"Fully Supported:
- CLI mode (encrypt/decrypt single files)
- Service mode (watch directories)
- File system watching via fsnotify
- Graceful shutdown (Ctrl+C)
- All crypto operations
- Key re-wrapping and version auditing
Important Differences:
- Hot-reload not available: Configuration changes require service restart
- Signal handling: Only Ctrl+C and SIGTERM work (no SIGHUP support)
- Path separators: Use forward slashes (
/) or double backslashes (\\) in config files - File permissions: Use
icaclsinstead ofchmodfor setting permissions
Running as Windows Service:
# Install NSSM (run as Administrator)
choco install nssm
# Create service
nssm install FileEncryptor "C:\Program Files\file-encryptor\file-encryptor.exe"
nssm set FileEncryptor AppParameters "watch -c C:\ProgramData\file-encryptor\config.hcl"
nssm set FileEncryptor Start SERVICE_AUTO_START
# Start service
Start-Service FileEncryptorConfiguration Example (Windows paths):
encryption {
source_dir = "C:/data/source" # Forward slashes recommended
dest_dir = "C:/data/encrypted"
}
queue {
state_path = "C:/ProgramData/file-encryptor/queue-state.json"
}
logging {
output = "C:/ProgramData/file-encryptor/logs/app.log"
}PowerShell Examples:
# CLI mode - works perfectly
.\file-encryptor.exe encrypt -i data.txt -o data.enc
.\file-encryptor.exe decrypt -i data.enc -k data.key -o data.txt
# Service mode
.\file-encryptor.exe watch -c config.hcl
# Press Ctrl+C to stop
# To reload config: Stop and restart the service
Stop-Service FileEncryptor
Start-Service FileEncryptorWindows-Specific Guides:
All features fully supported including hot-reload via SIGHUP signal.
Installation:
# Download binary from releases
# Make executable
chmod +x file-encryptor-linux-amd64
sudo mv file-encryptor-linux-amd64 /usr/local/bin/file-encryptor
# Or build from source
make buildRunning as systemd service (Linux):
sudo cp file-encryptor.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable file-encryptor
sudo systemctl start file-encryptorHot-reload configuration:
# Send SIGHUP to reload config without restart
pkill -SIGHUP file-encryptor- Envelope Encryption: Data keys never stored unencrypted
- AES-256-GCM: Authenticated encryption with 256-bit keys
- Unique Nonces: Each chunk uses base nonce + counter (prevents nonce reuse)
- File Metadata Authentication: File size authenticated via GCM additional data
- Nonce Overflow Protection: Maximum 2^32 chunks per file (~4 petabytes with 1MB chunks)
- Constant-Time Zeroing: Uses
crypto/subtleto prevent compiler optimization - Memory Locking: Plaintext DEKs locked in RAM (mlock) to prevent swapping to disk
- Immediate Cleanup: Keys zeroed from memory immediately after use
- Secure Patterns: Defer-based cleanup ensures keys are always zeroed
- Chunk Size Validation: Rejects chunks larger than 10MB during decryption
- Resource Protection: Prevents memory exhaustion from malformed files
- Vault Agent: Can use multiple authentication methods, keeping credentials rotated, and handles several types of secrets
- TLS: All Vault communication over HTTPS
- Audit Logging: All operations logged with security events
- No Primary Key Exposure: Primary key never leaves Vault
Encrypted files include:
- 12-byte master nonce (unique per file)
- 8-byte authenticated file size
- Per-chunk encryption with incremented nonces
- GCM authentication tags (128-bit per chunk)
For detailed security architecture, see docs/ARCHITECTURE.md.
For issues and questions:
- GitHub Issues: Report an issue
- Documentation: See the
docs/directory in this repository - Discussions: GitHub Discussions
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Copyright (c) 2025 Ricardo Oliveira
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
See LICENSE for full details.
This project includes comprehensive validation tools to ensure code quality and security:
# Run all validation checks
make validate-all
# Individual checks
make fmt-check # Check code formatting
make vet # Run go vet
make staticcheck # Run static analysis
make lint # Run golangci-lint
make gosec # Run security scanner
make test # Run all tests
# Build with validation
make build-validatedSee .github/workflows/build-and-test.yml for the complete CI/CD pipeline.