diff --git a/.actrc b/.actrc
index fde4504..63e0425 100644
--- a/.actrc
+++ b/.actrc
@@ -1,9 +1,8 @@
---bind
---action-cache-path .github/cache/act/actions
---artifact-server-path .github/cache/act/artifacts
---artifact-server-port 34565
---cache-server-path .github/cache/act/cache
 --use-new-action-cache
+--action-cache-path=.github/cache/act/actions
+--cache-server-path=.github/cache/act/cache
+--artifact-server-path=.github/cache/act/artifacts
+--artifact-server-port=34016
 --platform self-hosted=ghcr.io/catthehacker/ubuntu:act-latest
 --platform ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest
 --platform ubuntu-22.04=ghcr.io/catthehacker/ubuntu:act-22.04
diff --git a/.github/workflows/bouncer.yml b/.github/workflows/bouncer.yml
index 2fbb790..687eeaa 100644
--- a/.github/workflows/bouncer.yml
+++ b/.github/workflows/bouncer.yml
@@ -11,7 +11,7 @@ on:
     branches:
       - main
   schedule:
-    - cron '0 8 * * 2' # 8am Patch Tuesday
+    - cron: "0 14 * * 2" # 2pm Patch Tuesday
 
 concurrency:
   group: ${{ github.head_ref || github.run_id }}
@@ -19,7 +19,7 @@ concurrency:
 
 jobs:
   build:
-    name: Build Bouncer
+    name: Build Docker Swarm Loadbalancer
     runs-on: ubuntu-latest
     steps:
       - name: "Setup: Checkout Source"
@@ -39,8 +39,6 @@ jobs:
         uses: shivammathur/setup-php@v2
         with:
           php-version: 8.2
-        env:
-          runner: self-hosted
 
       - name: "Setup: Setup QEMU"
         uses: docker/setup-qemu-action@v3
@@ -55,14 +53,14 @@ jobs:
         uses: docker/login-action@v3
         with:
           username: matthewbaggett
-          password: ${{ secrets.DOCKER_HUB_PASSWORD }}
+          password: ${{ secrets.DOCKER_HUB_TOKEN }}
 
       - name: "Setup: Login to GHCR"
         uses: docker/login-action@v3
         with:
           registry: ghcr.io
           username: matthewbaggett
-          password: ${{ secrets.GHCR_PASSWORD }}
+          password: ${{ secrets.GITHUB_TOKEN }}
 
       - name: "Setup: Find Composer Cache Directory"
         id: composer-cache
@@ -72,8 +70,8 @@ jobs:
         uses: actions/cache@v4
         with:
           path: ${{ steps.composer-cache.outputs.dir }}
-          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
-          restore-keys: ${{ runner.os }}-composer-
+          key: ${{ runner.os }}-bouncer-composer-${{ hashFiles('**/composer.lock') }}
+          restore-keys: ${{ runner.os }}-bouncer-composer-
 
       - name: "Dependencies: Composer Install"
         run: composer install --ignore-platform-reqs
diff --git a/.github/workflows/trunk.cache.yml b/.github/workflows/trunk.cache.yml
index b4e255d..6e3c66f 100644
--- a/.github/workflows/trunk.cache.yml
+++ b/.github/workflows/trunk.cache.yml
@@ -1,24 +1,36 @@
 name: Trunk Cache
-on:
-  push:
-    branches: [main]
-    paths: [.trunk/trunk.yaml]
-  workflow_dispatch:
 
 permissions: read-all
 
