diff --git a/eos/messages/eos_messages.proto b/eos/messages/eos_messages.proto
index ed0bfd9e32c452c2eeab1c1249aaef6bb2114399..3fbf2d622c652f6497b4a5ad5ba808427a72cc28 100644
--- a/eos/messages/eos_messages.proto
+++ b/eos/messages/eos_messages.proto
@@ -1,37 +1,37 @@
 syntax = "proto3";
 package eos.wfe;
 
-message id {
+message Id {
   fixed64 n = 1;         // identity number
   string name = 2;       // identity name 
 }
 
-message checksum {
+message Checksum {
   string value = 1;      //< checksum value
   string name = 2;       //< checksum name
 }
 
-message clock {
+message Clock {
   fixed64 sec = 1;       //< seconds of a clock
   fixed64 nsec = 2;      //< nanoseconds of a clock
 }
 
-message md {
+message Md {
   fixed64 fid = 1;       //< file/container id
   fixed64 pid = 2;       //< parent id
-  clock ctime = 3;       //< change time
-  clock mtime = 4;       //< modification time
-  clock btime = 5;       //< birth time
-  clock ttime = 6;       //< tree modification time
-  id owner = 7;          //< ownership 
+  Clock ctime = 3;       //< change time
+  Clock mtime = 4;       //< modification time
+  Clock btime = 5;       //< birth time
+  Clock ttime = 6;       //< tree modification time
+  Id owner = 7;          //< ownership
   fixed64 size = 8;      //< size 
-  checksum cks = 9;      //< checksum information
+  Checksum cks = 9;      //< checksum information
   sfixed32 mode = 10;    //< mode
   string lpath = 11;     //< logical path
   map<string, string> xattr = 12; //< xattribute map
 };
 
-message security {
+message Security {
   string host = 1;       //< client host 
   string app = 2;        //< app string
   string name = 3;       //< sec name
@@ -39,44 +39,71 @@ message security {
   string grps = 5;       //< security grps
 }
 
-message client {
-  id user = 1;           //< acting client 
-  security sec = 2;      //< client security information
+message Client {
+  Id user = 1;           //< acting client
+  Security sec = 2;      //< client security information
 }
 
-message service {
+message Service {
   string name = 1;       //< name of the service
   string url = 2;        //< access url of the service
 }
 
-message workflow {
+message Workflow {
   string event = 1;      //< event
   string queue = 2;      //< queue
   string wfname = 3;   //< workflow
   string vpath = 4;      //< vpath
-  service instance = 5;  //< instance information
+  Service instance = 5;  //< instance information
   fixed64 timestamp = 6; //< event timestamp
 }
 
-message notification {
-  workflow wf = 1;      //< workflow
+message Notification {
+  Workflow wf = 1;      //< workflow
   string turl = 2;      //< transport URL
-  client cli = 3;       //< client information
-  md file = 4;          //< file meta data
-  md directory = 5;     //< directory meta data
+  Client cli = 3;       //< client information
+  Md file = 4;          //< file meta data
+  Md directory = 5;     //< directory meta data
 }
 
-message xattr {
+message Xattr {
   enum Operation { GET = 0; ADD = 1; SET = 2; DELETE = 3;}
   fixed64 fid = 1;               //< file id
   map<string, string> xattrs = 2; //< xattribute map
   Operation op = 3;              //< operation to execute for this xattr map
 }
 
-message tapereplica {
-   enum Status { OFFTAPE = 0; ONTAPE = 1; ONTAPESAVE  = 2;}
+message Tapereplica {
+   enum Status { OFFTAPE = 0; ONTAPE = 1; ONTAPESAVE = 2;}
    fixed64 fid = 1;   //< file  id
    Status status = 2; //< state state for file ID
    fixed64 size = 3;  //< File size as recorded on tape for cross check
-   checksum cks = 4;   //< File checksum as computer while writing to tape
+   Checksum cks = 4;   //< File checksum as computer while writing to tape
+}
+
+// The following message is used to wrap all messages sent between EOS and its
+// peers.
+//
+// This wrapper message allows new message types to be added to the protocol in
+// the future.
+//
+// This wrapper message also allows EOS peers to receive non-EOS messages as
+// long as the following two conditions are met:
+// 1. The peer uses a wrapper message with exactly the same (simple) structure.
+// 2. No two message types use the same numeric tag value.
+//
+// The structure of this message is based on the "Union Types" section of the
+// following Google protocol buffers web page:
+//
+//     https://developers.google.com/protocol-buffers/docs/techniques
+//
+// A protocol buffer parser cannot determine a message type based solely on its
+// contents. The type field of this wrapper message provides the required
+// metadata.
+message Wrapper {
+  enum Type {NOTIFICATION = 0; XATTR = 1; TAPEREPLICA = 2;}
+  Type type = 1;
+  Notification notification = 2;
+  Xattr xattr = 3;
+  Tapereplica tapereplica = 4;
 }
diff --git a/xroot_plugins/WriteNotificationMsgCmd.cpp b/xroot_plugins/WriteNotificationMsgCmd.cpp
index a8415e3b248dbfffcd2aae4f96e61d63672e6e65..5a06713cb81f2d0d6c3ed64262c22958f05da235 100644
--- a/xroot_plugins/WriteNotificationMsgCmd.cpp
+++ b/xroot_plugins/WriteNotificationMsgCmd.cpp
@@ -55,7 +55,7 @@ int WriteNotificationMsgCmd::exceptionThrowingMain(const int argc, char *const *
     return 0;
   }
 
-  eos::wfe::notification notification;
+  eos::wfe::Notification notification;
   notification.mutable_wf()->set_event("notification_workflow_event");
   notification.mutable_wf()->set_queue("notification_workflow_queue");
   notification.mutable_wf()->set_wfname("notification_workflow_wfname");
diff --git a/xroot_plugins/XrdCtaFilesystem.cpp b/xroot_plugins/XrdCtaFilesystem.cpp
index 8b9cfb1bf132de232f001453558def0821bc19ee..8d72c61ea04f4021ff50a2c230e68063bb2b1760 100644
--- a/xroot_plugins/XrdCtaFilesystem.cpp
+++ b/xroot_plugins/XrdCtaFilesystem.cpp
@@ -99,7 +99,7 @@ int XrdCtaFilesystem::FSctl(const int cmd, XrdSfsFSctl &args, XrdOucErrInfo &eIn
   }
 
   const std::string query(args.Arg1, args.Arg1Len);
-  eos::wfe::notification notification;
+  eos::wfe::Notification notification;
   if(!notification.ParseFromString(query)) {
     eInfo.setErrInfo(EINVAL, "Failed to parse notification message");
     return SFS_ERROR;