diff --git a/apps/cli/executables/alma_product_fetch/setup.py b/apps/cli/executables/alma_product_fetch/setup.py
index 4e47c644efb631efa7ca5f704f0f4cfd7a6318f9..16d863191a9ed0def89d4ad1f0089b188b00d1a3 100644
--- a/apps/cli/executables/alma_product_fetch/setup.py
+++ b/apps/cli/executables/alma_product_fetch/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/alma_product_fetch/_version.py').readlines()[-1].split()[-1]
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive ALMA Product Fetcher',
     long_description=README,
diff --git a/apps/cli/executables/alma_reingester/setup.py b/apps/cli/executables/alma_reingester/setup.py
index 5bb5b7593ee937a9145c708962abb67b6cfd1050..01d37ee293b06f9e64a6a194d5cdd9979928d25d 100644
--- a/apps/cli/executables/alma_reingester/setup.py
+++ b/apps/cli/executables/alma_reingester/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/alma_reingester/_version.py').readlines()[-1].split()[-1].st
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive ALMA Reingester',
     long_description=README,
diff --git a/apps/cli/executables/datafetcher/setup.py b/apps/cli/executables/datafetcher/setup.py
index 0da3167676195341f42bd23934f59a0d9d86c6fb..e5784994bc57b8ba55f147c47d19134bd1d0ba10 100644
--- a/apps/cli/executables/datafetcher/setup.py
+++ b/apps/cli/executables/datafetcher/setup.py
@@ -22,7 +22,7 @@ tests_require = [
 ]
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Data Fetcher Script',
     long_description=README,
diff --git a/apps/cli/executables/epilogue/setup.py b/apps/cli/executables/epilogue/setup.py
index 02c96229be89ae431d8b75a8f882eb4c22339807..641609dba80490c369fe89bf032886ae189fd3aa 100644
--- a/apps/cli/executables/epilogue/setup.py
+++ b/apps/cli/executables/epilogue/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/epilogue/_version.py').readlines()[-1].split()[-1].strip("\"
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Job Epilogue Script',
     long_description=README,
diff --git a/apps/cli/executables/ingestion/setup.py b/apps/cli/executables/ingestion/setup.py
index a689b4e90853c9c04224dc2e055b4de614c0dd87..2a90e81ebb8d86dcfc97ebf09f584d01fe83635a 100644
--- a/apps/cli/executables/ingestion/setup.py
+++ b/apps/cli/executables/ingestion/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/ingestion/_version.py').readlines()[-1].split()[-1].strip("\
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Ingestion',
     long_description=README,
diff --git a/apps/cli/executables/null/setup.py b/apps/cli/executables/null/setup.py
index 91b6b575c50c3c08f10dbc16446d91301d71d40c..c7d3294077322e07c1726b495a16a006a10b0aa9 100644
--- a/apps/cli/executables/null/setup.py
+++ b/apps/cli/executables/null/setup.py
@@ -14,7 +14,7 @@ tests_require = [
     'pytest>=5.4,<6.0'
 ]
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='Workspaces null executable.',
     long_description=README,
diff --git a/apps/cli/executables/vlba_grabber/setup.py b/apps/cli/executables/vlba_grabber/setup.py
index 287ab64787dae5858d889da1b4716b4f0fe05aeb..f6b5f801e1084a076ec1a8e24966a51ce47572fc 100644
--- a/apps/cli/executables/vlba_grabber/setup.py
+++ b/apps/cli/executables/vlba_grabber/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/vlba_grabber/_version.py').readlines()[-1].split()[-1].strip
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive VLBA Grabber',
     long_description=README,
diff --git a/apps/cli/executables/weblog_thumbs/setup.py b/apps/cli/executables/weblog_thumbs/setup.py
index d2a34103eeac80b00f36c9357230f4c99fa70a50..1c2d896c13539c61e033f84d92cd03501d4bad09 100644
--- a/apps/cli/executables/weblog_thumbs/setup.py
+++ b/apps/cli/executables/weblog_thumbs/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/weblog_thumbs/_version.py').readlines()[-1].split()[-1].stri
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Weblog Thumbs',
     long_description=README,
