diff --git a/docs/401/401.3.rst b/docs/401/401.3.rst
index 240a440..3747afd 100644
--- a/docs/401/401.3.rst
+++ b/docs/401/401.3.rst
@@ -6,7 +6,6 @@
 Learning Objectives
 -------------------
 
-
 --------------
 Lab Components
 --------------
@@ -25,41 +24,59 @@ Overview
 We have been asked to deploy a SaaS application called Board Effect. The
 service is already an InCommon member and honors an `eduPersonEntitlement`
 for "front door" access. Permission management within the application is
-centered around "work rooms".  Each work room provide access to specific
-documents, chat, mailing lists, etc.  The system will be used by trustees,
+centered around "work rooms". Each work room provide access to specific
+documents, chat, mailing lists, etc. The system will be used by trustees,
 executives, and various committee members.
 
 Thankfully the service is an InCommon member and using `eduPersonEntitlement`
-values.  However, it turns out users still need to have accounts provisioned
-in order to get access. We will need two different kinds of policy groups.
-The first, the account policy group, will be mapped to an `eduPersonEntitlement`
-value and also be used for provisioning accounts.  The second type,
-authorization groups, will provide subject to role mapping, and are mapped
-to work rooms created in Board Effect. This is an example of access control
-model 3 described in the `Grouper Deployment Guide`_.
-
-----------------
-Exercise 401.3.1
-----------------
+values. However, it turns out users still need to have accounts provisioned
+ahead of time in order to get access. We will need two different kinds of
+policy groups. The first, the account policy group, will be mapped to an
+`eduPersonEntitlement` value and also be used for provisioning accounts. The
+second type, authorization groups, will provide subject to role mapping, and
+are mapped to work rooms created in Board Effect. This is an example of access
+control model 3 described in the `Grouper Deployment Guide`_.
+
+------------------------------------------------------------
+Exercise 401.3.1 Create application policy folder and groups
+------------------------------------------------------------
+
+#. Use the application template and the policy group template to create a new
+   `board_effect` application folder and policy group called
+   `board_effect_access`.
+
+.. figure:: ../figures/401-board-effect-app.png
+
+---------------------------------------------------
+Exercise 401.3.2 Create policy groups for workrooms
+---------------------------------------------------
+
+Membership in a Board Effect Workroom provides access to a number of features
+and content within Board Effect. A Workroom is essentially an authorization
+group. Workroom membership can be updated via a REST API provided by Board
+Effect. Grouper policy groups will be mapped to Board Effect workrooms and used
+to provision membership updates.
 
-*Create a application policy folder and groups*
+A new workroom call Committee on Finance has been created in Board Effect.
+Create an authorization policy group in grouper and configure provisioning.
 
-Rather than create the basic structure manually, use a
-:ref:`GSH script <apdx-401.3.1-app-skeleton>`.
+#. Using the policy template create
+   `app:board_effect:service:policy:workroom_finance|allow|deny`.
 
+#. Add `workroom_finance` to `board_effect_access`
 
-----------------
-Exercise 401.3.2
-----------------
+.. figure:: ../figures/401-board-effect-workroom.png
 
-*Workrooms (i.e. authorization groups) can be updated via the Board Effect
-REST API.  Create Grouper authorization groups to manage those.*
+----------------------------------------------------
+Exercise 401.3.3 Configure the Grouper ESB Connector
+----------------------------------------------------
 
-A new workroom call Committee on Finance has been created in Board Effect.
-Need to create authorization group in grouper and configure provisioning.
+The `Grouper ESB Connector`_ is designed to enable Grouper to interface with an
+ESB in order to send and receive individual events as changes occur. We'll use
+the ESB Connector to send messages to rabbitMQ for provisioning the workroom
+memberships.
 
-#. Create `app:boardeffect:wr_cmt_fin_authorized|allow|deny`.
-#. Configure grouperESB to send membership changes to rabbitMQ exchange.
+#. The following has already been configured for you.
 
    .. literalinclude:: examples/401.3.2-grouper-loader.properties
         :language: properties
