JEP-0126: Invisibility

This JEP describes best practices regarding implementation of invisible presence by means of XMPP privacy lists.


NOTICE: This Informational JEP defines a best practice or protocol profile that has been approved by the Jabber Council and/or the JSF Board of Directors. Implementations are encouraged and the best practice or protocol profile is appropriate for deployment in production systems.


JEP Information

Status: Active
Type: Informational
Number: 0126
Version: 1.0
Last Updated: 2004-03-05
JIG: Standards JIG
Approving Body: Jabber Council
Dependencies: XMPP Core, XMPP IM
Supersedes: None
Superseded By: None
Short Name: N/A

Author Information

Peter Saint-Andre

Email: stpeter@jabber.org
JID: stpeter@jabber.org

Legal Notice

This Jabber Enhancement Proposal is copyright 1999 - 2005 by the Jabber Software Foundation (JSF) and is in full conformance with the JSF's Intellectual Property Rights Policy <http://www.jabber.org/jsf/ipr-policy.shtml>. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at <http://www.opencontent.org/openpub/>).

Discussion Venue

The preferred venue for discussion of this document is the Standards-JIG discussion list: <http://mail.jabber.org/mailman/listinfo/standards-jig>.

Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the Jabber Software 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 JEP 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.

Conformance Terms

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


Table of Contents

1. Introduction
2. Requirements
3. Use Cases
3.1. Log In as Globally Invisible
3.2. Become Selectively Visible
3.2.1. Becoming Visible by JID
3.2.2. Becoming Visible by Roster Group
3.2.3. Becoming Visible by Subscription Type
3.3. Become Globally Visible
3.4. Become Selectively Invisible
3.4.1. Becoming Invisible by JID
3.4.2. Becoming Invisible by Roster Group
3.4.3. Becoming Invisible by Subscription Type
3.5. Become Globally Invisible
4. Implementation Notes
5. Security Considerations
6. IANA Considerations
7. Jabber Registrar Considerations
8. Formal Definition
Notes
Revision History


1. Introduction

Several popular instant messaging services implement a feature known as invisibility: the ability to remain online yet appear offline to some or all of one's contacts. A number of Jabber servers and clients have also implemented such a feature, using special values of the <presence/> element's 'type' attribute (e.g., <presence type='invisible'/>). Unfortunately, such implementations are not compliant with XMPP Core [1] and XMPP IM [2], which specify that only the 'type' attribute values defined in the XML schema for the 'jabber:client' and 'jabber:server' namespaces are allowed in XMPP (and those values do not include "invisible"). However, XMPP IM also defines a privacy lists protocol (i.e., the 'jabber:iq:privacy' namespace) that can be used to implement invisibility in an XMPP-compliant manner. This JEP documents how to do just that.

2. Requirements

This document addresses the following requirements:

3. Use Cases

This JEP addresses the following use cases:

  1. Log In as Globally Invisible
  2. Become Selectively Visible
  3. Become Globally Visible
  4. Become Selectively Invisible
  5. Become Globally Invisible

These use cases are defined below in "chronological" order by following a scenario in which a user (1) logs in as invisible, (2) becomes selectively visible to certain contacts, (3) becomes visible to all contacts, (4) becomes selectively invisible to certain contacts, and finally (5) becomes invisible to all contacts.

3.1 Log In as Globally Invisible

If a user wants to log in as invisible, a certain order of events MUST be followed. Specifically, after authenticating but before sending initial presence, the user MUST define (if necessary) and set as active a privacy list that blocks all outbound presence notifications.

Example 1. User Defines and Sets Global Invisibility Privacy Rule

... authentication / session establishment ...

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv1'>
  <query xmlns='jabber:iq:privacy'>
    <list name='invisible'>
      <item action='deny' order='1'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active1'>
  <query xmlns='jabber:iq:privacy'>
    <active name='invisible'/>
  </query>
</iq>
    

Naturally, the user could have defined this list during a previous session and could simply set the relevant list as active when logging in, rather than defining the list on login. Both steps are shown here for completeness.

The user may now send initial presence to the server.

Example 2. User Sends Initial Presence

<presence>
  <status>I'm not really here, you understand!</status>
