@@ -106,7 +106,113 @@ Backups are stored as GitHub Actions artifacts:
1061062 . Click on a completed workflow run
1071073 . Download the artifact (valid for 30 days)
108108
109- SQL files are also committed to the repository for version control.
109+ ### 🔒 Encrypted Backups (Public Repositories)
110+
111+ ** For security** , backups are encrypted with AES256 before being uploaded as artifacts. This protects sensitive user data in public repositories.
112+
113+ #### Downloading Encrypted Backups
114+
115+ 1 . Go to ** Actions** tab in your repository
116+ 2 . Click on a completed workflow run
117+ 3 . Scroll to ** Artifacts** section
118+ 4 . Download ` supabase-backup-encrypted-XXX `
119+ 5 . You'll get a file named ` supabase_snapshot.tar.gz.gpg `
120+
121+ #### Decrypting Backups
122+
123+ ** Prerequisites** : Install GPG (GnuPG)
124+ ``` bash
125+ # macOS
126+ brew install gnupg
127+
128+ # Ubuntu/Debian
129+ sudo apt-get install gnupg
130+
131+ # Windows
132+ # Download from https://www.gnupg.org/download/
133+ ```
134+
135+ ** Decryption Steps** :
136+
137+ ``` bash
138+ # 1. Navigate to the directory with the encrypted file
139+ cd ~ /Downloads
140+
141+ # 2. Decrypt the backup (will prompt for password)
142+ gpg --decrypt supabase_snapshot.tar.gz.gpg > supabase_snapshot.tar.gz
143+
144+ # Enter the BACKUP_ENCRYPTION_KEY when prompted
145+
146+ # 3. Extract the archive
147+ tar -xzf supabase_snapshot.tar.gz
148+
149+ # 4. You now have the supabase_snapshot/ directory with all backup files
150+ cd supabase_snapshot/
151+ ls -lh
152+ ```
153+
154+ ** Files inside the decrypted backup** :
155+ - ` extensions.sql ` - Database extensions
156+ - ` schema.sql ` - Complete database schema
157+ - ` policies.sql ` - RLS policies
158+ - ` functions.sql ` - Custom SQL functions
159+ - ` triggers.sql ` - Database triggers
160+ - ` complete_backup.dump ` - Full binary backup with all data
161+ - ` backup_info.txt ` - Backup metadata
162+
163+ #### Restoring from Encrypted Backup
164+
165+ After decrypting:
166+
167+ ``` bash
168+ # 1. Set your NEW Supabase database URL
169+ export SUPABASE_DB_URL=" postgresql://postgres:password@db.xxx.supabase.co:6543/postgres"
170+
171+ # 2. Restore extensions first
172+ psql " $SUPABASE_DB_URL " -f extensions.sql
173+
174+ # 3. Restore schema
175+ psql " $SUPABASE_DB_URL " -f schema.sql
176+
177+ # 4. Restore full data using pg_restore
178+ pg_restore --dbname=" $SUPABASE_DB_URL " \
179+ --no-owner \
180+ --no-privileges \
181+ --clean \
182+ --if-exists \
183+ complete_backup.dump
184+
185+ # 5. Restore RLS policies
186+ psql " $SUPABASE_DB_URL " -f policies.sql
187+
188+ # 6. Restore functions
189+ psql " $SUPABASE_DB_URL " -f functions.sql
190+
191+ # 7. Restore triggers
192+ psql " $SUPABASE_DB_URL " -f triggers.sql
193+ ```
194+
195+ ** Or use the restore script** (if available in the backup):
196+ ``` bash
197+ cd supabase_snapshot/
198+ export SUPABASE_DB_URL=" your-new-connection-string"
199+ ./restore.sh
200+ ```
201+
202+ #### Security Notes
203+
204+ - 🔑 ** Keep your encryption key safe!** Store ` BACKUP_ENCRYPTION_KEY ` in a password manager
205+ - 🔒 ** Without the key, backups cannot be decrypted** - there's no recovery method
206+ - 👥 ** Share the key** with trusted team members who may need to restore
207+ - 🔄 ** Rotate keys periodically** and update the GitHub secret
208+
209+ #### Why Encryption?
210+
211+ Since this repository is public, anyone can view workflow runs and download artifacts. Encryption ensures:
212+ - ✅ User data remains private
213+ - ✅ Passwords (even hashed) are protected
214+ - ✅ Compliance with data protection regulations
215+ - ✅ Peace of mind for your users
110216
111217## 📝 Configuration
112218
0 commit comments