@@ -73,24 +90,33 @@ Need to create authorization group in grouper and configure provisioning.
         :caption: grouper.client.properties
         :linenos:
 
-#. Write provisioner component to read rabbitMQ and update BoardEffect via REST API.
+2. Write provisioner component to read rabbitMQ and update BoardEffect via REST
+   API.
 
    .. note::
 
-        This step is what logically should happen next to process the messages.
-        You aren't expected to actually accomplish this step during the lab.
+        We will not actually accomplish this step during the lab. Instead, let's
+        make sure our messages are making their way to rabbitMQ.
 
-----------------
-Exercise 401.3.3
-----------------
+3. Log in to http://localhost:15672/ as username `guest`, password `guest`.
+4. Select the `Queues` tab, and then click on the queue named `grouper`
+5. Scoll down and click on `Get Message(s)` and review the message.
+
+.. figure:: ../figures/401-board-effect-rabbitmq.png
+
+------------------------------------------------------------------------
+Exercise 401.3.4 Configure account provisioning and eduPersonEntitlement
+------------------------------------------------------------------------
 
-*Board Effect account provisioning*
+All access to Board Effect is predicated on the presenence of an
+eduPersonEntitlement value, and an account within Board Effect. We will use the
+`board_effect_access` policy group to both control the eduPersonEntitlement
+value and also provision the account to Board Effect via rabbitMQ.
 
-#. Create `app:boardeffect:boardeffect_authorized`.
-#. Add `...:wr_cmt_fin_authorized` to `boardeffect_authorized_allow`.
 #. Configure PSPNG to write `eduPersonEntitlement` value
-   **https://college.boardeffect.com/** to LDAP and release via Shibboleth only
-   for Boardeffect.
+   **https://college.boardeffect.com/** to LDAP. This value will only be
+   released via the Shibboleth IdP for the Boardeffect SP. The following is
+   already configured for you.
 
    .. literalinclude:: examples/401.3.2-grouper-loader.properties
         :language: properties
@@ -99,29 +125,38 @@ Exercise 401.3.3
         :caption: grouper-loader.properties
         :linenos:
 
-Subject to role mapping in place and provisioners working, but how do we get
-reference groups for committees? Ann in President’s Office knows.
+Subject to workroom mapping is now in place and the account and workroom
+provisioners are working! But how do we get reference groups for committees?
+Ann in President’s Office knows.
 
-----------------
-Exercise 401.3.4
-----------------
+-------------------------------------------------------
+Exercise 401.3.5 Distributed Reference Group Management
+-------------------------------------------------------
+
+Ann currently maintains list of committee members by hand. Instead, she can use
+a Grouper reference group.
+
+#. Create `app:board_effect:service:ref:finance_committee`.
+
+#. Give Ann admin access to `app:boardeffect:ref` by adding account
+   **amartinez410** to `app:board_effect:security:board_effectAdmins`.
+
+.. figure:: ../figures/401-board-effect-ann-privs.png
 
-*Distributed Reference Group Management*
+#. Add `finance_committee` to `workroom_finance_allow`.
 
-Amy maintains list of committee members. Use these to build application specific
-reference groups.
+.. figure:: ../figures/401-board-effect-finance-committee.png
 
-#. Create `app:boardeffect:ref:cmt_fin`.
-#. Add `...:ref:cmt_fin` to `...:wr_cmt_fin_allow`.
-#. Add `ref:global_deny` to `...:wr_cmt_fin_deny`.
-#. Give Ann admin access to `app:boardeffect:ref` by adding account 
-   **amartinez410** to `app:boardeffect:etc:boardeffect_admins`.
+#. In a private browser, log in as Ann Martinez (username `amartinez410`,
+   password `password`). Under *My Groups* you should see the reference groups
+   and policies Ann can manage.
 