diff --git a/apps/cli/launchers/pymygdala/setup.py b/apps/cli/launchers/pymygdala/setup.py
index 27b8db5fcf8ee62d932a165af321ef02d84f1ff3..62dca50fd2180bd867b29b2735dd5ab53ec76abe 100644
--- a/apps/cli/launchers/pymygdala/setup.py
+++ b/apps/cli/launchers/pymygdala/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/pymygdala/_version.py').readlines()[-1].split()[-1].strip("\
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Pymygdala General Message Sender',
     long_description=README,
diff --git a/apps/cli/launchers/wf/setup.py b/apps/cli/launchers/wf/setup.py
index 5e4539f7772b35ec947533333a8ebaba06d4484e..df4b7819d8899382177e9ed38860de1a81cfc289 100644
--- a/apps/cli/launchers/wf/setup.py
+++ b/apps/cli/launchers/wf/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/wf/_version.py').readlines()[-1].split()[-1].strip("\"'")
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Workflow Commands',
     long_description=README,
diff --git a/apps/cli/utilities/datafinder/setup.py b/apps/cli/utilities/datafinder/setup.py
index cb31133e0edeac0a127a72de129c9008bfea0fb9..0c527a77ede638b86532a7429b29dc1501ca213f 100644
--- a/apps/cli/utilities/datafinder/setup.py
+++ b/apps/cli/utilities/datafinder/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/datafinder/_version.py').readlines()[-1].split()[-1].strip("
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Data Finding Tools',
     long_description=README,
diff --git a/apps/cli/utilities/dumplogs/setup.py b/apps/cli/utilities/dumplogs/setup.py
index 74663608b7e7404a62484f422fb2f21ea0bdeee1..88cf73df693c3d72763c1ff66e3478b6d8d0ce00 100644
--- a/apps/cli/utilities/dumplogs/setup.py
+++ b/apps/cli/utilities/dumplogs/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/dumplogs/_version.py').readlines()[-1].split()[-1].strip("\"
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Dumplogs',
     long_description=README,
diff --git a/apps/cli/utilities/faultchecker/setup.py b/apps/cli/utilities/faultchecker/setup.py
index f3ff21842083992bc9151677adb8d3b0c1285243..6145260d24c3ace3776e23053590ec35e96c4bef 100644
--- a/apps/cli/utilities/faultchecker/setup.py
+++ b/apps/cli/utilities/faultchecker/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/faultchecker/_version.py').readlines()[-1].split()[-1].strip
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Fault Checker',
     long_description=README,
diff --git a/apps/cli/utilities/mr_books/setup.py b/apps/cli/utilities/mr_books/setup.py
index e6550e31c21b5724d9ecfdf745f7208988b5f1ec..ab8b97f85b4d64d2089ea59ff915ae2078ab5516 100644
--- a/apps/cli/utilities/mr_books/setup.py
+++ b/apps/cli/utilities/mr_books/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/mr_books/_version.py').readlines()[-1].split()[-1].strip("\"
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive mr_books',
     long_description=README,
diff --git a/apps/cli/utilities/mr_clean/setup.py b/apps/cli/utilities/mr_clean/setup.py
index bd0f57bd6c0471eecaf4b25e0134ab5fbc6d72b5..65945b49271e0fdc9fa175d227833cf93e218c43 100644
--- a/apps/cli/utilities/mr_clean/setup.py
+++ b/apps/cli/utilities/mr_clean/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/mr_clean/_version.py').readlines()[-1].split()[-1].strip("\"
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive mr_clean',
     long_description=README,
