diff --git a/.github/workflows/android_ci.yml b/.github/workflows/android_ci.yml
index 0ccfe4cde..5fc5ac6b8 100644
--- a/.github/workflows/android_ci.yml
+++ b/.github/workflows/android_ci.yml
@@ -1,50 +1,50 @@
 name: Android Build CI
 
 on:
   push:
     branches: [master]
     paths-ignore:
       - 'landing/**'
       - 'web/**'
       - 'docs/**'
       - 'keyserver/**'
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: set up JDK 11
         uses: actions/setup-java@v2
         with:
           java-version: '11'
           distribution: 'adopt'
 
       - name: Install Yarn
         run: npm install -g yarn
 
       - name: yarn --frozen-lockfile
         run: yarn --frozen-lockfile
 
       - name: Save ANDROID_KEY_STORE_B64 to file
         env:
           ANDROID_KEY_STORE_B64: ${{secrets.ANDROID_KEY_STORE_B64}}
         run: echo "$ANDROID_KEY_STORE_B64" > ANDROID_KEY_STORE_B64.b64
 
       - name: Save ANDROID_KEY_STORE to file
         run: base64 -d ANDROID_KEY_STORE_B64.b64 > android_key_store.keystore
 
       - name: Configure gradle.properties
         run: |
           mkdir ~/.gradle
           touch ~/.gradle/gradle.properties
           echo "COMM_UPLOAD_STORE_FILE=$(pwd)/android_key_store.keystore" >> ~/.gradle/gradle.properties
           echo "COMM_UPLOAD_KEY_ALIAS=AndroidSigningKey" >> ~/.gradle/gradle.properties
 
       - name: Build with Gradle
         working-directory: ./native/android
         env:
           ANDROID_SIGNING_PASSWORD: ${{secrets.ANDROID_SIGNING_PASSWORD}}
         run: ./gradlew bundleRelease
diff --git a/.github/workflows/android_release.yml b/.github/workflows/android_release.yml
index 1b83aa18d..7bfcddd55 100644
--- a/.github/workflows/android_release.yml
+++ b/.github/workflows/android_release.yml
@@ -1,54 +1,54 @@
 name: Android Build/Upload to Play Store Console
 
 on:
   release:
     types: [published]
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
       - name: set up JDK 11
         uses: actions/setup-java@v2
         with:
           java-version: '11'
           distribution: 'adopt'
 
       - name: Install Yarn
         run: npm install -g yarn
 
       - name: yarn --frozen-lockfile
         run: yarn --frozen-lockfile
 
       - name: Save ANDROID_KEY_STORE_B64 to file
         env:
           ANDROID_KEY_STORE_B64: ${{secrets.ANDROID_KEY_STORE_B64}}
         run: echo "$ANDROID_KEY_STORE_B64" > ANDROID_KEY_STORE_B64.b64
 
       - name: Save ANDROID_KEY_STORE to file
         run: base64 -d ANDROID_KEY_STORE_B64.b64 > android_key_store.keystore
 
       - name: Configure gradle.properties
         run: |
           mkdir ~/.gradle
           touch ~/.gradle/gradle.properties
           echo "COMM_UPLOAD_STORE_FILE=$(pwd)/android_key_store.keystore" >> ~/.gradle/gradle.properties
           echo "COMM_UPLOAD_KEY_ALIAS=AndroidSigningKey" >> ~/.gradle/gradle.properties
 
       - name: Build with Gradle
         working-directory: ./native/android
         env:
           ANDROID_SIGNING_PASSWORD: ${{secrets.ANDROID_SIGNING_PASSWORD}}
         run: ./gradlew bundleRelease
 
       - name: Save PLAY_STORE_PUBLISHING_KEY to file
         working-directory: ./native/android
         env:
           PLAY_STORE_PUBLISHING_KEY: ${{secrets.PLAY_STORE_PUBLISHING_KEY}}
         run: echo "$PLAY_STORE_PUBLISHING_KEY" > PLAY_STORE_PUBLISHING_KEY.json
 
       - name: Upload to Google Play
         working-directory: ./native/android
         run: node upload-aab.js
diff --git a/.github/workflows/backup_build.yml b/.github/workflows/backup_build.yml
index dd98d2995..b179af4c2 100644
--- a/.github/workflows/backup_build.yml
+++ b/.github/workflows/backup_build.yml
@@ -1,21 +1,21 @@
 name: Backup Build (Docker)
 
 on:
   push:
     branches: [master]
     paths-ignore:
       - 'landing/**'
       - 'web/**'
       - 'docs/**'
       - 'keyserver/**'
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: docker-compose build --no-cache backup-server
         working-directory: ./services
         run: docker-compose build --no-cache backup-server