-Log in as Ann Martinez (**amartinez410**).  Under *My Groups* you should see
-the reference groups and policies Ann can manage.
+.. figure:: ../figures/401-board-effect-my-groups.png
+
+#. Add `ksmith3` to the `finance_committee` group.
 
 ----------------
-Exercise 401.3.5
+Exercise 401.3.6
 ----------------
 
 *Committee member helpers*
@@ -153,7 +188,7 @@ are kept up to date via Grouper provisioners.  We could create workrooms
 automatically based on policy group creation-- exercise left to student at home.
 
 ----------------
-Exercise 401.3.6
+Exercise 401.3.7
 ----------------
 
 *Anna's Grouper Privileges*
@@ -174,7 +209,7 @@ This is better, but does Anna really need full admin privileges to
 
 
 ----------------
-Exercise 401.3.7
+Exercise 401.3.8
 ----------------
 
 *Global Committee reference groups*
@@ -222,3 +257,4 @@ The End
 
 
 .. _Grouper Deployment Guide: https://spaces.at.internet2.edu/display/Grouper/Grouper+Deployment+Guide+Work+-TIER+Program
+.. _`Grouper ESB Connector`: https://spaces.at.internet2.edu/display/Grouper/Grouper+ESB+Connector
diff --git a/docs/401/examples/401.3.2-grouper-loader.properties b/docs/401/examples/401.3.2-grouper-loader.properties
index 45f2b18..c9b2e21 100644
--- a/docs/401/examples/401.3.2-grouper-loader.properties
+++ b/docs/401/examples/401.3.2-grouper-loader.properties
@@ -94,7 +94,7 @@ changeLog.consumer.pspng_entitlements.type = edu.internet2.middleware.grouper.ps
 changeLog.consumer.pspng_entitlements.quartzCron = 0 * * * * ?
 changeLog.consumer.pspng_entitlements.ldapPoolName = demo
 changeLog.consumer.pspng_entitlements.provisionedAttributeName = eduPersonEntitlement
-changeLog.consumer.pspng_entitlements.provisionedAttributeValueFormat = ${group.name.equalsIgnoreCase('app:mfa:mfa_enabled') ? 'http://tier.internet2.edu/mfa/enabled' : (group.name.equalsIgnoreCase('app:boardeffect:boardeffect_authorized') ? 'https://college.boardeffect.com/' : 'urn:mace:example.edu:' + group.extension) }
+changeLog.consumer.pspng_entitlements.provisionedAttributeValueFormat = ${group.name.equalsIgnoreCase('app:mfa:mfa_enabled') ? 'http://tier.internet2.edu/mfa/enabled' : (group.name.equalsIgnoreCase('app:board_effect:service:policy:board_effect_access') ? 'https://college.boardeffect.com/' : 'urn:mace:example.edu:' + group.extension) }
 changeLog.consumer.pspng_entitlements.userSearchBaseDn = ou=people,dc=internet2,dc=edu
 changeLog.consumer.pspng_entitlements.userSearchFilter = uid=${subject.id}
 changeLog.consumer.pspng_entitlements.allProvisionedValuesPrefix=*
