Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 25 additions & 31 deletions .env.enc
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
DB_USER=ENC[AES256_GCM,data:ZuTXZnCIDMObGViREkvE5A==,iv:o/MCq/5KjtaocJMIdf239BqPZpbEiBEW7jKeyljmgwM=,tag:YTWwkCerN9hQoA591v25ww==,type:str]
DB_PASSWORD=ENC[AES256_GCM,data:FQn8WEEAggYtWel0Y4KHDA==,iv:Z8IjzQB/6Jn0P4g1ZU5SSZYvH2vFBU9N26T41AGCndk=,tag:NjZgBOvHRkybASe6PvaGbw==,type:str]
DB_NAME=ENC[AES256_GCM,data:DMDfyT5cXdh6ygzzgoOvFA==,iv:DxiUqQcgUSINhxdXHLKBuHD7k265JLW+X1w7rbPFbiM=,tag:TtFH8EthkWyUJVDcChAoOQ==,type:str]
DB_PORT=ENC[AES256_GCM,data:MxLXFw==,iv:+f7E0r9NEwsA1h9ZUFz9I9LFB8PDSXNZsRyZ0KrGQVk=,tag:FLae3fAWy5/ArnysJ1sgDg==,type:str]
REDIS_PORT=ENC[AES256_GCM,data:rA0BOA==,iv:cqEPtzAN5wcGsGgQp/bD2bPoW0nXhgzbnCk7k4YevHk=,tag:8pgcyAPDkUowrnjh79joiw==,type:str]
FRONTEND_PORT=ENC[AES256_GCM,data:j/4zww==,iv:lvrmXGAX8xrIPDy6Hnx7gLPg0YqGVitoBuGnmsxHqIg=,tag:+64/LuGZw/3PmqpcQP/6Mw==,type:str]
NEXT_PUBLIC_API_URL=ENC[AES256_GCM,data:rNSLpY3/KlPjIr8dJCttIDeNZ8De,iv:bUkNYfawC2vxFkApDHRNvuCFJjh0z5C70RqjCWTfW2U=,tag:OEbhBtz44kUi8Rn0ZsZDIA==,type:str]
NEXT_PUBLIC_WS_URL=ENC[AES256_GCM,data:vYq8w9XKpg14nW0aKrMLav9yxOQ95Q==,iv:JE3eu7hzYi8ic6PcH1zgLuqUXuSmPMHHkn5mBjYrbgs=,tag:G9LiirwL3Sr3eOx9q3Yrng==,type:str]
BACKEND_PORT=ENC[AES256_GCM,data:8ZazJw==,iv:CbHg3xSKdvqXJsWFAVkXIp5yZ2nxzagbIEMIH2KiLQE=,tag:QE6KgJiRy7SRxxdhvjdlJA==,type:str]
SPRING_PROFILE=ENC[AES256_GCM,data:t8kX,iv:PPqdggMykBjRSBsZJ/uTAOHHFdyYR13JZbDBAt2fxjA=,tag:ZriOUlkShkyp05sH9SI+xg==,type:str]
JWT_SECRET=ENC[AES256_GCM,data:yy72mAUDQ3IWrZU+dwoQW+UOM/Y=,iv:olGp+ADjXJwGoayVD3vtnI603ztFvKI+FmRXzAvWklI=,tag:1oNFi5N8eB23CYH8AH0Zpg==,type:str]
SPRING_JPA_HIBERNATE_DDL_AUTO=ENC[AES256_GCM,data:RciRsocc,iv:gb8PjuBC5qkymU4K/fiHQPuqum3RzWdOgBVHH9lH7Ts=,tag:6q7pQlk3jtW/gXvPPtbnPQ==,type:str]
PGADMIN_PORT=ENC[AES256_GCM,data:5bl80A==,iv:eJlyu9vGtXg1iNWS+nDkmvLWEhBOrXw73wYX/TcGdUY=,tag:B1IXGZNiObGoHdvKKCyHRg==,type:str]
PGADMIN_EMAIL=ENC[AES256_GCM,data:BR2bfU5LVuTSppwvfEvm,iv:jNQSh5U4yHQVUcXxWeTz7uEHt/7EYHV4eudW/qLc2mY=,tag:1Q4vKxfYfQ2mTfSzZd247Q==,type:str]
PGADMIN_PASSWORD=ENC[AES256_GCM,data:tVn20EM=,iv:5QY1NjmQekvbxoZ6i4/G2yvzHfq5byWVFnDy/q5B+gQ=,tag:6Wp2/1iR4gnVnd+wlvHiaQ==,type:str]
NEXT_PUBLIC_SUPABASE_URL=ENC[AES256_GCM,data:+PeLo+V+EWwcHVTnFBFT4syMGQtmgZff5UAD31lRBIexLbIlPvvGDA==,iv:/8A/aYoKi0kdrdARUOw2jRCCTDof7y/nll9NhvnjGFw=,tag:AA/snF/wOLvGD1ZCCAq1zQ==,type:str]
NEXT_PUBLIC_SUPABASE_ANON_KEY=ENC[AES256_GCM,data:IygcPTFrpwbvJDrosT1koFRLl1HzTQkqAoJ4WmMGUZW0N+ISdkCyyDArS6xp0+QElN04eigi4GVc55oiU7ojX2bODgwu8QdVUxo9YPWohcsNdmFwfClr7Y2b/+dCW2UFnsdbmr2o77mHPF1ainw/E+uDC1mHQ/Vd5J7jbRriAy9WodhjypptUszGdjR2cY4n3eZ0SWHpbtb1KeXevrPEWUssODvVOA8yxDHsZ3grFnAysK9Y/ZapeApypYh4qgAzCy9pYTqAmidYuYfCxaXb+FHP,iv:29F9/qg9GlJmN3cntiMY1HSszTsBM2gfM5h5O1+Rllk=,tag:Hq17D8k+VIqGZLQCS99ncw==,type:str]
SUPABASE_SERVICE_ROLE_KEY=ENC[AES256_GCM,data:+X3A8DOhf3+kBUe1fUcT5kzIltDGajvQgK0FrMkTHCxDxOYuziyL8Vm4K0yTs8UK4DzPmXiwmPPYwQkK+P1oV/BMOPCpPI/RMMSbV+BrFueNR5wTBpZhwaDGNYchomRfRbsjv1fadr3wNI93uikGipjpXce07EfotMVGIgAFWRjQEhNgfP/L7z+H7Lq7TmPJSZtumM9neEOQnzvaaNxLU3bWplLOrv5TMuRkudj+Ur8RL7Iuq7yqOZOtd5W34aekqV6SzmDfU7jtS9Cktd4F7qXryzx9X+cLvpGFMps=,iv:oiRF14Qmu+Cpd6DjkjYpeKK+oS9Lm3PyuYUx/QXOF9A=,tag:6iNaMcK7ceQc0bNOXhLDQA==,type:str]
SUPABASE_JWT_SECRET=ENC[AES256_GCM,data:GYXfoeot4vk4lpNOZVMjDukD/vpq3zA74qVW+W7Z3AJ7QI43anS8geS48x3cHJSOS81e+vRYyXb2GZH7XhWiM1eMLLLPRJlXaV3XvV+yANP71kAdzzSrbPCU,iv:wF8aIsUTWnM+enWdaJ4VTtZjUxvdnBN19tkdGGUBaYg=,tag:KKJb5HRd4XBPpMaooRDGWg==,type:str]
sops_lastmodified=2025-06-28T05:07:23Z
sops_mac=ENC[AES256_GCM,data:v0iZaxDog6gn9LznoX/dj6Hsa06is7BaI1WA39RuUeuVzlkXacUzSPoM6Mp3dh3jSdkMruNvAm9Or/u035MmQoUu2uQgzy70UyP9k9t35HcrMxlZ2xAvxUMkkEcuzOS/jkT43qikXS+iclu5pP3N7EAgM2qn5cNJ9ZpuTAB2sr0=,iv:RZdfnixevHfVJlPrRDHq7Qzqp/1J3Y2v9SCMqA+rnB4=,tag:FUh4hxTpoz7/E+U/y+55MQ==,type:str]
sops_pgp__list_0__map_created_at=2025-06-28T03:10:57Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhF4DSt16dI0PNiISAQdAJnyGeAm/ZneDUrTRukvLhwHshMxJ0AYwz7oQD7LiunYw\nKbLEg/YRRawB5ARiW9hvQo9d+gBYxaByNvuE0OJ9v/nJLXf5K9NoEU1/tf3f41kc\n1GYBCQIQQQ6qRcTqA5+PtrEd6UOrx8L/JPskywb3HogBsBml9o7FZ9KwgLp2DPLw\n5K3mIauAtqHWn0RDw9kkaIhhahuhxBTox5vNPWMi6lcJN22TmWmT7dRAoE8Lf3Hv\n81YCDVNFwh0=\n=7p6t\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=A42113A260AFDA3A
sops_pgp__list_1__map_created_at=2025-06-28T05:00:17Z
sops_pgp__list_1__map_enc=-----BEGIN PGP MESSAGE-----\n\nhF4DD2ITbbO4/MESAQdA7Cw4ms6XFsk5GF58azUd791DQEQBp8kegb98X+sz+1gw\nqaZiQc6yUqKJ8CLIcNkANrBIRx4bL92giIMDDJCwK1Z3IQxBYQgg97LAitps9+jk\n1GYBCQIQ0fX5o+LZKeahrLy6M0dHmwuPESmL8lMhVSegcZj7NXvU0zKlm2Fu/ZR7\n6lwduoJ+YZHncGd4W5Lu8cLAcNG1PHCBlZ+/GU09EI9m8JpBCu5mEARpVGRbv1c+\n7yqEwVrUNTg=\n=9pza\n-----END PGP MESSAGE-----
sops_pgp__list_1__map_fp=A603931ABDBB8AB72C97AE07ED479F8459ACCFDD
sops_pgp__list_2__map_created_at=2025-06-28T05:07:22Z
sops_pgp__list_2__map_enc=-----BEGIN PGP MESSAGE-----\n\nhF4DugffLwUcW/ESAQdArShOHLcofBL8P+Q7BXc3F72eRcR5GcQngJFdvjFngz8w\nJLPFirGj3qvlgNW95HWHzX/FCJEjsizfLOgmKOf/YCXToTj/+vuMezC1CJA/8Sx3\n1GYBCQIQMA5mKwiYJuaN8vy1U3bb3bM2L9GdlQ5xRN2QYyPlN0TMO8sgNXxp6XKM\nQVvKHTbQGXjtHGA0ISGBEWLZls32qxeJYvh6+lnw4BxKGZk0h04kQRWytFIl/lb3\nWJuyVSUUpgs=\n=PlNl\n-----END PGP MESSAGE-----
sops_pgp__list_2__map_fp=BB58AF94309753F6CDF13B57A9C2279290596F20
sops_unencrypted_suffix=_unencrypted
DB_USER=ENC[AES256_GCM,data:dNWbJtvYBLGu4cqEdLop2d8=,iv:FcKghlD8V/SAkIPI373mJbyV/uJuneblOwuH4Rr/Bsc=,tag:u5pOdEzzdjvnd+NqqUUMWA==,type:str]
DB_PASSWORD=ENC[AES256_GCM,data:63k982x4Uyed6q0Z9eGjYkM=,iv:MZMnLgxHVVjayzCOyn6iOs5w7d3wHgWGxHz3KLlYjYA=,tag:eCcFgaXCJ8rtuibMCyHNFg==,type:str]
DB_NAME=ENC[AES256_GCM,data:uKxkH3WT6XKFm7qe88erPJ8=,iv:l0V7OfSo7U+cmM41hnFQLVEAmMHMxrCCWcCKAI6PCbw=,tag:TRlibqRtH/YHYPedrQRZzQ==,type:str]
DB_PORT=ENC[AES256_GCM,data:CyeDvso=,iv:l4g1rBSR/GllUMRL9kjurQPgT7vNnGIx4zMAHw+gSuo=,tag:wrl2f14xATY0Nf5vdpXL3w==,type:str]
REDIS_PORT=ENC[AES256_GCM,data:bnFoICA=,iv:6ikTsuTfi17iEkpcrvarMHJ1Mu0QxLmbZXB8FsDMeck=,tag:iN7R6lL8onA3Jpe/YQoNVw==,type:str]
FRONTEND_PORT=ENC[AES256_GCM,data:Z9F9wx0=,iv:KMj373jm9CuOy6YIVqCIMHJBp1Z2iWxfKYLMAp7MB5I=,tag:8CrYpW+NW70Xv/Cyst40Ag==,type:str]
NEXT_PUBLIC_API_URL=ENC[AES256_GCM,data:nDuR51aMZn/1E6ImmlUMT4VUcWXKbQ==,iv:3DIK2RHiLc3dzriYBY11FAk5S6vm8GQPTApC7jNnupo=,tag:Bb9m1xt+5D4g3VBETAo2oA==,type:str]
NEXT_PUBLIC_WS_URL=ENC[AES256_GCM,data:csoyrsCn4TwMWCdSckRzmSEPtLCtHJY=,iv:nosYULKst1lU1vwBcZ/nC4FnlxcKKkBATM22VKz9PgQ=,tag:JRNheQ4cgzc02gJQc8viVQ==,type:str]
BACKEND_PORT=ENC[AES256_GCM,data:wYHQ+Io=,iv:kNK63eN0unAWakgtTOlhFsfDXxxtSxD1ZQR6rMDYHUg=,tag:Pem+s6ZiqSwuAbMzMztmRw==,type:str]
SPRING_PROFILE=ENC[AES256_GCM,data:+Sw2FQ==,iv:bTZIYehAMQlhf4z2K8q+5Fm2tp2kY4QvWsI2vY03KJE=,tag:t4C8aWXI41kp1cZDytTFBQ==,type:str]
JWT_SECRET=ENC[AES256_GCM,data:oH/cdk3ef38Bhkk2N8UnVG0dkcJf,iv:2g4/qU0eGUTqy+6cQdUSxhe1P0DmSSRrltDIO31WRso=,tag:xdC9wpQ6oR7eL8y80CcB8w==,type:str]
SPRING_JPA_HIBERNATE_DDL_AUTO=ENC[AES256_GCM,data:XbTRZMyV/g==,iv:OFlxmt+RP6JjPAX/2o6EtD1u2RxS1T5XhbxE3kU7doA=,tag:KXjo60p75eZuc+c53UDcMQ==,type:str]
PGADMIN_PORT=ENC[AES256_GCM,data:E9dLtTM=,iv:wtSDQogRq9Q/30Q09pLfLw5UJB9WAP23oxEOxEl6KsU=,tag:idC5/4IT27zbzC5dPweESw==,type:str]
PGADMIN_EMAIL=ENC[AES256_GCM,data:WASPLvRzwjuUiBQpcOsHpQ==,iv:j9fm5i0Q1XAqi6ZRfzjMWBgwCHH5GeCamg4TfVUeijA=,tag:+5htvbptVc7zMpS4WYLAPg==,type:str]
PGADMIN_PASSWORD=ENC[AES256_GCM,data:uP/Mi00W,iv:qC2gaOJffcefiU7rMpdxt4okrnbgTJ5BPr0tvtgbhq0=,tag:pkyMuashbvNVofY3XaO4VA==,type:str]
NEXT_PUBLIC_SUPABASE_URL=ENC[AES256_GCM,data:GmRuqMJjk97u1NvmX/UGMNbRDflPcQU0YhYW7qaIAqqNX0iXY4bW5+M=,iv:liM5Dl4hKlSYjCh3ItvJVcGbm2osP/tbHn0A6OCArqs=,tag:G/ryZgCpkJFBGHL0LFs42A==,type:str]
NEXT_PUBLIC_SUPABASE_ANON_KEY=ENC[AES256_GCM,data:fE/XFzNRarL/fDfJhkoXznEWrcekuYwBGPGHwgwn8lq7mnd9wGrMByBYEQ91ElJGNKR5in36LwR/WF/sH5S7LWn/wdWCdvLaEYPvDQiz9ZLV4FpYw/DfZnxHbo8QbNXwrNJOrxE1dITAw580MKfPl3Rg145B2XLvRkpxpOIgYKJllG9AA+VzTm3DS7nGebrK8qWObHCa3vI+7U8qKtGzxoTOOGFTXcVUDZkms2XROMY6Mx6pNUA+INjQzbylYrQdo02Z8iXYuMsVe84xHrR7AR+8iA==,iv:+AF7gmo4Xp5eAhXXI/v+q983cXLd86U/laghpEKKFJw=,tag:/YSEclotJpTRfJsnk/iAQQ==,type:str]
SUPABASE_SERVICE_ROLE_KEY=ENC[AES256_GCM,data:YdRW/ePWPz6/BfRVJoHo8TJ5SlgaTiVbnv99X7QY6i70Xy9oMn6WSyWeVnORTp3i4xD6V8UTSYs3iYMTcXJUzg7rShQj2EakPSb4CP7gDpg5JpUQXKB+BSVsiY4BRx/6Sjm6hQ1VQUNz4AGt0RYTbXxv6yfMs4kJPmxcrOH2vs/upyCp6mdCpZwjKf+icoGG4VHIZysIFLj+etvbRDt3VpDEm6YOb3gVA/8WJVT61srbwJCYaFk4odJNTWp5V6kmvtvbHj61eN9z7rwnOy3rdU8cGma4ZPXSpoIUxNJS,iv:Z8DJFPDsuy+Y2GHOAJ2e67KbviCBKhjpy4bkOsIcdb0=,tag:BDjVTjTET6p43SVwJZRWCA==,type:str]
SUPABASE_JWT_SECRET=ENC[AES256_GCM,data:KdTilsYTjqEW7RDbGOIsoJkmlF6y0aqkLEGtk6CLBWGNlSlVrsqihhEWYHexTv0rZsH3ajSG9gr2pa+yXhFA6vi7CRP7SCd3owqjLVf71F6qqI5i4GW9cZ1puw==,iv:2BxhC3yJ2L4rg2pNYimVODxv+0+yxzPHZgvAke5cb7E=,tag:/8miDM8J1vv41V5CkzuUZA==,type:str]
sops_encrypted_regex=.*
sops_lastmodified=2025-06-28T20:01:43Z
sops_mac=ENC[AES256_GCM,data:O5fnFm1bKAY2lupMF2ysPvNCyDbYJGJGtC12rKmXF+SEF10jS3+17kOH5kSEbQBMh1A5rJ5Y045Ohut8sjSy3falA41ErVFLXWcUv4cyPcGOKiGVOeobam/3wK6BzJyVx4PZe9peRO2l+ki5uCger72LZ0i2mTk9R09ToJ5vyd4=,iv:3zDtkih451rLAjgP+22uxfK1lEMRBjgKPb2EfrsuYkA=,tag:LKOVRbnueRqtzHOArKYpOQ==,type:str]
sops_pgp__list_0__map_created_at=2025-06-28T20:01:43Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhF4DugffLwUcW/ESAQdAiIz81O+kn/NlDCxPZXa3XsPhB9/nsjHFMPnE7oyZlXIw\nTU9wOylLugN3NEwDObxdQLbkcvvn9VGaCjLj119AyKalxT8oImo0bBa2Wt5RKwIN\n1GgBCQIQdqmPVEXjny0OQalPLZntaYweSVy4WsmkwNCNwRm1ZQMeU+Xqwp2tm5z/\nc/jafpS7aZr5Ivv46YK9zApOV2LzjBUvzdH8B6rOU2D7mvTmATCkmnh8NQVdlY1U\nIcjCFe3OeBxEWA==\n=3ema\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=BB58AF94309753F6CDF13B57A9C2279290596F20
sops_version=3.10.2
59 changes: 45 additions & 14 deletions .github/workflows/sops-onboard.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# .github/workflows/sops-onboard.yml

