diff --git a/doc/source/command-objects/federation-protocol.rst b/doc/source/command-objects/federation-protocol.rst
new file mode 100644
index 0000000000..0ed0980a54
--- /dev/null
+++ b/doc/source/command-objects/federation-protocol.rst
@@ -0,0 +1,112 @@
+===================
+federation protocol
+===================
+
+Identity v3
+
+`Requires: OS-FEDERATION extension`
+
+federation protocol create
+--------------------------
+
+Create new federation protocol
+
+.. program:: federation protocol create
+.. code:: bash
+
+    os federation protocol create
+        --identity-provider <identity-provider>
+        --mapping <mapping>
+        <name>
+
+.. option:: --identity-provider <identity-provider>
+
+    Identity provider that will support the new federation protocol (name or ID) (required)
+
+.. option:: --mapping <mapping>
+
+    Mapping that is to be used (name or ID) (required)
+
+.. describe:: <name>
+
+    New federation protocol name (must be unique per identity provider)
+
+federation protocol delete
+--------------------------
+
+Delete a federation protocol
+
+.. program:: federation protocol delete
+.. code:: bash
+
+    os federation protocol delete
+        --identity-provider <identity-provider>
+        <federation-protocol>
+
+.. option:: --identity-provider <identity-provider>
+
+    Identity provider that supports <federation-protocol> (name or ID) (required)
+
+.. describe:: <federation-protocol>
+
+    Federation protocol to delete (name or ID)
+
+federation protocol list
+------------------------
+
+List federation protocols
+
+.. program:: federation protocol list
+.. code:: bash
+
+    os federation protocol list
+        --identity-provider <identity-provider>
+
+.. option:: --identity-provider <identity-provider>
+
+    Identity provider to list (name or ID) (required)
+
+federation protocol set
+-----------------------
+
+Set federation protocol properties
+
+.. program:: federation protocol set
+.. code:: bash
+
+    os federation protocol set
+        --identity-provider <identity-provider>
+        [--mapping <mapping>]
+        <federation-protocol>
+
+.. option:: --identity-provider <identity-provider>
+
+    Identity provider that supports <federation-protocol> (name or ID) (required)
+
+.. option:: --mapping <mapping>
+
+    Mapping that is to be used (name or ID)
+
+.. describe:: <federation-protocol>
+
+    Federation protocol to modify (name or ID)
+
+federation protocol show
+------------------------
+
+Display federation protocol details
+
+.. program:: federation protocol show
+.. code:: bash
+
+    os federation protocol show
+        --identity-provider <identity-provider>
+        <federation-protocol>
+
+.. option:: --identity-provider <identity-provider>
+
+    Identity provider that supports <federation-protocol> (name or ID) (required)
+
+.. describe:: <federation-protocol>
+
+    Federation protocol to display (name or ID)
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index cbe46ef7e7..a09dcb9ec8 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -83,6 +83,7 @@ referring to both Compute and Volume quotas.
 * ``ec2 cedentials``: (**Identity**) AWS EC2-compatible credentials
 * ``endpoint``: (**Identity**) the base URL used to contact a specific service
 * ``extension``: (**Compute**, **Identity**, **Volume**) OpenStack server API extensions
+* ``federation protocol``: (**Identity**) the underlying protocol used while federating identities
 * ``flavor``: (**Compute**) predefined server configurations: ram, root disk, etc
 * ``group``: (**Identity**) a grouping of users
 * ``host``: Compute - the physical computer running a hypervisor
diff --git a/openstackclient/identity/v3/federation_protocol.py b/openstackclient/identity/v3/federation_protocol.py
index 693ec94eae..5a651165b1 100644
--- a/openstackclient/identity/v3/federation_protocol.py
+++ b/openstackclient/identity/v3/federation_protocol.py
@@ -25,7 +25,7 @@ from openstackclient.common import utils
 
 
 class CreateProtocol(show.ShowOne):
-    """Create new Federation Protocol tied to an Identity Provider"""
+    """Create new federation protocol"""
 
     log = logging.getLogger(__name__ + 'CreateProtocol')
 
@@ -34,16 +34,19 @@ class CreateProtocol(show.ShowOne):
         parser.add_argument(
             'federation_protocol',
             metavar='<name>',
-            help='Protocol (must be unique per Identity Provider')
+            help='New federation protocol name (must be unique per identity '
+                 ' provider)')
         parser.add_argument(
             '--identity-provider',
             metavar='<identity-provider>',
-            help=('Identity Provider you want to add the Protocol to '
-                  '(must already exist)'), required=True)
+            required=True,
+            help='Identity provider that will support the new federation '
+                 ' protocol (name or ID) (required)')
         parser.add_argument(
             '--mapping',
-            metavar='<mapping>', required=True,
-            help='Mapping you want to be used (must already exist)')
+            metavar='<mapping>',
+            required=True,
+            help='Mapping that is to be used (name or ID) (required)')
 
         return parser
 