diff --git a/docs/figures/401-board-effect-ann-privs.png b/docs/figures/401-board-effect-ann-privs.png
new file mode 100644
index 0000000..f9f50cf
Binary files /dev/null and b/docs/figures/401-board-effect-ann-privs.png differ
diff --git a/docs/figures/401-board-effect-app.png b/docs/figures/401-board-effect-app.png
new file mode 100644
index 0000000..cd778f3
Binary files /dev/null and b/docs/figures/401-board-effect-app.png differ
diff --git a/docs/figures/401-board-effect-finance-committee.png b/docs/figures/401-board-effect-finance-committee.png
new file mode 100644
index 0000000..2e901a4
Binary files /dev/null and b/docs/figures/401-board-effect-finance-committee.png differ
diff --git a/docs/figures/401-board-effect-my-groups.png b/docs/figures/401-board-effect-my-groups.png
new file mode 100644
index 0000000..2c94de5
Binary files /dev/null and b/docs/figures/401-board-effect-my-groups.png differ
diff --git a/docs/figures/401-board-effect-rabbitmq.png b/docs/figures/401-board-effect-rabbitmq.png
new file mode 100644
index 0000000..8782eb1
Binary files /dev/null and b/docs/figures/401-board-effect-rabbitmq.png differ
diff --git a/docs/figures/401-board-effect-workroom.png b/docs/figures/401-board-effect-workroom.png
new file mode 100644
index 0000000..f7f1edd
Binary files /dev/null and b/docs/figures/401-board-effect-workroom.png differ
diff --git a/ex401/ex401.1.1/container_files/grouper-loader.properties b/ex401/ex401.1.1/container_files/grouper-loader.properties
index 3887673..5144557 100644
--- a/ex401/ex401.1.1/container_files/grouper-loader.properties
+++ b/ex401/ex401.1.1/container_files/grouper-loader.properties
@@ -94,7 +94,7 @@ changeLog.consumer.pspng_entitlements.type = edu.internet2.middleware.grouper.ps
 changeLog.consumer.pspng_entitlements.quartzCron = 0 * * * * ?
 changeLog.consumer.pspng_entitlements.ldapPoolName = demo
 changeLog.consumer.pspng_entitlements.provisionedAttributeName = eduPersonEntitlement
-changeLog.consumer.pspng_entitlements.provisionedAttributeValueFormat = ${group.name.equalsIgnoreCase('app:mfa:service:policy:mfa_enabled') ? 'http://tier.internet2.edu/mfa/enabled' : 'urn:mace:example.edu:' + group.extension}
+changeLog.consumer.pspng_entitlements.provisionedAttributeValueFormat = ${group.name.equalsIgnoreCase('app:mfa:service:policy:mfa_enabled') ? 'http://tier.internet2.edu/mfa/enabled' : (group.name.equalsIgnoreCase('app:board_effect:service:policy:board_effect_access') ? 'https://college.boardeffect.com/' : 'urn:mace:example.edu:' + group.extension)}
 changeLog.consumer.pspng_entitlements.userSearchBaseDn = ou=people,dc=internet2,dc=edu
 changeLog.consumer.pspng_entitlements.userSearchFilter = uid=${subject.id}
 changeLog.consumer.pspng_entitlements.allProvisionedValuesPrefix=*
diff --git a/ex401/ex401.3.1/container_files/seed-data/bootstrap.gsh b/ex401/ex401.3.1/container_files/seed-data/bootstrap.gsh
index 0c07f9d..48bbb2c 100644
--- a/ex401/ex401.3.1/container_files/seed-data/bootstrap.gsh
+++ b/ex401/ex401.3.1/container_files/seed-data/bootstrap.gsh
@@ -1 +1,3 @@
 gs = GrouperSession.startRootSession();
+delStem("401.2.end")
+addRootStem("401.3.1", "401.3.1")
\ No newline at end of file
diff --git a/ex401/ex401.3.end/Dockerfile b/ex401/ex401.3.end/Dockerfile
index cebfd9d..40ad125 100644
--- a/ex401/ex401.3.end/Dockerfile
+++ b/ex401/ex401.3.end/Dockerfile
@@ -1,5 +1,5 @@
 ARG VERSION_TAG
-FROM tier/gte:401.3.7-$VERSION_TAG
+FROM tier/gte:401.3.1-$VERSION_TAG
 
 LABEL author="tier-packaging@internet2.edu <tier-packaging@internet2.edu>" \
       Vendor="TIER" \
diff --git a/ex401/ex401.3.end/container_files/seed-data/bootstrap.gsh b/ex401/ex401.3.end/container_files/seed-data/bootstrap.gsh
index 65c0386..8aa2ea4 100644
--- a/ex401/ex401.3.end/container_files/seed-data/bootstrap.gsh
+++ b/ex401/ex401.3.end/container_files/seed-data/bootstrap.gsh
@@ -1,4 +1,46 @@
 gs = GrouperSession.startRootSession();