</presence>
    

Even though the user has sent initial presence, that presence information will not be broadcasted to any of the user's contacts, since the active privacy list blocks all outbound presence notifications.

3.2 Become Selectively Visible

Let us now suppose that the user tires of being globally invisible, and decides to become visible to some -- but not all -- contacts (not even famous magic rings possess this feature). The 'jabber:iq:privacy' namespace gives the user three options:

Examples of these options are shown below.

3.2.1 Becoming Visible by JID

Example 3. User Defines and Sets Selective Visibility Privacy Rule (by JID)

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv2'>
  <query xmlns='jabber:iq:privacy'>
    <list name='visible-to-Frodo'>
      <item type='jid'
            value='frodo@tolkien.lit'
            action='allow'
            order='1'>
        <presence-out/>
      </item>
      <item action='deny' order='2'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active2'>
  <query xmlns='jabber:iq:privacy'>
    <active name='visible-to-Frodo'/>
  </query>
</iq>
      

The foregoing privacy list blocks outbound presence notifications to every JID except one. In order to ensure synchronization of presence notifications, the client SHOULD now send the user's last available presence to any active resources associated with the selected JID:

Example 4. Client Sends Last Available Presence

<presence from='bilbo@tolkien.net/shire'
          to='frodo@tolkien.lit/garden'>
  <status>I'm not really here, you understand!</status>
</presence>
      

3.2.2 Becoming Visible by Roster Group

Example 5. User Defines and Sets Selective Visibility Privacy Rule (by Roster Group)

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv3'>
  <query xmlns='jabber:iq:privacy'>
    <list name='visible-to-Bagginses'>
      <item type='group'
            value='Bagginses'
            action='allow'
            order='1'>
        <presence-out/>
      </item>
      <item action='deny' order='2'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active3'>
  <query xmlns='jabber:iq:privacy'>
    <active name='visible-to-Bagginses'/>
  </query>
</iq>
      

The foregoing privacy list blocks outbound presence notifications to every JID except those in a certain roster group. In order to ensure synchronization of presence notifications, the client SHOULD now send the user's last available presence to any active resources associated with JIDs in that group:

Example 6. Client Sends Last Available Presence

<presence from='bilbo@tolkien.net/shire'
          to='frodo@tolkien.lit/garden'>
  <status>I'm not really here, you understand!</status>
</presence>

<presence from='bilbo@tolkien.net/shire'
          to='bungo@tolkien.lit/pub'>
  <status>I'm not really here, you understand!</status>
</presence>

<presence from='bilbo@tolkien.net/shire'
          to='rosa.baggins@tolkien.lit/home'>
  <status>I'm not really here, you understand!</status>
</presence>
      

3.2.3 Becoming Visible by Subscription Type

Becoming visible or invisible by subscription type is probably much less likely than becoming visible by JID or roster group; however, it is described here for the sake of completeness.

Example 7. User Defines and Sets Selective Visibility Privacy Rule (by Subscription State)

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv4'>
  <query xmlns='jabber:iq:privacy'>
    <list name='visible-to-both'>
      <item type='subscription'
            value='both'
            action='allow'
            order='1'>
        <presence-out/>
      </item>
      <item action='deny' order='2'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active4'>
  <query xmlns='jabber:iq:privacy'>
    <active name='visible-to-both'/>
  </query>
</iq>
      

The foregoing privacy list blocks outbound presence notifications to every JID except those that are in the user's roster with a subscription type of "both". Outbound presence notifications are sent accordingly.

3.3 Become Globally Visible

Let us now suppose that the user wants to become visible to all those who are subscribed to his presence. This easy to do by defining and setting as active a new privacy list (here again, the privacy list may have been defined previously).

Example 8. User Defines and Sets Global Visibility Privacy Rule

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv5'>
  <query xmlns='jabber:iq:privacy'>
    <list name='visible'>
      <item action='allow' order='1'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active5'>
  <query xmlns='jabber:iq:privacy'>
    <active name='visible'/>
  </query>
</iq>
    

Because globally allowing outbound presence notifications is most likely the default behavior of any server, a more straightforward way to become globally visible is to decline the use of any active rule (the equivalent, as it were, of taking off a magic invisibility ring):