diff --git a/apps/cli/utilities/proprietary_setter/setup.py b/apps/cli/utilities/proprietary_setter/setup.py
index e63875be644d35a19b83f6e650ac3b529141803f..66397d214725cf34116821fba63d2a956ed63c0f 100644
--- a/apps/cli/utilities/proprietary_setter/setup.py
+++ b/apps/cli/utilities/proprietary_setter/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/proprietary_setter/_version.py').readlines()[-1].split()[-1]
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Proprietary Time Setter',
     long_description=README,
diff --git a/apps/cli/utilities/qa_results/setup.py b/apps/cli/utilities/qa_results/setup.py
index d5ecaf926f5f04a3652f8bb5e90d206095d1d757..1750c6d10b122e7f35417e75d675e72e2170f610 100644
--- a/apps/cli/utilities/qa_results/setup.py
+++ b/apps/cli/utilities/qa_results/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/qa_results/_version.py').readlines()[-1].split()[-1].strip("
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Quality Assurance Pass/Fail Scripts',
     long_description=README,
diff --git a/apps/cli/utilities/s_code_project_updater/setup.py b/apps/cli/utilities/s_code_project_updater/setup.py
index 3fb55970f3eb2930f568d43280c4847b6a7cf0d5..9aa45572a805d200f2ef671897bc0bfc94633a6a 100644
--- a/apps/cli/utilities/s_code_project_updater/setup.py
+++ b/apps/cli/utilities/s_code_project_updater/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/s_code_project_updater/_version.py').readlines()[-1].split()
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive S-Code Project Updater',
     long_description=README,