@@ -66,7 +69,7 @@ class CreateProtocol(show.ShowOne):
 
 
 class DeleteProtocol(command.Command):
-    """Delete Federation Protocol tied to a Identity Provider"""
+    """Delete a federation protocol"""
 
     log = logging.getLogger(__name__ + '.DeleteProtocol')
 
@@ -74,12 +77,14 @@ class DeleteProtocol(command.Command):
         parser = super(DeleteProtocol, self).get_parser(prog_name)
         parser.add_argument(
             'federation_protocol',
-            metavar='<name>',
-            help='Protocol (must be unique per Identity Provider')
+            metavar='<federation-protocol>',
+            help='Federation protocol to delete (name or ID)')
         parser.add_argument(
             '--identity-provider',
-            metavar='<identity-provider>', required=True,
-            help='Identity Provider the Protocol is tied to')
+            metavar='<identity-provider>',
+            required=True,
+            help='Identity provider that supports <federation-protocol> '
+                 '(name or ID) (required)')
 
         return parser
 
@@ -92,7 +97,7 @@ class DeleteProtocol(command.Command):
 
 
 class ListProtocols(lister.Lister):
-    """List Protocols tied to an Identity Provider"""
+    """List federation protocols"""
 
     log = logging.getLogger(__name__ + '.ListProtocols')
 
@@ -100,8 +105,9 @@ class ListProtocols(lister.Lister):
         parser = super(ListProtocols, self).get_parser(prog_name)
         parser.add_argument(
             '--identity-provider',
-            metavar='<identity-provider>', required=True,
-            help='Identity Provider the Protocol is tied to')
+            metavar='<identity-provider>',
+            required=True,
+            help='Identity provider to list (name or ID) (required)')
 
         return parser
 
@@ -118,7 +124,7 @@ class ListProtocols(lister.Lister):
 
 
 class SetProtocol(command.Command):
-    """Set Protocol tied to an Identity Provider"""
+    """Set federation protocol properties"""
 
     log = logging.getLogger(__name__ + '.SetProtocol')
 
@@ -127,21 +133,26 @@ class SetProtocol(command.Command):
         parser.add_argument(
             'federation_protocol',
             metavar='<name>',
-            help='Protocol (must be unique per Identity Provider')
+            help='Federation protocol to modify (name or ID)')
         parser.add_argument(
             '--identity-provider',
-            metavar='<identity-provider>', required=True,
-            help=('Identity Provider you want to add the Protocol to '
-                  '(must already exist)'))
+            metavar='<identity-provider>',
+            required=True,
+            help='Identity provider that supports <federation-protocol> '
+                 '(name or ID) (required)')
         parser.add_argument(
             '--mapping',
-            metavar='<mapping>', required=True,
-            help='Mapping you want to be used (must already exist)')
+            metavar='<mapping>',
+            help='Mapping that is to be used (name or ID)')
         return parser
 
     def take_action(self, parsed_args):
         identity_client = self.app.client_manager.identity
 
+        if not parsed_args.mapping:
+            self.app.log.error("No changes requested")
+            return
+
         protocol = identity_client.federation.protocols.update(
             parsed_args.identity_provider, parsed_args.federation_protocol,
             parsed_args.mapping)
@@ -156,7 +167,7 @@ class SetProtocol(command.Command):
 
 
 class ShowProtocol(show.ShowOne):
-    """Show Protocol tied to an Identity Provider"""
+    """Display federation protocol details"""
 
     log = logging.getLogger(__name__ + '.ShowProtocol')
 
@@ -164,13 +175,14 @@ class ShowProtocol(show.ShowOne):
         parser = super(ShowProtocol, self).get_parser(prog_name)
         parser.add_argument(
             'federation_protocol',
-            metavar='<name>',
-            help='Protocol (must be unique per Identity Provider')
+            metavar='<federation-protocol>',
+            help='Federation protocol to display (name or ID)')
         parser.add_argument(
             '--identity-provider',
-            metavar='<identity-provider>', required=True,
-            help=('Identity Provider you want to add the Protocol to '
-                  '(must already exist)'))
+            metavar='<identity-provider>',
+            required=True,
+            help=('Identity provider that supports <federation-protocol> '
+                  '(name or ID) (required)'))
         return parser
 
     def take_action(self, parsed_args):