permissions:
contents: write
pull-requests: write

name: Refresh SOPS config

on:
Expand All @@ -25,29 +30,55 @@ jobs:
sudo mv sops /usr/local/bin/
sops --version

# 3) Ensure your update script is executable
- name: Make update script executable
run: chmod +x scripts/update-sops.sh

# 4) Capture the runner’s TTY for GPG
# 4) Capture the runner's TTY for GPG
- id: tty
run: echo "::set-output name=tty::$(tty)"
run: echo "tty=$(tty)" >> $GITHUB_OUTPUT

# 5) Import the CI GPG private key (no passphrase needed)
- name: Import CIs GPG key
- name: Import CI's GPG key
env:
GPG_TTY: ${{ steps.tty.outputs.tty }}
run: |
echo "${{ secrets.CI_GPG_PRIVATE }}" > ci.key.asc
gpg --batch --import ci.key.asc
echo "${{ secrets.CI_GPG_PRIVATE }}" \
| gpg --batch --import

- name: Import all teammates' public keys
shell: bash
run: |
shopt -s nullglob

key_files=(keys/*.asc)

if [ ${#key_files[@]} -eq 0 ]; then
echo "⚠️ No public keys found in keys/*.asc — skipping import."
exit 0
fi

for pub in "${key_files[@]}"; do
echo "🔑 Importing $pub"
gpg --batch --import "$pub"
done

# 6) Rebuild .sops.yaml and re-encrypt .env → .env.enc
- name: Rebuild SOPS config & re-encrypt
run: bash scripts/update-sops.sh
run: |
bash scripts/update-sops.sh

# 7) Commit & push the changes back to main
- name: Commit & push changes
uses: stefanzweifel/git-auto-commit-action@v4
- name: Create Pull Request with updated env
uses: peter-evans/create-pull-request@v5
with:
commit_message: "chore: onboard new teammate and re-encrypt env"
branch: main
# A descriptive branch name
branch: sops/update-env-${{ github.sha }}
# What base branch to target
base: main
title: "chore: re-encrypt env for new teammate"
body: |
This PR was auto-generated by the SOPS onboarding workflow.
It updates `.sops.yaml` and re-encrypts `.env.enc` to include the new
public key(s) under `keys/*.asc`.
# You can auto-assign reviewers or labels if you like:
reviewers: "lstsk"
labels: "ci,sops"
commit-message: "chore: re-encrypt env for new teammate"
skip-if-no-changes: true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Environment files
**/.env
.env
.env.*
# But keep encrypted env files and the example
Expand Down
4 changes: 2 additions & 2 deletions .sops.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
creation_rules:
- path_regex: '(^|/)\.env(\.enc)?$'
encrypted_regex: "^(?!#).*"
- path_regex: '.*\.env(\.enc)?$'
encrypted_regex: ".*"
pgp:
Empty file added env.dec
Empty file.
14 changes: 14 additions & 0 deletions scripts/encrypt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Grab all fingerprints from keys/*.asc
FPS=$(for pub in keys/*.asc; do
gpg --with-colons --import-options show-only --import "$pub" \
| awk -F: '/^fpr:/ {print $10; exit}'
done)

# Encrypt each .env → .env.enc
find . -type f -name ".env" | while read -r ENV; do
OUT="${ENV}.enc"
echo "🔒 Encrypting $ENV → $OUT"
sops --encrypt --input-type dotenv --output-type dotenv \
$(printf -- '--pgp %s ' $FPS) \
"$ENV" > "$OUT"
done
52 changes: 28 additions & 24 deletions scripts/update-sops.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail

# Enable nullglob so missing files result in an empty array\shopt -s nullglob
# 1) Make globs vanish if they don’t match
shopt -s nullglob

ENV_FILE=".env.enc"
# 2) Gather current .asc fingerprints
declare -a current_fps=()
for pub in keys/*.asc; do
fp=$(gpg --with-colons --import-options show-only --import "$pub" \
| awk -F: '/^fpr:/ {print $10; exit}')
if [[ -n "$fp" ]]; then
current_fps+=("$fp")
else
echo "⚠️ Could not extract fingerprint from $pub; skipping."
fi
done

# Exit early if encrypted file doesn't exist
if [ ! -f "$ENV_FILE" ]; then
echo "⚠️ No $ENV_FILE found; skipping recipient rotation."
exit 0
fi
# 3) Load existing fingerprints from .sops.yaml
fps_csv=$(IFS=,; echo "${current_fps[*]}")
echo "🔧 Setting .sops.yaml pgp to: $fps_csv"
yq e -i '.creation_rules[0].pgp = "'"$fps_csv"'"' .sops.yaml

# Gather public key files
pub_keys=(keys/*.asc)
if [ ${#pub_keys[@]} -eq 0 ]; then
echo "↩️ No public keys found in keys/*.asc — nothing to do."
# 6) Rotate all .env.enc files (recursively)
mapfile -t env_files < <(find . -type f -name '.env.enc')
if [ ${#env_files[@]} -eq 0 ]; then
echo "⚠️ No .env.enc files foundnothing to re-encrypt."
exit 0
fi

# Rotate recipients into the existing encrypted file
for pub in "${pub_keys[@]}"; do
# Extract the full fingerprint
fp=$(gpg --with-colons --import-options show-only --import "$pub" \
| awk -F: '/^fpr:/ {print $10; exit}')
if [ -z "$fp" ]; then
echo "⚠️ Could not extract fingerprint from $pub; skipping."
continue
fi
echo "🔐 Rotating $ENV_FILE: adding recipient $fp"
# Use explicit dotenv format so SOPS doesn't try JSON
sops --input-type dotenv --output-type dotenv -i --rotate --add-pgp "$fp" "$ENV_FILE"
for file in "${env_files[@]}"; do
echo "🔄 Rotating recipients on $file"
for fp in "${current_fps[@]}"; do
sops --input-type dotenv --output-type dotenv -i \
--rotate --add-pgp "$fp" "$file"
done
done

echo "✅ Rotation complete: $ENV_FILE now accessible by ${#pub_keys[@]} recipient(s)."
echo "✅ Update complete."
Loading