diff --git a/apps/cli/utilities/wf_monitor/setup.py b/apps/cli/utilities/wf_monitor/setup.py
index 86da440095ebee75ad9003a8c85cc1f586583160..e93572288ebb76202b432991d9aeff3f933d00e0 100644
--- a/apps/cli/utilities/wf_monitor/setup.py
+++ b/apps/cli/utilities/wf_monitor/setup.py
@@ -10,6 +10,8 @@ README = Path('README.md').read_text()
 requires = [
     'pika==1.1',
     'pendulum==2.1.2',
+    'ssa-workspaces',
+    'ssa-channels'
 ]
 tests_require = [
     'pytest>=5.4,<6.0',
@@ -17,7 +19,7 @@ tests_require = [
 ]
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='Workflow monitor that reads in HTCondor logs and translates them into AMQP events',
     long_description=README,
diff --git a/apps/cli/utilities/wf_monitor/src/wf_monitor/monitor.py b/apps/cli/utilities/wf_monitor/src/wf_monitor/monitor.py
index bd3a7073a49b7ee146f33ed316909dd50e08360f..bf3fdad02fe9ec6aaaf621c97a56cf42cff9dc3a 100644
--- a/apps/cli/utilities/wf_monitor/src/wf_monitor/monitor.py
+++ b/apps/cli/utilities/wf_monitor/src/wf_monitor/monitor.py
@@ -10,13 +10,11 @@ import tracemalloc
 from typing import List, Union, Dict, Callable, Tuple, Any
 from pathlib import Path
 
-import pika
 import pendulum
-import workspaces
-from pycapo import CapoConfig
 
-from workspaces.schema import WorkflowEvent, WorkflowEventType
 from ._version import ___version___ as VERSION
+from channels.amqp_helpers import make_amqp_connection, configure_amqp_channel, emit_amqp_message
+from workspaces.schema import WorkflowEvent, WorkflowEventType
 
 WORKFLOW_STATUS_EXCH = 'workspaces.workflow-service.workflow-status'
 
@@ -237,51 +235,27 @@ def make_arg_parser() -> argparse.ArgumentParser:
     return parser
 
 
-@log_decorator_factory('Establishing connection to the AMQP server...')
-def make_amqp_connection(profile: str) -> pika.BlockingConnection:
-    """
-    Initialize connection to AMQP server
-    :param profile: Capo profile to use
-    :return: Established connection
-    """
-    capo_cfg = CapoConfig(profile=profile)
-
-    hostname = capo_cfg.getstring('edu.nrao.archive.configuration.AmqpServer.hostname')
-    username = capo_cfg.getstring('edu.nrao.archive.configuration.AmqpServer.username')
-    password = capo_cfg.getstring('edu.nrao.archive.configuration.AmqpServer.password')
-
-    return pika.BlockingConnection(
-        pika.ConnectionParameters(
-            hostname,
-            credentials=pika.PlainCredentials(
-                username,
-                password
-            )
-        )
-    )
-
-
-@log_decorator_factory('Sending event data to the channel...')
-def send_event_data(connection: pika.BlockingConnection, event: WorkflowEvent):
-    """
-    Takes in a JSON-formatted string and sends it off to the workflow status exchange
-    :param event: JSON string of event metadata
-    """
-    # Send data to exchange
-    channel = connection.channel()
-    channel.exchange_declare(WORKFLOW_STATUS_EXCH, 'topic', durable=True)
-    return channel.basic_publish(
-        exchange=WORKFLOW_STATUS_EXCH,
-        routing_key=f'{event.job_name}.{event.job_id}.{event.type.name.lower()}',
-        body=workspaces.json.workflow_event.dump(event)
-    )
-
-
 def main():
     # Parse command-line args
     args = make_arg_parser().parse_args()
-    connection = make_amqp_connection(args.profile)
     monitor = WorkflowMonitor(args.log_path)
 
-    for event in monitor.events:
-        send_event_data(connection, event)
+    # Probably want to refactor this so that it doesn't create its own connection just for this,
+    # since creating connections is expensive
+    decorated_connect = log_decorator_factory('Making connection...')(make_amqp_connection)
+    decorated_config_channel = log_decorator_factory('Configuring channel...')(configure_amqp_channel)
+    decorated_emit = log_decorator_factory('Emitting message...')(emit_amqp_message)
+
+    with decorated_connect(args.profile) as connection:
+        with decorated_config_channel(
+            connection=connection,
+            exchange=WORKFLOW_STATUS_EXCH,
+            exchange_type='topic'
+        ) as channel:
+            for event in monitor.events:
+                decorated_emit(
+                    channel=channel,
+                    exchange=WORKFLOW_STATUS_EXCH,
+                    routing_key=f'{event.job_name}.{event.job_id}.{event.type.name.lower()}',
+                    msg=event.json()
+                )
diff --git a/apps/cli/utilities/wf_monitor/test/test_wf_monitor.py b/apps/cli/utilities/wf_monitor/test/test_wf_monitor.py
index 2fe39cb990466c8f513be600644001a4ac829754..7f0cf4e95f759e937f9389be4d51abdc52cf0b36 100644
--- a/apps/cli/utilities/wf_monitor/test/test_wf_monitor.py
+++ b/apps/cli/utilities/wf_monitor/test/test_wf_monitor.py
@@ -1,9 +1,13 @@
 import pytest
-from wf_monitor.wf_event import EventType
-from wf_monitor.monitor import WorkflowMonitor, send_event_data, make_amqp_connection
+from pytest_mock import MockerFixture
+
+from workspaces.schema import WorkflowEventType
+from wf_monitor.monitor import WorkflowMonitor
+from channels.amqp_helpers import make_amqp_connection, configure_amqp_channel, emit_amqp_message
 
 log_path = 'logs/condor.log'
 test_monitor = WorkflowMonitor(log_path)
+WORKFLOW_STATUS_EXCH = 'workspaces.workflow-service.workflow-status'
 
 
 def test_read_log():
@@ -27,14 +31,14 @@ def test_read_log_timeout(capsys):
 
 def test_parse_log():
     test_event_types = [
-        EventType.SUBMITTED,
-        EventType.EXECUTING,
-        EventType.OTHER,
-        EventType.TERMINATED,
-        EventType.SUBMITTED,
-        EventType.EXECUTING,
-        EventType.OTHER,
-        EventType.TERMINATED
+        WorkflowEventType.SUBMITTED,
+        WorkflowEventType.EXECUTING,
+        WorkflowEventType.OTHER,
+        WorkflowEventType.TERMINATED,
+        WorkflowEventType.SUBMITTED,
+        WorkflowEventType.EXECUTING,
+        WorkflowEventType.OTHER,
+        WorkflowEventType.TERMINATED
     ]
     for e, e_type in zip(test_monitor.events, test_event_types):
         assert e.type == e_type
@@ -46,16 +50,26 @@ def test_parse_log_error():
     assert val_err.type == ValueError
 
 
-def test_send_event_data(mocker):
+def test_monitor_events(mocker: MockerFixture):
     mock_list = [
         'pika.adapters.blocking_connection.BlockingChannel.basic_publish',
-        'wf_monitor.monitor.make_amqp_connection',
-        'wf_monitor.monitor.send_event_data',
+        'channels.amqp_helpers.make_amqp_connection',
+        'channels.amqp_helpers.configure_amqp_channel',
+        'channels.amqp_helpers.emit_amqp_message',
     ]
     [mocker.patch(mock) for mock in mock_list]
 
-    connection = make_amqp_connection('nmtest')
-
-    for event in WorkflowMonitor(log_path).events:
-        send_event_data(connection, event)
-    assert connection.channel().basic_publish.call_count == 8
+    with make_amqp_connection('nmtest') as connection:
+        with configure_amqp_channel(
+                connection=connection,
+                exchange=WORKFLOW_STATUS_EXCH,
+                exchange_type='topic'
+        ) as channel:
+            for event in WorkflowMonitor(log_path).events:
+                emit_amqp_message(
+                    channel=channel,
+                    exchange=WORKFLOW_STATUS_EXCH,
+                    routing_key=f'{event.job_name}.{event.job_id}.{event.type.name.lower()}',
+                    msg=event
+                )
+            assert channel.basic_publish.call_count == 8
diff --git a/environment.yml b/environment.yml
index db6fd6093cd09a0f0379c6a00aa8b1f90fa6f718..6bb290b866b1d2ee388b556fe97bac1a35d5a3d0 100644
--- a/environment.yml
+++ b/environment.yml
@@ -32,6 +32,7 @@ dependencies:
   - pytest=5.4
   - python=3.8
   - requests=2.23
+  - scp=0.13
   - simplejson=3.17
   - sqlalchemy=1.3
   - tqdm=4.46
diff --git a/services/archive/setup.py b/services/archive/setup.py
index 555b4fd0221b90ffe2b8f6a05d86e23fef1e296b..f4bdad5d46b61ee1aeade38379984e804fa62ee9 100644
--- a/services/archive/setup.py
+++ b/services/archive/setup.py
@@ -50,7 +50,7 @@ requires = [
 ]
 
 setup(
-    name=this_module,
+    name='ssa-' + this_module,
 
     # Versions should comply with PEP440.  For a discussion on single-sourcing
     # the version across setup.py and the project code, see
diff --git a/services/workflow/setup.py b/services/workflow/setup.py
index 35e161cca2b241e72b0550cf09245d10a4c09b96..71f6c4bb0943be573fed881cd04f989cb76865fb 100644
--- a/services/workflow/setup.py
+++ b/services/workflow/setup.py
@@ -51,7 +51,7 @@ requires = [
 ]
 
 setup(
-    name=this_module,
+    name='ssa-' + this_module,
 
     # Versions should comply with PEP440.  For a discussion on single-sourcing
     # the version across setup.py and the project code, see
diff --git a/shared/channels/README.md b/shared/channels/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ae2729b2b2dbb272c11ae5106f41807f26ef8478
--- /dev/null
+++ b/shared/channels/README.md
@@ -0,0 +1 @@
+Area for AMQP helper functions. May be expanded in the future to include other AMQP utilities.
\ No newline at end of file
diff --git a/shared/channels/setup.py b/shared/channels/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..f61589e38bfcb4f113da70b9dd07232a6b246fb7
--- /dev/null
+++ b/shared/channels/setup.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pathlib import Path
+from setuptools import setup, find_packages
+
+VERSION = open('src/channels/_version.py').readlines()[-1].split()[-1].strip("\"'")
+README = Path('README.md').read_text()
+
+setup(
+    name='ssa-' + Path().absolute().name,
+    version=VERSION,
+    description='Workspaces AMQP utility area',
+    long_description=README,
+    author='NRAO SSA Team',
+    author_email='dms-ssa@nrao.edu',
+    url='TBD',
+    license="GPL",
+    install_requires=['pika', 'pycapo'],
+    keywords=[],
+    packages=['channels'],
+    package_dir={'':'src'},
+    classifiers=[
+        'Programming Language :: Python :: 3.8'
+    ]
+)
diff --git a/shared/channels/src/channels/__init__.py b/shared/channels/src/channels/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/shared/channels/src/channels/_version.py b/shared/channels/src/channels/_version.py
new file mode 100644
index 0000000000000000000000000000000000000000..f27d146a3f39885ce269bacf9ab4510254147c8d
--- /dev/null
+++ b/shared/channels/src/channels/_version.py
@@ -0,0 +1,2 @@
+""" Version information for this package, don't put anything else here. """
+___version___ = '4.0.0a1.dev1'
diff --git a/shared/channels/amqp_helpers.py b/shared/channels/src/channels/amqp_helpers.py
similarity index 100%
rename from shared/channels/amqp_helpers.py
rename to shared/channels/src/channels/amqp_helpers.py
diff --git a/shared/messaging/events/setup.py b/shared/messaging/events/setup.py
index f866cf79a01c30a364a5e8bdd48f26bad063a77a..26bd7ea4a4a38fb46961f9a69a50850f93157c77 100644
--- a/shared/messaging/events/setup.py
+++ b/shared/messaging/events/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/events/_version.py').readlines()[-1].split()[-1].strip("\"'"
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Event Library',
     long_description=README,
diff --git a/shared/schema/setup.py b/shared/schema/setup.py
index e16ee2a511ea62e595a7e837b9c68a2fc0a2ac68..ffd4a09d8e3a66d36de6edac8e51a9000c2c973c 100644
--- a/shared/schema/setup.py
+++ b/shared/schema/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/schema/_version.py').readlines()[-1].split()[-1].strip("\"'"
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Schema Library',
     long_description=README,
diff --git a/shared/support/setup.py b/shared/support/setup.py
index c0604ed3f00da344b7cbdec44e69d9ee7db5711e..ce47e54ecdce208b5d6ec3e6f0629f98c3d9b051 100644
--- a/shared/support/setup.py
+++ b/shared/support/setup.py
@@ -8,7 +8,7 @@ VERSION = open('src/support/_version.py').readlines()[-1].split()[-1].strip("\"'
 README = Path('README.md').read_text()
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='NRAO Archive Python Support Library',
     long_description=README,
diff --git a/shared/workspaces/setup.py b/shared/workspaces/setup.py
index 9747766b3bb10366d8c91226658cd836ee6d949f..c91c712d85e2a22bece790c99fd167bde7f4b40f 100644
--- a/shared/workspaces/setup.py
+++ b/shared/workspaces/setup.py
@@ -10,7 +10,7 @@ README = Path('README.md').read_text()
 requires = [
     'pycapo',
     'marshmallow',
-    'schema',
+    'ssa-schema',
     'sqlalchemy',
 ]
 tests_require = [
@@ -18,7 +18,7 @@ tests_require = [
 ]
 
 setup(
-    name=Path().absolute().name,
+    name='ssa-' + Path().absolute().name,
     version=VERSION,
     description='Workspaces support library',
     long_description=README,