Step 20: Encryption polish — e2e test, docs, flake.
E2e encryption test: full lifecycle covering init, add encrypted + plaintext, checkpoint, modify, status (no DEK needed), re-checkpoint, restore, verify, re-open with unlock, diff, slot management, passphrase change, old passphrase rejection. Docs updated: - ARCHITECTURE.md: package structure (encrypt.go, encrypt_fido2.go, encrypt CLI), Garden struct (dek field, encryption methods), auth.go descriptions updated for JWT - README.md: encryption commands table, encryption section with usage - CLAUDE.md: added jwt/argon2/chacha20 deps, encryption file mentions flake.nix: vendorHash updated for new deps. Phase 3 complete. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -576,6 +576,7 @@ the same server? This requires a proper trust/key-authority design.
|
||||
sgard/
|
||||
cmd/sgard/ # CLI entry point — one file per command
|
||||
main.go # cobra root command, --repo/--remote/--ssh-key flags
|
||||
encrypt.go # sgard encrypt init/add-fido2/remove-slot/list-slots/change-passphrase
|
||||
push.go pull.go prune.go mirror.go
|
||||
init.go add.go remove.go checkpoint.go
|
||||
restore.go status.go verify.go list.go diff.go version.go
|
||||
@@ -585,6 +586,8 @@ sgard/
|
||||
|
||||
garden/ # Core business logic — one file per operation
|
||||
garden.go # Garden struct, Init, Open, Add, Checkpoint, Status, accessors
|
||||
encrypt.go # EncryptInit, UnlockDEK, encrypt/decrypt blobs, slot management
|
||||
encrypt_fido2.go # FIDO2Device interface, AddFIDO2Slot, unlock resolution
|
||||
restore.go mirror.go prune.go remove.go verify.go list.go diff.go
|
||||
hasher.go # SHA-256 file hashing
|
||||
|
||||
@@ -596,12 +599,12 @@ sgard/
|
||||
|
||||
server/ # gRPC server implementation
|
||||
server.go # GardenSync RPC handlers with RWMutex
|
||||
auth.go # SSH key auth interceptor
|
||||
convert.go # proto ↔ manifest type conversion
|
||||
auth.go # JWT token + SSH key auth interceptor, Authenticate RPC
|
||||
convert.go # proto ↔ manifest type conversion (incl. encryption)
|
||||
|
||||
client/ # gRPC client library
|
||||
client.go # Push, Pull, Prune methods
|
||||
auth.go # SSHCredentials (PerRPCCredentials), LoadSigner
|
||||
client.go # Push, Pull, Prune with auto-auth retry
|
||||
auth.go # TokenCredentials, LoadSigner, Authenticate, token caching
|
||||
|
||||
sgardpb/ # Generated protobuf + gRPC Go code
|
||||
proto/sgard/v1/ # Proto source definitions
|
||||
@@ -622,10 +625,11 @@ type Garden struct {
|
||||
root string
|
||||
manifestPath string
|
||||
clock clockwork.Clock
|
||||
dek []byte // unlocked data encryption key
|
||||
}
|
||||
|
||||
// Local operations
|
||||
func (g *Garden) Add(paths []string) error
|
||||
func (g *Garden) Add(paths []string, encrypt ...bool) error
|
||||
func (g *Garden) Remove(paths []string) error
|
||||
func (g *Garden) Checkpoint(message string) error
|
||||
func (g *Garden) Restore(paths []string, force bool, confirm func(string) bool) error
|
||||
@@ -637,6 +641,14 @@ func (g *Garden) Prune() (int, error)
|
||||
func (g *Garden) MirrorUp(paths []string) error
|
||||
func (g *Garden) MirrorDown(paths []string, force bool, confirm func(string) bool) error
|
||||
|
||||
// Encryption
|
||||
func (g *Garden) EncryptInit(passphrase string) error
|
||||
func (g *Garden) UnlockDEK(prompt func() (string, error), fido2 ...FIDO2Device) error
|
||||
func (g *Garden) AddFIDO2Slot(device FIDO2Device, label string) error
|
||||
func (g *Garden) RemoveSlot(name string) error
|
||||
func (g *Garden) ListSlots() map[string]string
|
||||
func (g *Garden) ChangePassphrase(newPassphrase string) error
|
||||
|
||||
// Accessors (used by server package)
|
||||
func (g *Garden) GetManifest() *manifest.Manifest
|
||||
func (g *Garden) BlobExists(hash string) bool
|
||||
|
||||
Reference in New Issue
Block a user