XEP-xxxx: Authorization Tokens

Abstract
This document defines an XMPP protocol extension for issuing authentication tokens to client applications and provides methods for managing сlient connections.
Authors
  • Andrey Gagarin
  • Andrew Nenakhov
Copyright
© 2019 – 2019 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

ProtoXEP

WARNING: This document has not yet been accepted for consideration or approved in any official manner by the XMPP Standards Foundation, and this document is not yet an XMPP Extension Protocol (XEP). If this document is accepted as a XEP by the XMPP Council, it will be published at <https://xmpp.org/extensions/> and announced on the <standards@xmpp.org> mailing list.
Type
Standards Track
Version
0.0.1 (2019-09-11)
Document Lifecycle
  1. Experimental
  2. Proposed
  3. Stable
  4. Final

1. Introduction

When an XMPP client is negotiating a stream with an XMPP server, it typically needs to perform authentication and authorization. Typically stream negotiation requires providing a password on each connection attempt. Naturally this means that an XMPP client needs to store password: reconnections are very frequent on some types of clients, asking a user to provide a password on each reconnect would result in a very bad user experience.

This results in increased security threats associated with storing account password on physical device: password can be extracted from this device by whoever gains access to it. Also, a user can't revoke access to clients without changing password. More, password change won't help to immediately revoke access from a device with established connection.

This document describes a method address mentioned issues and provide more security for users. The idea is to use XMPP-based tokens, which allow to control client sessions.

2. Requirements

  1. It is RECOMMENDED for the client to transfer information about connected device: type of client, version of the operating system.
  2. Server MUST show latest IP address used with the token

3. Obtaining a token

3.1 Issuing a token

The following example illustrates the XML structure to be sent when issuing new token for client.

Example 1. The client sends a request with information about his operating system and the client version to the server to issue new token
    <iq type='set' from='juliet@capulet.lit/chamber' to='capulet.it' id='1'>
      <issue xmlns='https://xabber.com/protocol/auth-tokens'>
        <client>xabber-web</client>
        <device>MacOS 10.14</device>
      </issue>
    </iq>
Example 2. The server in response sends a new token to the the client
  <iq type='result' from='capulet.it' to='juliet@capulet.it/balcony' id='1'>
    <x xmlns='https://xabber.com/protocol/auth-tokens'>
      <token>VkpTYqfpPcLpwciTRtgHaV7HLBC9O9kY</token>
      <expire>1536322632</expire>
      <token-uid>49975a48609793c5c93f5e9eab264f6706f04164</token-uid>
    </x>
  </iq>

3.2 Issuing a token with a specified lifetime

Example 3. If the client wants to explicitly indicate the lifetime of the token, it MAY add the expire tag with expiration time in seconds
    <iq type='set' from='juliet@capulet.lit/chamber' to='capulet.it' id='2'>
      <issue xmlns='https://xabber.com/protocol/auth-tokens'>
        <client>xabber-web</client>
        <device>iMac Pro MacOS 10.14</device>
        <expire>3600</expire>
      </issue>
    </iq>
Example 4. The server in response sends a new token to the the client
  <iq type='result' from='capulet.it' to='juliet@capulet.it/balcony' id='2'>
    <x xmlns='https://xabber.com/protocol/auth-tokens'>
      <token>VkpTYqfpPcLpwciTRtgHaV7HLBC9O9kY</token>
      <expire>1536321232</expire>
      <token-uid>49975a48609793c5c93f5e9eab264f6706f04164</token-uid>
    </x>
  </iq>

3.3 Issuing a new token during authentication before bind

During authentication process the client can receive a token before bind.

Example 5. The client establishes a connection to the server
  <?xml version='1.0'?>
  <stream:stream xmlns="jabber:client" to="capulet.it" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xml:lang="ru">

The server accepts the connection and sends a list of supported stream features. Feature x-token is also on the list:

Example 6.
  <?xml version='1.0'?>
  <stream:stream xmlns="jabber:client" to="capulet.it" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xml:lang="ru">

  <stream:features>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
    ...
    <x-token xmlns='https://xabber.com/protocol/auth-tokens'/>
  </stream:features>
Example 7. After passing all authentication steps, the client makes a standard request to issue a token
  <iq to='capulet.it' type='set' id='2'>
    <issue xmlns='https://xabber.com/protocol/auth-tokens'>
      <client>xabber-web</client>
      <device>MacOS 10.14</device>
    </issue>
  </iq>
