diff --git a/website/src/app/docs/migration/page.tsx b/website/src/app/docs/migration/page.tsx new file mode 100644 index 0000000..799af4c --- /dev/null +++ b/website/src/app/docs/migration/page.tsx @@ -0,0 +1,251 @@ +import { CodeBlock } from "@/components/CodeBlock"; +import { Section, PageHeader } from "@/components/DocsComponents"; + +export const metadata = { + title: "Migration Guides - xenvsync", + description: "Step-by-step guides to migrate from dotenv-vault, sops, and git-crypt to xenvsync.", + openGraph: { + title: "Migration Guides - xenvsync", + description: "Migrate from dotenv-vault, sops, or git-crypt to xenvsync with step-by-step instructions.", + url: "https://xenvsync.softexforge.io/docs/migration", + }, + alternates: { canonical: "https://xenvsync.softexforge.io/docs/migration" }, +}; + +export default function Migration() { + return ( +
+ + + {/* dotenv-vault */} +
+

+ dotenv-vault uses a cloud service to manage encrypted vaults. xenvsync does everything locally with no cloud dependency. +

+ +

1. Export your secrets

+

+ If you have a .env.vault from dotenv-vault, you need to decrypt it first using your DOTENV_KEY: +

+ +{`# Decrypt your dotenv-vault secrets to a plain .env file +# (use your dotenv-vault tooling or dashboard to export) +npx dotenv-vault@latest pull + +# Verify your .env has all expected variables +cat .env`} + + +

2. Set up xenvsync

+ +{`# Initialize xenvsync (generates encryption key) +xenvsync init + +# Encrypt your .env +xenvsync push + +# Verify the vault +xenvsync verify`} + + +

3. Clean up dotenv-vault

+ +{`# Remove dotenv-vault artifacts +rm -f .env.vault # (the old dotenv-vault format, now replaced by xenvsync's) +rm -f .env.keys + +# Remove dotenv-vault from dependencies +npm uninstall dotenv-vault + +# Commit the new vault +git add .env.vault .gitignore +git commit -m "Migrate from dotenv-vault to xenvsync"`} + + +

4. Verify

+ +{`# Delete .env and restore from vault +rm .env +xenvsync pull +cat .env # should match your original secrets + +# Test in-memory injection +xenvsync run -- env | grep YOUR_KEY`} + + +
+ Key differences: xenvsync vaults are not compatible with dotenv-vault vaults. The .env.vault file format is different. + xenvsync uses AES-256-GCM with a local key, while dotenv-vault uses a cloud-managed key. +
+
+ + {/* sops */} +
+

+ sops encrypts individual values within YAML/JSON/ENV files. xenvsync encrypts the entire .env file as a single unit. +

+ +

1. Export your secrets

+ +{`# Decrypt your sops-encrypted file to plain .env +sops -d secrets.enc.env > .env + +# Or from YAML/JSON: +sops -d secrets.yaml | yq -r 'to_entries[] | "\\(.key)=\\(.value)"' > .env`} + + +

2. Set up xenvsync

+ +{`# Initialize xenvsync +xenvsync init + +# Encrypt your .env +xenvsync push + +# Verify +xenvsync diff # should show no differences`} + + +

3. Clean up sops

+ +{`# Remove sops-encrypted files +rm -f secrets.enc.env secrets.yaml +rm -f .sops.yaml + +# Update .gitignore if needed +# (xenvsync init already added .xenvsync.key and .env) + +# Commit +git add .env.vault .gitignore +git rm secrets.enc.env .sops.yaml # if tracked +git commit -m "Migrate from sops to xenvsync"`} + + +

4. Verify

+ +{`rm .env +xenvsync pull +xenvsync verify`} + + +
+ Key differences: sops supports KMS, PGP, and age keys with per-value encryption. xenvsync uses a single AES-256-GCM key (or X25519 team keys) and encrypts the entire file. + If you need per-value encryption or cloud KMS integration, sops may be a better fit. +
+
+ + {/* git-crypt */} +
+

+ git-crypt transparently encrypts files in a Git repo. xenvsync uses explicit push/pull commands and encrypts only .env files. +

+ +

1. Export your secrets

+ +{`# Ensure your repo is unlocked (files are decrypted in working tree) +git-crypt unlock + +# Copy your .env (it's already in plaintext when unlocked) +cp .env .env.backup + +# Verify contents +cat .env`} + + +

2. Remove git-crypt

+ +{`# Lock first to see what was encrypted +git-crypt lock + +# Remove git-crypt configuration +rm -rf .git-crypt/ +rm -f .gitattributes # or remove git-crypt filter lines + +# Unlock to restore plaintext +git-crypt unlock`} + + +

3. Set up xenvsync

+ +{`# Initialize xenvsync +xenvsync init + +# Restore .env if needed +cp .env.backup .env + +# Encrypt +xenvsync push + +# Verify +xenvsync verify`} + + +

4. Commit the migration

+ +{`git add .env.vault .gitignore +git commit -m "Migrate from git-crypt to xenvsync" + +# Clean up backup +rm .env.backup`} + + +
+ Key differences: git-crypt encrypts transparently on git operations and works with any file type. + xenvsync is focused specifically on .env files and adds features like in-memory injection (run), multi-environment support, and vault diff/status. +
+
+ + {/* Team migration */} +
+

+ If your team uses xenvsync's V2 (team) mode, follow these additional steps after any migration: +

+ +{`# Each team member generates their keypair (once) +xenvsync keygen + +# Share public keys and add to roster +xenvsync team add alice +xenvsync team add bob + +# Re-push to create V2 vault with per-member encryption +xenvsync push + +# Commit the roster and vault +git add .xenvsync-team.json .env.vault +git commit -m "Enable V2 team vault"`} + +
+ + {/* Comparison */} +
+
+ + + + + + + + + + + + + + + + + + + + +
Featurexenvsyncdotenv-vaultsopsgit-crypt
No cloud requiredYesNoYesYes
In-memory injectionYesNoNoNo
Multi-environmentYesYesManualNo
Team sharingX25519CloudKMS/PGPGPG
Key rotationYesCloudManualNo
Diff / audit logYesNoPartialNo
Single binaryYesNoYesNo
Passphrase protectionYesNoNoNo
+
+
+
+ ); +} diff --git a/website/src/components/Search.tsx b/website/src/components/Search.tsx index 1a71abe..48c84ca 100644 --- a/website/src/components/Search.tsx +++ b/website/src/components/Search.tsx @@ -279,6 +279,44 @@ const searchIndex: SearchEntry[] = [ "version prints version commit hash and build date. Build info is injected at compile time via ldflags.", }, + // Migration Guides + { + href: "/docs/migration", + title: "Migration Guides", + section: "Docs", + heading: "From dotenv-vault", + keywords: ["migration", "dotenv-vault", "switch", "migrate", "cloud", "DOTENV_KEY"], + content: + "Step-by-step guide to migrate from dotenv-vault to xenvsync. Export secrets from dotenv-vault, set up xenvsync, and verify the migration. No cloud dependency needed.", + }, + { + href: "/docs/migration", + title: "Migration Guides", + section: "Docs", + heading: "From sops", + keywords: ["migration", "sops", "switch", "migrate", "kms", "pgp", "age", "yaml"], + content: + "Step-by-step guide to migrate from sops to xenvsync. Decrypt sops files, set up xenvsync encryption, and clean up sops configuration.", + }, + { + href: "/docs/migration", + title: "Migration Guides", + section: "Docs", + heading: "From git-crypt", + keywords: ["migration", "git-crypt", "switch", "migrate", "gpg", "transparent"], + content: + "Step-by-step guide to migrate from git-crypt to xenvsync. Export decrypted files, remove git-crypt configuration, and set up xenvsync.", + }, + { + href: "/docs/migration", + title: "Migration Guides", + section: "Docs", + heading: "Feature Comparison", + keywords: ["comparison", "compare", "vs", "alternative", "dotenv-vault", "sops", "git-crypt"], + content: + "Feature comparison table between xenvsync, dotenv-vault, sops, and git-crypt. Covers cloud dependency, in-memory injection, multi-environment, team sharing, key rotation, and more.", + }, + // Security { href: "/docs/security", diff --git a/website/src/components/Sidebar.tsx b/website/src/components/Sidebar.tsx index 351516e..2d175ac 100644 --- a/website/src/components/Sidebar.tsx +++ b/website/src/components/Sidebar.tsx @@ -13,11 +13,13 @@ import { Menu, X, ChevronRight, + ArrowRightLeft, } from "lucide-react"; export const docPages = [ { href: "/docs/getting-started", label: "Getting Started", icon: BookOpen, section: "Learn" }, { href: "/docs/installation", label: "Installation", icon: Download, section: "Learn" }, + { href: "/docs/migration", label: "Migration Guides", icon: ArrowRightLeft, section: "Learn" }, { href: "/docs/commands", label: "Commands", icon: Terminal, section: "Reference" }, { href: "/docs/security", label: "Security Model", icon: Shield, section: "Reference" }, { href: "/roadmap", label: "Roadmap", icon: Map, section: "Project" },