diff --git a/.github/workflows/blob_build.yml b/.github/workflows/blob_build.yml
index f391f94f8..0b26c6b47 100644
--- a/.github/workflows/blob_build.yml
+++ b/.github/workflows/blob_build.yml
@@ -1,21 +1,21 @@
 name: Blob Build (Docker)
 
 on:
   push:
     branches: [master]
     paths-ignore:
       - 'landing/**'
       - 'web/**'
       - 'docs/**'
       - 'keyserver/**'
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: docker-compose build --no-cache blob-server
         working-directory: ./services
         run: docker-compose build --no-cache blob-server
diff --git a/.github/workflows/docker_keyserver.yml b/.github/workflows/docker_keyserver.yml
index f08a9990d..0a5d8b9c0 100644
--- a/.github/workflows/docker_keyserver.yml
+++ b/.github/workflows/docker_keyserver.yml
@@ -1,20 +1,20 @@
 name: Docker keyserver CI
 
 on:
   push:
     branches: [master]
     paths-ignore:
       - 'native/**'
       - 'docs/**'
       - 'services/**'
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: Build Docker
         working-directory: ./keyserver
         run: touch .env && bash/dc.sh build --no-cache
diff --git a/.github/workflows/eslint_flow_jest.yml b/.github/workflows/eslint_flow_jest.yml
index 6b95eece2..6ab9f2993 100644
--- a/.github/workflows/eslint_flow_jest.yml
+++ b/.github/workflows/eslint_flow_jest.yml
@@ -1,48 +1,48 @@
 name: ESLint & Flow & Jest
 
 on:
   push:
     branches: [master]
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
     steps:
       - uses: actions/checkout@v2
 
       - name: npm install -g yarn
         run: npm install -g yarn
 
       - name: yarn --frozen-lockfile
         run: yarn --frozen-lockfile
 
       - name: yarn eslint --max-warnings=0
         run: yarn eslint --max-warnings=0
 
       - name: '[lib] flow'
         working-directory: ./lib
         run: ./node_modules/.bin/flow
 
       - name: '[keyserver] flow'
         working-directory: ./keyserver
         run: ./node_modules/.bin/flow
 
       - name: '[web] flow'
         working-directory: ./web
         run: ./node_modules/.bin/flow
 
       - name: '[landing] flow'
         working-directory: ./landing
         run: ./node_modules/.bin/flow
 
       - name: '[native] flow'
         working-directory: ./native
         run: ./node_modules/.bin/flow
 
       - name: '[lib] test'
         working-directory: ./lib
         run: yarn test
 
       - name: '[keyserver] test'
         working-directory: ./keyserver
         run: yarn test
diff --git a/.github/workflows/identity_build.yaml b/.github/workflows/identity_build.yaml
index 99a0d3ace..89d48ff15 100644
--- a/.github/workflows/identity_build.yaml
+++ b/.github/workflows/identity_build.yaml
@@ -1,21 +1,21 @@
 name: Identity Build (Docker)
 
 on:
   push:
     branches: [master]
     paths-ignore:
       - 'landing/**'
       - 'web/**'
       - 'docs/**'
       - 'keyserver/**'
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: docker-compose build --no-cache identity-server
         working-directory: ./services
         run: docker-compose build --no-cache identity-server
diff --git a/.github/workflows/ios_release.yml b/.github/workflows/ios_release.yml
index 89619f854..7f364ac2e 100644
--- a/.github/workflows/ios_release.yml
+++ b/.github/workflows/ios_release.yml
@@ -1,82 +1,82 @@
 name: iOS Build/Archive/Upload to AppStore Connect
 
 on:
   release:
     types: [published]
 
 jobs:
   build:
     name: Build, archive, and upload iOS app