Example 8. The server responds with a new client token
  <iq from='capulet.it' type='result' id='2'>
    <x xmlns='https://xabber.com/protocol/auth-tokens'>
      <token>VkpTYqfpPcLpwciTRtgHaV7HLBC9O9kY</token>
      <expire>1536322632</expire>
      <token-uid>49975a48609793c5c93f5e9eab264f6706f04164</token-uid>
    </x>
  </iq>

4. Authentication

Example 9. The client establishes a connection with the server
    <?xml version='1.0'?>
    <stream:stream xmlns="jabber:client" to="capulet.it" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xml:lang="ru" >
Example 10. The server accepts this connection and sends a list of supported protocols for authentication
    <?xml version='1.0'?>
    <stream:stream xmlns="jabber:client" to="capulet.it" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xml:lang="ru" >

    <stream:features>
      <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        ...
        <mechanism>X-TOKEN</mechanism>
        ...
      </mechanisms>
    </stream:features>
Example 11. The client sends the next element for authentication:
    <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-TOKEN">
      base64("\0" + user_name + "\0" + auth_token)
    </auth>

The content in the auth element should be base64 encoding of a string containing a null byte, followed by username, another null byte and the string representation of the user authentication token. This is similar to authentication with a password using the PLAIN mechanism, except the token is added instead of password.

Example 12. The response is standard for SASL XMPP authentication. For example, on success, the server will reply with:
    <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>

5. Token management

5.1 List of tokens

Example 13. To get a list of all existing tokens, the client sends a request to the server
      <iq type='get' from='juliet@capulet.it/balcony' to='capulet.it' id='3'>
        <query xmlns='https://xabber.com/protocol/auth-tokens#items'/>
      </iq>
Example 14. The server responds to the client with a list of tokens with unique identifiers
      <iq type='result' from='capulet.it' to='juliet@capulet.it/balcony' id='3'>
        <x xmlns='https://xabber.com/protocol/auth-tokens#items'>
          <field var='1'>
            <client>xabber-web 2.3</client>
            <device>iMac Pro MacOS 10.14</device>
            <token-uid>
              024717297867c1d32714cadde305825a9909ef7c
            </token-uid>
            <expire>1536322632</expire>
            <ip>192.168.1.2</ip>
            <last-auth>1536322632</last-auth>
          </field>
          <field var='2'>
            <client>xabber-android 2.363</client>
            <device>Nokia  Android 8.0</device>
            <token-uid>
              7dbf8541c4de1d24a0f748cc01f98a140100979a
            </token-uid>
            <expire>1536322632</expire>
            <ip>192.168.1.3</ip>
            <last-auth>1536322632</last-auth>
          </field>
          <field var='3'>
            <client>xabber-ios 1.8</client>
            <device>iphone 5s IOS 12.3.1</device>
            <token-uid>
              49975a48609793c5c93f5e9eab264f6706f04164
            </token-uid>
            <expire>1536322632</expire>
            <ip>192.168.1.3</ip>
            <last-auth>1536322632</last-auth>
          </field>
          <field var='4'>
            <client>xabber-desktop 1.2</client>
            <device>PC Arch Linux x86_64</device>
            <token-uid>
              86c763fcdca9b3372685ca4b258b1a207b9138f5
            </token-uid>
            <expire>1536322632</expire>
            <ip>192.168.1.5</ip>
            <last-auth>1536322632</last-auth>
          </field>
        </x>
      </iq>

5.2 Token revocation

Example 15. To revoke a token, the client sends to the server
      <iq type='set' from='juliet@capulet.it/balcony' to='capulet.it' id='4'>
        <revoke xmlns='https://xabber.com/protocol/auth-tokens'>
          <token-uid>
            86c763fcdca9b3372685ca4b258b1a207b9138f5
          </token-uid>
        </revoke>
      </iq>
Example 16. If the client wants to delete several tokens, it needs to send them in a list
      <iq type='set' from='juliet@capulet.it/balcony' to='capulet.it' id='5'>
        <revoke xmlns='https://xabber.com/protocol/auth-tokens'>
          <token-uid>
            49975a48609793c5c93f5e9eab264f6706f04164
          </token-uid>
          <token-uid>
            7dbf8541c4de1d24a0f748cc01f98a140100979a
          </token-uid>
        </revoke>
      </iq>
