diff --git a/build-binary.py b/build-binary.py
index f65560635a9c69a855d426fd13a0f346134a58a2..6dd281d5d69f3c8c5bd04d99124be7964fe6571c 100755
--- a/build-binary.py
+++ b/build-binary.py
@@ -40,6 +40,9 @@ def main():
     build_windows(tool, versions)
     package_windows(tool, versions)
 
+    build_macos(tool, versions)
+    package_macos(tool, versions)
+
 
 def get_repo_dir(versions):
     # This needs to be always the same path, otherwise it breaks reproducibility
@@ -137,7 +140,13 @@ def build_windows(tool, versions):
     build_desktop_arch(tool, versions, 'windows', 'x86_64', 'amd64')
 
 
-def build_desktop_arch(tool, versions, platform, arch, goarch, goarm=None):
+def build_macos(tool, versions):
+    os.mkdir(get_platform_output_dir(tool, 'macos'))
+    build_desktop_arch(tool, versions, 'darwin', 'x86_64', 'amd64', output_name = 'macos')
+    build_desktop_arch(tool, versions, 'darwin', 'aarch64', 'arm64', output_name = 'macos')
+
+
+def build_desktop_arch(tool, versions, platform, arch, goarch, goarm=None, output_name=None):
     env = os.environ.copy()
     env['CGO_ENABLED'] = "0"
     env['GOOS'] = platform
@@ -145,8 +154,10 @@ def build_desktop_arch(tool, versions, platform, arch, goarch, goarm=None):
     if goarm: env['GOARM'] = goarm
     build_path = os.path.join('.', versions['build_path'])
 
-    print("Building %s for %s %s" % (tool, platform, arch))
-    output_dir = get_platform_output_dir(tool, platform)
+    if not output_name: output_name = platform
+
+    print("Building %s for %s %s" % (tool, output_name, arch))
+    output_dir = get_platform_output_dir(tool, output_name)
     arch_dir = os.path.join(output_dir, arch)
     os.mkdir(arch_dir)
     extension = '.exe' if platform == 'windows' else ''
@@ -186,6 +197,15 @@ def package_windows(tool, versions):
     package(tool, versions, file_list, 'windows')
 
 
+def package_macos(tool, versions):
+    output_dir = get_platform_output_dir(tool, 'macos')
+    file_list = [
+        os.path.join(output_dir, 'aarch64', tool),
+        os.path.join(output_dir, 'x86_64', tool),
+    ]
+    package(tool, versions, file_list, 'macos')
+
+
 def package(tool, versions, file_list, platform):
     zip_file = get_final_file_path(tool, versions, platform)
     zip_files(file_list, zip_file, versions)
diff --git a/install.sh b/install.sh
index 82dd84d2050eef6e1d803bdb33cc8a2a61ee816f..29e43b7c943217b2de4f0b7873b28b8eed7dd311 100755
--- a/install.sh
+++ b/install.sh
@@ -3,7 +3,7 @@ set -e
 set -x
 
 # use snapshot repos for deterministic package versions
-DATE="20230209T000000Z"
+DATE="20230509T000000Z"
 cat << EOF > /etc/apt/sources.list
 deb http://snapshot.debian.org/archive/debian/${DATE}/ bullseye main
 deb http://snapshot.debian.org/archive/debian/${DATE}/ bullseye-updates main
diff --git a/template-obfs4proxy-macos.pom b/template-obfs4proxy-macos.pom
new file mode 100644
index 0000000000000000000000000000000000000000..b02f3e4dbfae2be0f1c1bb26fd83787ddd6279ed
--- /dev/null
+++ b/template-obfs4proxy-macos.pom
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.briarproject</groupId>
+  <artifactId>obfs4proxy-macos</artifactId>
+  <name>obfs4proxy-macos</name>
+  <version>VERSION</version>
+  <url>https://torproject.org</url>
+  <description>Repo for building obfs4proxy for macOS.</description>
+  <licenses>
+   <license>
+     <name>BSD-3-clause</name>
+     <url>https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/obfs4/-/blob/main/LICENSE</url>
+   </license>
+  </licenses>
+  <developers>
+    <developer>
+      <id>yawning</id>
+      <name>Yawning Angel</name>
+      <email>yawning at torproject dot org</email>
+    </developer>
+    <developer>
+      <id>torproject</id>
+      <name>Tor Project</name>
+      <email>frontdesk@rt.torproject.org</email>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/obfs4.git</connection>
+    <developerConnection>scm:git@gitlab.torproject.org:tpo/anti-censorship/pluggable-transports/obfs4.git</developerConnection>
+    <url>scm:https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/obfs4.git</url>
+  </scm>
+</project>
diff --git a/template-snowflake-macos.pom b/template-snowflake-macos.pom
new file mode 100644
index 0000000000000000000000000000000000000000..9c1625d45bc11536a776c78ee26411cf5d8d2640
--- /dev/null
+++ b/template-snowflake-macos.pom
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.briarproject</groupId>
+  <artifactId>snowflake-macos</artifactId>
+  <name>snowflake-macos</name>
+  <version>VERSION</version>
+  <url>https://torproject.org</url>
+  <description>Repo for building snowflake for macOS.</description>
+  <licenses>
+   <license>
+     <name>BSD-3-clause</name>
+     <url>https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/blob/main/LICENSE</url>
+   </license>
+  </licenses>
+  <developers>
+    <developer>
+      <id>torproject</id>
+      <name>Tor Project</name>
+      <email>frontdesk@rt.torproject.org</email>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git</connection>
+    <developerConnection>scm:git@gitlab.torproject.org:tpo/anti-censorship/pluggable-transports/snowflake.git</developerConnection>
+    <url>scm:https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git</url>
+  </scm>
+</project>
diff --git a/verify-binary.py b/verify-binary.py
index 283f04df4feedf055b429ebfefb9374f80b6408a..4829c125a20fa837c7243a2f0f8e02c71808c9a9 100755
--- a/verify-binary.py
+++ b/verify-binary.py
@@ -14,7 +14,8 @@ def main():
     verified_android = verify(tool, command_line_version, 'android')
     verified_linux = verify(tool, command_line_version, 'linux')
     verified_windows = verify(tool, command_line_version, 'windows')
-    if verified_android and verified_linux and verified_windows:
+    verified_macos = verify(tool, command_line_version, 'macos')
+    if verified_android and verified_linux and verified_windows and verified_macos:
         sys.exit(0)
     else:
         sys.exit(1)