diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 95bab5f..ccabc9b 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye
+FROM mcr.microsoft.com/devcontainers/python:3.12-bullseye
 RUN apt-get update && apt-get upgrade -y
 RUN pip install pip-tools invoke
 COPY requirements.in requirements.txt requirements-dev.in requirements-dev.txt constraints.txt tasks.py ./
diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml
index 77ba251..de6941b 100644
--- a/.github/workflows/codeql-analysis.yaml
+++ b/.github/workflows/codeql-analysis.yaml
@@ -40,7 +40,7 @@ jobs:
     - name: Set up Python
       uses: actions/setup-python@v4
       with:
-        python-version: '3.11'
+        python-version: '3.12'
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index a6bc112..7cf98a5 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -17,7 +17,7 @@ jobs:
       - name: Set up Python
         uses: actions/setup-python@v4
         with:
-          python-version: '3.11'
+          python-version: '3.12'
           cache: pip
       - name: Install dependencies
         run: |
diff --git a/.github/workflows/update-dependencies.yaml b/.github/workflows/update-dependencies.yaml
index ad53e37..3ec7e4e 100644
--- a/.github/workflows/update-dependencies.yaml
+++ b/.github/workflows/update-dependencies.yaml
@@ -20,7 +20,7 @@ jobs:
       - name: Set up Python
         uses: actions/setup-python@v4
         with:
-          python-version: '3.11'
+          python-version: '3.12'
           cache: pip
       - name: Update dependencies
         run: |
diff --git a/.rtx.toml b/.rtx.toml
index 1642e12..007b6e1 100644
--- a/.rtx.toml
+++ b/.rtx.toml
@@ -1,5 +1,5 @@
 [tools]
-python = {version="3.11", virtualenv=".venv"}
+python = {version="3.12", virtualenv=".venv"}
 
 [env]
 ENV_FILE = "{{config_root}}/envs/local-envs.env"
diff --git a/constraints.txt b/constraints.txt
index 4db7adc..bc0867a 100644
--- a/constraints.txt
+++ b/constraints.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with Python 3.11
+# This file is autogenerated by pip-compile with Python 3.12
 # by the following command:
 #
 #    pip-compile --allow-unsafe --output-file=constraints.txt --strip-extras requirements.in
@@ -14,14 +14,10 @@ certifi==2023.7.22
     # via
     #   requests
     #   selenium
-cffi==1.16.0
-    # via cryptography
 charset-normalizer==3.3.1
     # via requests
 confusable-homoglyphs==3.2.0
     # via django-registration
-cryptography==41.0.4
-    # via django-anymail
 django==4.2.6
     # via
     #   -r requirements.in
@@ -65,8 +61,6 @@ packaging==23.2
     # via gunicorn
 pillow==10.1.0
     # via -r requirements.in
-pycparser==2.21
-    # via cffi
 pysocks==1.7.1
     # via urllib3
 requests==2.31.0
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 0161661..3b93c72 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with Python 3.11
+# This file is autogenerated by pip-compile with Python 3.12
 # by the following command:
 #
 #    pip-compile --allow-unsafe requirements-dev.in
@@ -14,7 +14,7 @@ attrs==23.1.0
     #   hypothesis
     #   outcome
     #   trio
-black==23.10.0
+black==23.10.1
     # via -r requirements-dev.in
 blessed==1.20.0
     # via curtsies
@@ -194,7 +194,7 @@ urllib3[socks]==2.0.7
     #   -c constraints.txt
     #   requests
     #   selenium
-virtualenv==20.24.5
+virtualenv==20.24.6
     # via pre-commit
 wcwidth==0.2.8
     # via blessed
diff --git a/requirements.txt b/requirements.txt
index 3ebfd3f..f6c6264 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with Python 3.11
+# This file is autogenerated by pip-compile with Python 3.12
 # by the following command:
 #
 #    pip-compile --allow-unsafe requirements.in
@@ -14,14 +14,10 @@ certifi==2023.7.22
     # via
     #   requests
     #   selenium
-cffi==1.16.0
-    # via cryptography
 charset-normalizer==3.3.1
     # via requests
 confusable-homoglyphs==3.2.0
     # via django-registration
-cryptography==41.0.4
-    # via django-anymail
 django==4.2.6
     # via
     #   -r requirements.in
@@ -65,8 +61,6 @@ packaging==23.2
     # via gunicorn
 pillow==10.1.0
     # via -r requirements.in
-pycparser==2.21
-    # via cffi
 pysocks==1.7.1
     # via urllib3
 requests==2.31.0