+delStem("401.3.1")
+addRootStem("401.3.end", "401.3.end")
+
+// 401.3.1
+parent_stem_path = "app";
+app_extension = "board_effect";
+app_name = "board_effect";
+
+stem = addStem(parent_stem_path, app_extension, app_name);
+security = addStem(stem.name, "security", "security");
+service = addStem(stem.name, "service", "service");
+policy = addStem(service.name, "policy", "policy");
+ref = addStem(service.name, "ref", "ref");
+
+admin_group_name = "${app_extension}Admins";
+admin_group = addGroup(security.name, admin_group_name, admin_group_name);
+mgr_group_name = "${app_extension}Updaters";
+mgr_group = addGroup(security.name, mgr_group_name, mgr_group_name);
+view_group_name = "${app_extension}Readers";
+view_group = addGroup(security.name, view_group_name, view_group_name);
+
+addGroup("app:board_effect:service:policy", "board_effect_access", "board_effect_access");
+addGroup("app:board_effect:service:policy", "board_effect_access_allow", "board_effect_access_allow");
+addGroup("app:board_effect:service:policy", "board_effect_access_deny", "board_effect_access_deny");
+addComposite("app:board_effect:service:policy:board_effect_access", CompositeType.COMPLEMENT, "app:board_effect:service:policy:board_effect_access_allow", "app:board_effect:service:policy:board_effect_access_deny");
+
+// 401.3.2
+addGroup("app:board_effect:service:policy", "workroom_finance", "workroom_finance");
+addGroup("app:board_effect:service:policy", "workroom_finance_allow", "workroom_finance_allow");
+addGroup("app:board_effect:service:policy", "workroom_finance_deny", "workroom_finance_deny");
+addComposite("app:board_effect:service:policy:workroom_finance", CompositeType.COMPLEMENT, "app:board_effect:service:policy:workroom_finance_allow", "app:board_effect:service:policy:workroom_finance_deny");
+addMember("app:board_effect:service:policy:board_effect_access_allow", "app:board_effect:service:policy:workroom_finance");
+
+// 401.3.3 nothing to do
+// 401.3.4 nothing to do
+
+// 401.3.5
+addGroup("app:board_effect:service:ref", "finance_committee", "finance_committee");
+grantPriv("app:board_effect:service:ref:finance_committee", "app:board_effect:security:board_effectAdmins",  AccessPrivilege.ADMIN);
+addMember("app:board_effect:service:policy:workroom_finance_allow", "app:board_effect:service:ref:finance_committee");
+addMember("app:board_effect:security:board_effectAdmins", "amartinez410");
+
 
 addStem("ref", "board", "board");
 
diff --git a/ex401/manualBuild.sh b/ex401/manualBuild.sh
index f759d6b..6f070c9 100755
--- a/ex401/manualBuild.sh
+++ b/ex401/manualBuild.sh
@@ -5,12 +5,6 @@ docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.1.1-${VER
 && docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.2.1-${VERSION_TAG} ex401.2.1 \
 && docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.2.end-${VERSION_TAG} ex401.2.end \
 && docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.1-${VERSION_TAG} ex401.3.1 \
-&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.2-${VERSION_TAG} ex401.3.2 \
-&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.3-${VERSION_TAG} ex401.3.3 \
-&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.4-${VERSION_TAG} ex401.3.4 \
-&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.5-${VERSION_TAG} ex401.3.5 \
-&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.6-${VERSION_TAG} ex401.3.6 \
-&& docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.7-${VERSION_TAG} ex401.3.7 \
 && docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.3.end-${VERSION_TAG} ex401.3.end \
 && docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.4.1-${VERSION_TAG} ex401.4.1 \
 && docker build --build-arg VERSION_TAG=${VERSION_TAG} --tag=tier/gte:401.4.end-${VERSION_TAG} ex401.4.end