Example 9. User Declines the Use of Any Active Rule

<iq from='bilbo@tolkien.lit/shire' type='set' id='active6'>
  <query xmlns='jabber:iq:privacy'>
    <active/>
  </query>
</iq>
    

3.4 Become Selectively Invisible

Let us now suppose that the user no longer wants to be globally visible, but desires to be invisible only to some -- but not all -- contacts. As with visibility, here again the 'jabber:iq:privacy' namespace gives the user three options:

Examples of these options are shown below.

3.4.1 Becoming Invisible by JID

Example 10. User Defines and Sets Selective Invisibility Privacy Rule (by JID)

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv6'>
  <query xmlns='jabber:iq:privacy'>
    <list name='invisible-to-Gandalf'>
      <item type='jid'
            value='gandalf@tolkien.lit'
            action='deny'
            order='1'>
        <presence-out/>
      </item>
      <item action='allow' order='2'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active7'>
  <query xmlns='jabber:iq:privacy'>
    <active name='invisible-to-Gandalf'/>
  </query>
</iq>
      

The foregoing privacy list allows outbound presence notifications to every JID except one. In order to ensure synchronization of presence notifications, the client SHOULD now send unavailable presence from the user to any active resources associated with the selected JID:

Example 11. Client Sends Unavailable Presence

<presence from='bilbo@tolkien.net/shire'
          to='gandalf@tolkien.lit/forest'
          type='unavailable'/>
      

3.4.2 Becoming Invisible by Roster Group

Example 12. User Defines and Sets Selective Invisibility Privacy Rule (by Roster Group)

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv7'>
  <query xmlns='jabber:iq:privacy'>
    <list name='invisible-to-Wizards'>
      <item type='group'
            value='Wizards'
            action='deny'
            order='1'>
        <presence-out/>
      </item>
      <item action='allow' order='2'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active8'>
  <query xmlns='jabber:iq:privacy'>
    <active name='invisible-to-Wizards'/>
  </query>
</iq>
      

The foregoing privacy list allows outbound presence notifications to every JID except those in a certain roster group. In order to ensure synchronization of presence notifications, the client SHOULD now send unavailable presence from the user to any active resources associated with JIDs in that group:

Example 13. Client Sends Unavailable Presence

<presence from='bilbo@tolkien.net/shire'
          to='gandalf@tolkien.lit/forest'
          type='unavailable'/>

<presence from='bilbo@tolkien.net/shire'
          to='sauramon@tolkien.lit/chamber'
          type='unavailable'/>
      

3.4.3 Becoming Invisible by Subscription Type

Becoming visible or invisible by subscription type is probably much less likely than becoming visible by JID or roster group; however, it is described here for the sake of completeness.

Example 14. User Defines and Sets Selective Invisibility Privacy Rule (by Subscription State)

<iq from='bilbo@tolkien.lit/shire' type='set' id='inv8'>
  <query xmlns='jabber:iq:privacy'>
    <list name='invisible-to-from'>
      <item type='subscription'
            value='from'
            action='deny'
            order='1'>
        <presence-out/>
      </item>
      <item action='allow' order='2'>
        <presence-out/>
      </item>
    </list>
  </query>
</iq>

<iq from='bilbo@tolkien.lit/shire' type='set' id='active9'>
  <query xmlns='jabber:iq:privacy'>
    <active name='invisible-to-from'/>
  </query>
</iq>
      

The foregoing privacy list allows outbound presence notifications to every JID except those that are in the user's roster with a subscription type of "to". Outbound presence stanzas of type "unavailable" are sent accordingly.

3.5 Become Globally Invisible

In order to become globally invisible again, the user simply sets as active the global invisibility list previously defined:

Example 15. User Becomes Globally Invisible

<iq from='bilbo@tolkien.lit/shire' type='set' id='active10'>
  <query xmlns='jabber:iq:privacy'>
    <active name='invisible'/>
  </query>
</iq>
    

4. Implementation Notes

The foregoing text explains the protocol used to implement invisibility. Naturally, client developers will most likely want to hide these protocol details from the end user. For example, rather than forcing the end user to navigate the details of privacy list management, a client could simply provide a "Go Invisible" button that sets as active the appropriate privacy list.