Example 17. On success, the server responds to the client
<iq from='capulet.it' to='juliet@capulet.it/balcony' type='result' id='5'/>
Example 18. The server also sends notification
      <message type='headline' from='capulet.it' to='juliet@capulet.it/balcony' id='5'>
        <revoke xmlns='https://xabber.com/protocol/auth-tokens'>
          <token-uid>
            49975a48609793c5c93f5e9eab264f6706f04164
          </token-uid>
          <token-uid>
            7dbf8541c4de1d24a0f748cc01f98a140100979a
          </token-uid>
        </revoke>
      </message>
Example 19. On failure, the server responds to the client
      <iq type='error' from='capulet.it' to='juliet@capulet.it/balcony' id='5'>
        <error code='400' type='modify'>
          <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
        </error>
      </iq>

5.3 Notification about new token

The server issues a new token and sends a message with a notification about the entrance from the new device.

Example 20.
      <message type='chat' from='capulet.it' to='juliet@capulet.it/balcony' id='msg1'>
        <x xmlns='https://xabber.com/protocol/auth-tokens'>
          <token-uid>dnbo3gasxia1agsj5nxzrlxr57ilibh9</token-uid>
        </x>
        <body>New login. Dear juliet@capulet.it, we detected a new login into your account from a new device on 01/09/2019 at 05:39:10 UTC
          Xabber Web 2.6.5.642
          PC Linux x86_64
          192.168.1.2
          If this wasn't you, go to Settings > XMPP Account > Active sessions and terminate suspicious sessions.
        </body>
      </message>

5.4 Token revocation before bind

During authentication process the client can revoke all tokens before bind. This might be necessary if someone has gained access to a client device and revokes all tokens immediately after connection, not giving a chance to account owner to revoke access.

After passing all the authentication steps, the client makes a request to delete all tokens

Example 21.
      <iq type='set' to='capulet.it' id='6'>
        <revoke-all xmlns='https://xabber.com/protocol/auth-tokens'/>
      </iq>
Example 22. On success, the server responds to the client
      <iq from='capulet.it' type='result' id='6'/>

5.5 Request token information

Example 23. To view information about the token, the client sends a request to the server
      <iq type='get' from='juliet@capulet.it/balcony' to='capulet.it' id='7'>
        <query xmlns='https://xabber.com/protocol/auth-tokens#items'>
          <token>VkpTYqfpPcLpwciTRtgHaV7HLBC9O9kY</token>
        </query>
      </iq>
Example 24. The server responds with return full information about the token
      <iq  type='result' from='capulet.it' to='juliet@capulet.it/balcony' id='7'>
        <x xmlns='https://xabber.com/protocol/auth-tokens#items'>
          <field var='1'>
            <client>xabber-web 2.3</client>
            <device>iMac Pro MacOS 10.14</device>
            <token-uid>
              024717297867c1d32714cadde305825a9909ef7c
            </token-uid>
            <expire>1536322632</expire>
            <ip>192.168.1.2</ip>
            <last-auth>1536322632</last-auth>
          </field>
        </x>
      </iq>

6. Determining support

Example 25. The client requests list of supported protocols from his server
    <iq type='get' from='juliet@capulet.it/balcony' to='capulet.it'  id='1'>
      <query xmlns='http://jabber.org/protocol/disco#info'/>
    </iq>
Example 26. The server announces support for token protocol
    <iq type='result' from='capulet.it' to='juliet@capulet.it/balcony' id='1'>
      <query xmlns='http://jabber.org/protocol/disco#info'>
        ...
        <feature var='https://xabber.com/protocol/auth-tokens'/>
        ...
      </query>
    </iq>

7. Security Considerations

The server is recording IP addresses used by user. While this enforces privacy during regular usage, making user aware of a malicious attempts to access his data, it also creates a privacy risk for a user if this data is leaked: it might help to determine user identity and location. Server operators should be warned about this risk and take measures against it.

8. IANA Considerations

This document requires no interaction with the Internet Assigned Numbers Authority (IANA) [1].

9. XMPP Registrar Considerations

9.1 Protocol Namespaces