+on:
+  workflow_call:
+  workflow_dispatch:
+  push:
+    branches:
+      - main
+    paths:
+      - .trunk/trunk.yaml
+  schedule:
+    - cron: "0 9 * * 1" # 9am Tooling Monday
+
+concurrency:
+  group: ${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
+
 jobs:
   trunk-cache:
     name: Trunk Cache
-    runs-on: self-hosted
+    runs-on: ubuntu-latest
     permissions:
       actions: write
-
     steps:
-      - name: Checkout
+      - name: "Setup PHP"
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: 8.3
+      - name: "Checkout"
         uses: actions/checkout@v4
-
-      - name: Trunk Check
+      - name: "Trunk Cache"
         uses: trunk-io/trunk-action@v1
         with:
           check-mode: populate_cache_only
diff --git a/.github/workflows/trunk.check.yml b/.github/workflows/trunk.check.yml
index b22ebb2..2e06a65 100644
--- a/.github/workflows/trunk.check.yml
+++ b/.github/workflows/trunk.check.yml
@@ -1,27 +1,33 @@
-name: Code Quality Check (Trunk)
+name: Trunk Check
+
+permissions: read-all
+
 on:
   workflow_call:
   workflow_dispatch:
+  push:
+    branches:
+      - main
+  schedule:
+    - cron: "0 11 * * 2" # 11am Patch Tuesday
 
 concurrency:
   group: ${{ github.head_ref || github.run_id }}
   cancel-in-progress: true
 
-permissions:
-  contents: read
-
 jobs:
   trunk-check:
     name: Trunk Check Runner
-    runs-on: self-hosted
+    runs-on: ubuntu-latest
     permissions:
       checks: write # For trunk to post annotations
       contents: read # For repo checkout
     steps:
-      - name: Checkout
-        if: ${{ !env.ACT }}
+      - name: "Setup PHP"
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: 8.3
+      - name: "Checkout"
         uses: actions/checkout@v4
-
-      - name: Trunk Check
-        if: ${{ !env.ACT }}
+      - name: "Trunk Check"
         uses: trunk-io/trunk-action@v1
diff --git a/.github/workflows/trunk.upgrade.yml b/.github/workflows/trunk.upgrade.yml
index e77ea97..cc870b3 100644
--- a/.github/workflows/trunk.upgrade.yml
+++ b/.github/workflows/trunk.upgrade.yml
@@ -1,19 +1,36 @@
 name: Trunk Upgrade
-on:
-  schedule:
-    - cron: 0 8 * * 2 # Every Tuesday at 8am
-  workflow_dispatch: {}
 
 permissions: read-all
+
+on:
+  workflow_call:
+  workflow_dispatch:
+  push:
+    branches:
+      - main
+    paths:
+      - .trunk/trunk.yaml
+      - .github/workflows/trunk.upgrade.yml
+  schedule:
+    - cron: "0 11 * * 1" # 11am Tooling Monday
+
+concurrency:
+  group: ${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
+
 jobs:
   trunk-upgrade:
     name: Upgrade Trunk
-    runs-on: ubuntu-latest # MB: For some reason, the action doesn't work on self-hosted runners. I've not got time to investigate why right now but its so low-frequency and fast that it doesn't matter.
+    runs-on: ubuntu-latest
     permissions:
       contents: write # For trunk to create PRs
       pull-requests: write # For trunk to create PRs
     steps:
-      - name: Checkout
+      - name: "Setup PHP"
+        uses: shivammathur/setup-php@v2
+        with:
+          php-version: 8.3
+      - name: "Checkout"
         uses: actions/checkout@v4
       - name: "Trunk Upgrade"
         uses: trunk-io/trunk-action/upgrade@v1
diff --git a/.trunk/configs/.checkov.yaml b/.trunk/configs/.checkov.yaml
new file mode 100644
index 0000000..8331ca9
--- /dev/null
+++ b/.trunk/configs/.checkov.yaml
@@ -0,0 +1,3 @@
+---
+skip-check:
+  - CKV_SECRET_* # Skip all checks that start with CKV_SECRET, we already have gitleaks doing this.
diff --git a/.trunk/configs/.gitleaks.toml b/.trunk/configs/.gitleaks.toml
new file mode 100644
index 0000000..0ba3b68
--- /dev/null
+++ b/.trunk/configs/.gitleaks.toml
@@ -0,0 +1,3 @@
+title = "Gitleaks config"
+[extend]
+useDefault = true
diff --git a/.trunk/configs/.gitleaksignore b/.trunk/configs/.gitleaksignore
index 6dc9f25..e69de29 100644
--- a/.trunk/configs/.gitleaksignore
+++ b/.trunk/configs/.gitleaksignore
@@ -1,7 +0,0 @@
-948b6fc9559ec3be24a1200a246044d343efa86c:bouncer/grey-ooo-test.yml:generic-api-key:15
-a1a6c22a080fe58f80183f3737972155fc9c8220:bouncer/grey-ooo-test.yml:generic-api-key:15
-919a1b9eefe9291ab0d174c12eb80008da5dfe94:aio/docker-compose.yml:generic-api-key:15
-2fd5c6207464dba39701548ab5a6339f334418fe:bouncer/grey-ooo-test.yml:generic-api-key:13
-2fd5c6207464dba39701548ab5a6339f334418fe:bouncer/self-signed-certificates/example.key:private-key:1
-1b657b62e8a9036e608e3867cd0da4857f9478ca:php/self-signed-certificates/example.key:private-key:1
-25fd34861ee2e2475b1c64de47e9aa54dea80a0e:php/self-signed-certificates/example.key:private-key:1
diff --git a/.trunk/configs/.hadolint.yaml b/.trunk/configs/.hadolint.yaml
index 1870030..d700141 100644
--- a/.trunk/configs/.hadolint.yaml
+++ b/.trunk/configs/.hadolint.yaml
@@ -1,5 +1,3 @@
 ignored:
   - DL3006
   - DL3008
-  - SC2043
-  - SC2312
diff --git a/.trunk/configs/.markdownlintignore b/.trunk/configs/.markdownlintignore
new file mode 100644
index 0000000..bf789ea
--- /dev/null
+++ b/.trunk/configs/.markdownlintignore
@@ -0,0 +1 @@
+LICENCE.md
diff --git a/.trunk/configs/.shellcheckrc b/.trunk/configs/.shellcheckrc
index 8c7b1ad..8cc03cd 100644
--- a/.trunk/configs/.shellcheckrc
+++ b/.trunk/configs/.shellcheckrc
@@ -1,6 +1,5 @@
 enable=all
 source-path=SCRIPTDIR
-disable=SC2154
 
 # If you're having issues with shellcheck following source, disable the errors via:
 # disable=SC1090
diff --git a/.trunk/configs/.tflint.hcl b/.trunk/configs/.tflint.hcl
new file mode 100644
index 0000000..7488b8c
--- /dev/null
+++ b/.trunk/configs/.tflint.hcl
@@ -0,0 +1,16 @@
+config {
+    format = "compact"
+    module = true
+    plugin_dir = "~/.tflint.d/plugins"
+}
+
+plugin "terraform" {
+    enabled = true
+    preset  = "recommended"
+}
+
+plugin "aws" {
+    enabled = true
+    version = "0.27.0"
+    source  = "github.com/terraform-linters/tflint-ruleset-aws"
+}
diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml
index 5a85c2d..984573e 100644
--- a/.trunk/configs/.yamllint.yaml
+++ b/.trunk/configs/.yamllint.yaml
@@ -1,8 +1,15 @@
----
 extends: relaxed
 rules:
+  quoted-strings:
+    required: only-when-needed
+    extra-allowed: ["{|*}"]
   empty-values:
+    forbid-in-block-mappings: false
+    forbid-in-flow-mappings: false
     ignore:
       - .github/workflows/*.yml
+  key-duplicates: {}
+  octal-values:
+    forbid-implicit-octal: true
   document-start: disable
   line-length: disable
diff --git a/.trunk/configs/svgo.config.js b/.trunk/configs/svgo.config.js
new file mode 100644
index 0000000..b257d13
--- /dev/null
+++ b/.trunk/configs/svgo.config.js
@@ -0,0 +1,14 @@
+module.exports = {
+  plugins: [
+    {
+      name: "preset-default",
+      params: {
+        overrides: {
+          removeViewBox: false, // https://github.com/svg/svgo/issues/1128
+          sortAttrs: true,
+          removeOffCanvasPaths: true,
+        },
+      },
+    },
+  ],
+};
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 372ea1b..e98156c 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -2,14 +2,12 @@
 # To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
 version: 0.1
 cli:
-  version: 1.21.0
-  shell_hooks:
-    enforce: true
+  version: 1.22.1
 # Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
 plugins:
   sources:
     - id: trunk
-      ref: v1.4.5
+      ref: v1.5.0
       uri: https://github.com/trunk-io/plugins
 # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
 runtimes:
@@ -19,179 +17,43 @@ runtimes:
     - python@3.10.8
 # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
 lint:
-  disabled:
-    - terrascan
   enabled:
     - gitleaks@8.18.2
-    - actionlint@1.6.27
-    - checkov@3.2.52
+    - markdownlint@0.40.0
+    - taplo@0.8.1
+    - actionlint@1.7.0
+    - checkov@3.2.92
     - git-diff-check
-    - hadolint@2.12.0
-    - markdownlint@0.39.0
-    - osv-scanner@1.7.0
     - prettier@3.2.5
-    - shellcheck@0.10.0
-    - shfmt@3.6.0
-    - trivy@0.50.1
-    - trufflehog@3.71.0
+    - trivy@0.51.1
+    - trufflehog@3.76.2
     - yamllint@1.35.1
-    - php-cs-fixer@0.0.1
-  ignore:
-    - linters: [markdownlint]
-      paths:
-        - "**/LICENCE.md"
-        - "**/LICENSE.md"
-        - "**/CODE_OF_CONDUCT.md"
   definitions:
-    - name: php-cs-fixer
-      files: [php]
-      commands:
-        - name: lint
-          output: sarif
-          #parse_regex: "((?P<path>.*):(?P<line>\\d+):(?P<col>\\d+): \\[(?P<severity>.*)\\] (?P<message>.*) \\((?P<code>.*)\\))" # matches the parser run output
-          success_codes: [0, 1, 4, 8]
-          cache_results: false
-          run: php-cs-fixer fix --dry-run --format=checkstyle ${target}
-          read_output_from: stdout
-          parser:
-            run: "cs2pr"
-
-      #        - name: format
-      #          output: rewrite
-      #          success_codes: [0]
-      #          run: php-cs-fixer fix -q ${target}
-      #          formatter: true
-      #          batch: true
-
-      direct_configs: [.php-cs-fixer.php, .php-cs-fixer.dist.php]
-      #working_directory: ${root_or_parent_with_direct_config}
-      suggest_if: files_present
-      tools: [php-cs-fixer, cs2pr]
-      version_command:
-        parse_regex: ${semver}
-        run: php-cs-fixer --version
-
+    - name: markdownlint
+      direct_configs:
+        - .markdownlintignore
+        - .markdownlint.yaml
 actions:
+  disabled:
+    - trunk-upgrade-available
   enabled:
     - trunk-announce
     - trunk-check-pre-push
     - trunk-fmt-pre-commit
-    - trunk-upgrade-available
 tools:
-  disabled:
-    - composer
   enabled:
-    - action-validator@0.6.0
-    - php-cs-fixer@0.0.1
-    - cs2pr@0.0.1
+    - tfupdate@0.8.2
+    - phpstan@1.10.58
+    - gh@2.49.2
     - jq@jq-1.7.1
-    - gh@2.47.0
-    - act@0.2.61
-    - terraform@1.7.2
-  definitions:
-    - name: gh
-      download: gh
-      known_good_version: 2.27.0
-      environment:
-        - name: PATH
-          list: ["${tool}/bin"]
-      shims: [gh]
-    - name: composer
-      download: composer
-      known_good_version: 0.0.1
-      environment:
-        - name: PATH
-          list: ["${tool}/bin"]
-      shims: [composer]
-    - name: php-cs-fixer
-      download: php-cs-fixer
-      known_good_version: 0.0.1
-      environment:
-        - name: PATH
-          list: ["${tool}/bin"]
-      shims: [php-cs-fixer]
-    - name: cs2pr
-      download: cs2pr
-      known_good_version: 0.0.1
-      environment:
-        - name: PATH
-          list: ["${tool}/bin"]
-      shims: [cs2pr]
-
-    - name: php-static-cli
-      download: php-static-cli
-      known_good_version: 2.0.1
-      environment:
-        - name: PATH
-          list: ["${tool}/bin"]
-      shims: [spc]
-downloads:
-  - name: gh
-    downloads:
-      - os:
-          linux: linux
-        cpu:
-          x86_64: amd64
-          arm_64: arm64
-        url: https://github.com/cli/cli/releases/download/v${version}/gh_${version}_${os}_${cpu}.tar.gz
-        strip_components: 1
-      - os:
-          windows: windows
-        cpu:
-          x86_64: amd64
-          arm_64: arm64
-        url: https://github.com/cli/cli/releases/download/v${version}/gh_${version}_${os}_${cpu}.zip
-        strip_components: 1
-      # macOS releases since 2.28.0 started using .zip instead of .tar.gz
-      - os:
-          macos: macOS
-        cpu:
-          x86_64: amd64
-          arm_64: arm64
-        url: https://github.com/cli/cli/releases/download/v${version}/gh_${version}_${os}_${cpu}.zip
-        strip_components: 1
-        version: ">=2.28.0"
-      - os:
-          macos: macOS
-        cpu:
-          x86_64: amd64
-          arm_64: arm64
-        url: https://github.com/cli/cli/releases/download/v${version}/gh_${version}_${os}_${cpu}.tar.gz
-        strip_components: 1
-  - name: composer
-    downloads:
-      - os:
-          linux: linux
-          macos: macos
-        cpu:
-          x86_64: x86_64
-          arm_64: arm64
-        url: https://github.com/matthewbaggett/packaged-tooling/releases/download/${version}/composer-8.2-${os}-${cpu}
-  - name: php-cs-fixer
-    downloads:
-      - os:
-          linux: linux
-          macos: macos
-        cpu:
-          x86_64: x86_64
-          arm_64: arm64
-        url: https://github.com/matthewbaggett/packaged-tooling/releases/download/${version}/php-cs-fixer-8.2-${os}-${cpu}
-  - name: cs2pr
-    downloads:
-      - os:
-          linux: linux
-          macos: macos
-        cpu:
-          x86_64: x86_64
-          arm_64: arm64
-        url: https://github.com/matthewbaggett/packaged-tooling/releases/download/${version}/cs2pr-8.2-${os}-${cpu}
-
-  - name: php-static-cli
-    downloads:
-      - os:
-          linux: linux
-          macos: macos
-        cpu:
-          x86_64: x86_64
-          arm_64: aarch64
-        url: https://github.com/crazywhalecc/static-php-cli/releases/download/${version}/spc-${os}-${cpu}.tar.gz
+    - yq@4.44.1
+    - awscli@1.32.107
+    - action-validator@0.6.0
+    - act@0.2.62
+    - shellcheck@0.10.0
+    - hadolint@2.12.0
+    - svgo@3.3.2
+    - tofu@1.7.1
+    - trunk-toolbox@0.3.1
+    - tflint@0.51.1
+    - terraform@1.1.4
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 90e43cb..e0cc98e 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,19 +1,21 @@
+# Code of Conduct
+
 This code of conduct outlines our expectations for participants within the open source community. Anyone who violates this code of conduct may be banned from contributing here.
 
-# Requirements
+## Requirements
 
 - **Be friendly and patient.**
 - **Be welcoming** _We strive to be a community that welcomes and supports people of all backgrounds and identities._
 - **Be respectful** _Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners._
 
-# Unacceptable Behaviour
+## Unacceptable Behaviour
 
 - Offensive comments related to gender, sexual orientation, disability, mental illness, physical appearance, body size, race, age, regional discrimination, political or religious affiliation.
 - Threats of violence, both physical and psycological.
 - Incitement of violence towards any individual, including encouraging a person to commit suicide or to engage in self-harm.
 - Continued communication after requests to cease.
 
-# Interactions
+## Interactions
 
 - Don't just tell somebody they are wrong, or what they have done is wrong. You must always explain what is wrong, and why it is wrong.
 - Don't reject contributions that are partially complete and then go and commit your own version. Try to work with the author to complete their work.
diff --git a/LICENSE.md b/LICENCE.md
similarity index 100%
rename from LICENSE.md
rename to LICENCE.md