Note well that the privacy lists used to implement invisibility SHOULD be active lists and not the default list.

To help ensure cross-client compatibility, it is RECOMMENDED to use the privacy list names "visible" and "invisible" for simple global visibility and invisibility respectively. It is also RECOMMENDED to use list names of the form "visible-to-GroupName" and "invisible-to-JID" for simple lists that implement visibility or invisibility with regard to roster groups and JIDs. Obviously list names could become rather complex, such as "visible-to-Group1 Group2 Group3". Implementations MUST NOT attempt to derive semantic meaning from privacy list names; these recommendations are provided for ease of use only with regard to basic privacy lists related to visibility/invisibility.

In general it is probably easiest for users to become visible/invisible either globally or based on roster group, since these models are conceptually simple. Although, naturally, a client developer cannot tell users what to do, it probably best to encourage the use of conceptually simple models for privacy lists.

Privacy lists can become complex and must be carefully managed by clients. For example, let us imagine that the user is currently applying another active list unrelated to visibility (e.g., a list that blocks communications with a stalker); if the user then clicks "Go Invisible" and the client is not smart, it could overwrite the stalker blocking. Therefore, if the user has an active list that incorporates rules other than those related to visibility/invisibility, the client SHOULD either assume that visibility/invisibility is an overlay on the list currently in use (generating an appropriate privacy list that takes both into account) or prompt the user regarding their intentions. In the absence of privacy lists unrelated to visibility/invisibility, the client may proceed in a less cautious fashion.

5. Security Considerations

For security concerns related to privacy lists, refer to XMPP IM. Care must be taken regarding privacy lists, especially so that visibility/invisibility rules do not overwrite existing rules the user has set for the sake of security and privacy; see the "Implementation Notes" for details.

It is important to recognize that invisibility can be defeated without more advanced privacy lists than those defined above and an awareness of context on the part of a client. For example, a contact can send an IQ request to a user's usual full JID using Last Activity [3], Entity Time [4], or Software Version [5] and receive a reply, thus providing information that reveals the user's availability. In addition, Last Activity requests to the user's bare JID will normally reveal the user's availability as well. To help ensure that the user's invisibility cannot be defeated in this way, the user's client SHOULD add IQ blocking to the relevant privacy list. Finally, the user's client SHOULD NOT return "is-composing" events as defined in Message Events [6] or Chat State Notifications [7].

6. IANA Considerations

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

7. Jabber Registrar Considerations

No namespaces or parameters need to be registered with the Jabber Registrar [9] as a result of this JEP.

8. Formal Definition

The XML schema for the 'jabber:iq:privacy' namespace is contained in XMPP IM.


Notes

1. RFC 3920: Extensible Messaging and Presence Protocol (XMPP): Core <http://www.ietf.org/rfc/rfc3920.txt>.

2. RFC 3921: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence <http://www.ietf.org/rfc/rfc3921.txt>.

3. JEP-0012: Last Activity <http://www.jabber.org/jeps/jep-0012.html>.

4. JEP-0090: Entity Time <http://www.jabber.org/jeps/jep-0090.html>.

5. JEP-0092: Software Version <http://www.jabber.org/jeps/jep-0092.html>.

6. JEP-0022: Message Events <http://www.jabber.org/jeps/jep-0022.html>.

7. JEP-0085: Chat State Notifications <http://www.jabber.org/jeps/jep-0085.html>.

8. 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/>.

9. The Jabber Registrar maintains a list of reserved Jabber protocol namespaces as well as registries of parameters used in the context of protocols approved by the Jabber Software Foundation. For further information, see <http://www.jabber.org/registrar/>.


Revision History

Version 1.0 (2004-03-05)

Per a vote of the Jabber Council, advanced status to Active. (psa)

Version 0.4 (2004-02-10)

Minor editorial clarifications. (psa)

Version 0.3 (2004-01-22)

Added client responsibility for sending last available or unavailable presence. (psa)

Version 0.2 (2004-01-21)

Added more detail to the Security Considerations. (psa)

Version 0.1 (2004-01-08)

Initial version. (psa)


END