The XMPP Registrar [2] includes 'https://xabber.com/protocol/auth-tokens' and 'https://xabber.com/protocol/auth-tokens#items' in its registry of protocol namespaces (see <https://xmpp.org/registrar/namespaces.html>).

10. XML Schemas

10.1 Namespace https://xabber.com/protocol/auth-tokens

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='https://xabber.com/protocol/auth-tokens'
    xmlns='https://xabber.com/protocol/auth-tokens'
    elementFormDefault='qualified'>

    <xs:annotation>
      <xs:documentation>
        The protocol documented by this schema is defined in
        XEP-xxxx: http://www.xmpp.org/extensions/xep-xxxx.html
      </xs:documentation>
    </xs:annotation>

  <xs:element name='x'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='token' type='xs:string' minOccurs='0' maxOccurs='1'/>
        <xs:element name='token-uid' type='xs:string' minOccurs='0' maxOccurs='1'/>
        <xs:element name='expire' type='xs:unsigned' minOccurs='0' maxOccurs='1'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='issue'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='client' type='xs:string' minOccurs='1' maxOccurs='1'/>
        <xs:element name='device' type='xs:string' minOccurs='1' maxOccurs='1'/>
        <xs:element name='expire' type='xs:unsigned' minOccurs='0' maxOccurs='1'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='revoke'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='token-uid' type='xs:string' minOccurs='1' maxOccurs='unbounded'/>
        <xs:element ref='revoke-all' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='revoke-all'/>

</xs:schema>

10.2 Namespace https://xabber.com/protocol/auth-tokens#items

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='https://xabber.com/protocol/auth-tokens#items'
    xmlns='https://xabber.com/protocol/auth-tokens#items'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-xxxx: http://www.xmpp.org/extensions/xep-xxxx.html
    </xs:documentation>
  </xs:annotation>

  <xs:element name='query'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='token' type='xs:string' minOccurs='0' maxOccurs='1'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='x'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='field' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='field'>
  <xs:complexType>
      <xs:sequence>
        <xs:attribute name='var' type='xs:string' use='required'/>
        <xs:element name='client' type='xs:string' minOccurs='1' maxOccurs='1'/>
        <xs:element name='device' type='xs:string' minOccurs='1' maxOccurs='1'/>
        <xs:element name='token-uid' type='xs:string' minOccurs='1' maxOccurs='1'/>
        <xs:element name='expire' type='xs:unsigned' minOccurs='1' maxOccurs='1'/>
        <xs:element name='ip' type='xs:string' minOccurs='1' maxOccurs='1'/>
        <xs:element name='last-auth' type='xs:unsigned' minOccurs='1' maxOccurs='1'/>
      </xs:sequence>
  </xs:complexType>
  </xs:element>

</xs:schema>

Appendices

Appendix A: Document Information

Series
XEP
Number
xxxx
Publisher
XMPP Standards Foundation
Status
ProtoXEP
Type
Standards Track
Version
0.0.1
Last Updated
2019-09-11
Approving Body
XMPP Council
Dependencies
XMPP Core, XEP-0001
Supersedes
None
Superseded By
None
Short Name
xabber-tokens

This document in other formats: XML  PDF

Appendix B: Author Information

Andrey Gagarin
Email
andrey.gagarin@redsolution.com
JabberID
andrey.gagarin@redsolution.com
Andrew Nenakhov
Email
andrew.nenakhov@redsolution.com
JabberID
andrew.nenakhov@redsolution.com

Copyright

This XMPP Extension Protocol is copyright © 1999 – 2024 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which can be found at <https://xmpp.org/about/xsf/ipr-policy> or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).

Visual Presentation

The HTML representation (you are looking at) is maintained by the XSF. It is based on the YAML CSS Framework, which is licensed under the terms of the CC-BY-SA 2.0 license.

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 6120) and XMPP IM (RFC 6121) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <https://xmpp.org/community/> for a complete list.

Errata can be sent to <editor@xmpp.org>.

Appendix F: Requirements Conformance

The following requirements keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".

Appendix G: Notes

1. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.

2. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <https://xmpp.org/registrar/>.

Appendix H: Revision History

Note: Older versions of this specification might be available at https://xmpp.org/extensions/attic/

  1. Version 0.0.1 (2019-09-11)

    First draft.

    ag/an

Appendix I: Bib(La)TeX Entry

@report{gagarin2019xabber-tokens,
  title = {Authorization Tokens},
  author = {Gagarin, Andrey and Nenakhov, Andrew},
  type = {XEP},
  number = {xxxx},
  version = {0.0.1},
  institution = {XMPP Standards Foundation},
  url = {https://xmpp.org/extensions/xep-xxxx.html},
  date = {2019-09-11/2019-09-11},
}

END