-    runs-on: macos-11
+    runs-on: macos-12
 
     steps:
       - name: Checkout
         uses: actions/checkout@v2
 
       - name: Install the Apple certificate and provisioning profile
         env:
           BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
           P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
           BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
           KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
         run: |
           # create variables
           CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
           PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
           KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
 
           # import certificate and provisioning profile from secrets
           echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH
           echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode --output $PP_PATH
 
           # create temporary keychain
           security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
           security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
           security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
 
           # import certificate to keychain
           security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
           security list-keychain -d user -s $KEYCHAIN_PATH
 
           # apply provisioning profile
           mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
           cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
 
       - name: npm install -g yarn
         run: npm install -g yarn
 
       - name: yarn --frozen-lockfile
         run: yarn --frozen-lockfile
 
       - name: Save auth_key to file
         working-directory: ./native/ios
         env:
           AUTH_KEY: ${{secrets.AUTH_KEY}}
         run: echo "$AUTH_KEY" > AUTH_KEY.p8
 
       - name: Archive
         working-directory: ./native/ios
         env:
           AUTH_KEY_ID: ${{secrets.AUTH_KEY_ID}}
           AUTH_KEY_ISSUER_ID: ${{secrets.AUTH_KEY_ISSUER_ID}}
         run: xcodebuild archive -workspace Comm.xcworkspace -scheme Comm -configuration Release -archivePath archives/Comm.xcarchive -destination generic/platform=iOS -allowProvisioningUpdates -authenticationKeyIssuerID "$AUTH_KEY_ISSUER_ID" -authenticationKeyID "$AUTH_KEY_ID" -authenticationKeyPath $PWD/AUTH_KEY.p8
 
       - name: Export IPA
         working-directory: ./native/ios
         env:
           AUTH_KEY_ID: ${{secrets.AUTH_KEY_ID}}
           AUTH_KEY_ISSUER_ID: ${{secrets.AUTH_KEY_ISSUER_ID}}
         run: xcodebuild -exportArchive -archivePath archives/Comm.xcarchive -exportOptionsPlist exportOptions.plist -exportPath output -allowProvisioningUpdates -authenticationKeyIssuerID "$AUTH_KEY_ISSUER_ID" -authenticationKeyID "$AUTH_KEY_ID" -authenticationKeyPath $PWD/AUTH_KEY.p8
 
       - name: Upload IPA to TestFlight
         working-directory: ./native/ios
         env:
           APPLE_USER_NAME: ${{secrets.APPLE_USER_NAME}}
           APPLE_APP_SPECIFIC_PASSWORD: ${{secrets.APPLE_APP_SPECIFIC_PASSWORD}}
         run: xcrun altool --upload-app --type ios --file output/Comm.ipa --username "$APPLE_USER_NAME" --password "$APPLE_APP_SPECIFIC_PASSWORD"
 
       - name: Clean up keychain and provisioning profile
         if: ${{ always() }}
         run: |
           rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision
           security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
diff --git a/.github/workflows/remove_harbormaster_tags.yml b/.github/workflows/remove_harbormaster_tags.yml
index 1515466ba..fa132cae1 100644
--- a/.github/workflows/remove_harbormaster_tags.yml
+++ b/.github/workflows/remove_harbormaster_tags.yml
@@ -1,28 +1,28 @@
 name: Remove extraneous Harbormaster git tags
 
 on:
   push:
     branches: [master]
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: npm install -g yarn
         run: npm install -g yarn
 
       - name: yarn --frozen-lockfile
         run: yarn --frozen-lockfile
 
       - name: Generate tag removal script
         working-directory: ./scripts
         env:
           PHABRICATOR_API_TOKEN: ${{secrets.PHABRICATOR_API_TOKEN}}
         run: node generate-phab-tag-removal-script.js
 
       - name: Run tag removal script
         working-directory: ./scripts
         run: chmod +x tag_removal_script.sh && ./tag_removal_script.sh
diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml
index abc988e54..c66af57ff 100644
--- a/.github/workflows/shellcheck.yml
+++ b/.github/workflows/shellcheck.yml
@@ -1,18 +1,18 @@
 name: ShellCheck
 
 on:
   push:
     branches: [master]
 
 jobs:
   shellcheck:
     name: ShellCheck
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
     steps:
-    - uses: actions/checkout@v2
+      - uses: actions/checkout@v2
 
-    - name: Set globstar
-      run: shopt -s globstar
+      - name: Set globstar
+        run: shopt -s globstar
 
-    - name: Run ShellCheck
-      run: shellcheck -x -P SCRIPTDIR **/*.sh
+      - name: Run ShellCheck
+        run: shellcheck -x -P SCRIPTDIR **/*.sh
diff --git a/.github/workflows/tunnelbroker_build.yaml b/.github/workflows/tunnelbroker_build.yaml
index ce0d6b3ba..11f2ab129 100644
--- a/.github/workflows/tunnelbroker_build.yaml
+++ b/.github/workflows/tunnelbroker_build.yaml
@@ -1,21 +1,21 @@
 name: Tunnelbroker Build (Docker)
 
 on:
   push:
     branches: [master]
     paths-ignore:
       - 'landing/**'
       - 'web/**'
       - 'docs/**'
       - 'keyserver/**'
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
 
     steps:
       - uses: actions/checkout@v2
 
       - name: docker-compose build --no-cache tunnelbroker-server
         working-directory: ./services
         run: docker-compose build --no-cache tunnelbroker-server