Operators of XMPP services are sometimes required, for legal or policy reasons, to obtain a user's explicit acceptance of a terms-of-service document before letting that user access the service, and to be able to demonstrate that the currently-applicable version of that document was the one accepted.
Today this is typically handled outside of the XMPP authentication exchange itself, for example through an out-of-band web flow, or by nagging the user post-login with no guarantee they ever comply. Neither gives the server a reliable way to withhold a session from an account that has not accepted the current terms.
Extensible SASL Profile (XEP-0388) [1] defines a generic mechanism, the SASL2 "task" flow, by which a server can insert one or more additional steps between the completion of a SASL exchange and the completion of the SASL2 negotiation, using the <continue/>, <next/> and <task-data/> elements it defines. Nothing that marks a session as authenticated may occur until every such task has completed. This specification defines one concrete task, built on that mechanism, for the purpose of requiring acceptance of a versioned terms-of-service document.
This document defines only the task itself: its namespace, its elements, and the rules governing when it applies and how its outcome is determined. How a task is offered, selected, and driven to completion or failure in general is defined by Extensible SASL Profile (XEP-0388) [1].
This specification defines the urn:xmpp:tos:0 namespace, used to qualify the elements defined below, and one SASL2 task, identified in <task/> and <next/> elements by the token TOS-ACCEPT.
Once the SASL exchange has succeeded, the server determines whether this task applies to the authenticating account, per the following rules (see also Business Rules):
When the task applies, the server offers it as it would any SASL2 task, in a <continue/> element. It MUST include human-readable <text/> explaining why authentication has not yet completed.
<continue xmlns='urn:xmpp:sasl:2'>
<tasks>
<task>TOS-ACCEPT</task>
</tasks>
<text>The terms of service have changed and must be accepted before you can sign in.</text>
</continue>
<next xmlns='urn:xmpp:sasl:2' task='TOS-ACCEPT'/>
On selection, the server sends the current terms in a <task-data/> element, carrying a <terms/> element. Its content is the URL at which the terms can be read, and its version attribute identifies the version being offered for acceptance.
<task-data xmlns='urn:xmpp:sasl:2'> <terms xmlns='urn:xmpp:tos:0' version='2026-01'>https://example.org/terms</terms> </task-data>
The client responds with a <task-data/> element of its own. To accept, it includes an <accept/> element whose version attribute repeats the version it was offered.
<task-data xmlns='urn:xmpp:sasl:2'> <accept xmlns='urn:xmpp:tos:0' version='2026-01'/> </task-data>
A peer that does not wish to accept, or that does not implement this task at all, has no way to decline while continuing the negotiation: per Extensible SASL Profile (XEP-0388) [1], it can only abort, which fails the entire SASL2 negotiation and leaves the session unauthenticated.
<abort xmlns='urn:xmpp:sasl:2'/>
On receiving the client's response, the server determines the outcome per the following rules:
<accept/> element, the server MUST fail the SASL2 negotiation with a <not-authorized/> condition.<accept/> element whose version attribute does not match the version that was offered in this round, the server MUST fail the SASL2 negotiation with a <malformed-request/> condition (rejecting, for example, a value cached from an earlier attempt).Once every eligible task, including this one, has completed, the SASL2 negotiation concludes as usual with <success/>.
version identifiers it issues as opaque and SHOULD compare them for exact equality, both when checking whether a previously-recorded acceptance is still current and when validating a peer's <accept/> against the version it was offered in the same round.This task is a policy and record-keeping mechanism, not an authentication factor. It MUST NOT be treated as contributing to the strength of the authentication that preceded it, and does not protect against an attacker who already holds valid credentials: by the time this task runs, the SASL exchange has already succeeded.
This task, like any SASL2 task, is only evaluated as part of a SASL2 negotiation. If a server also offers an authentication path that bypasses SASL2 entirely, for example the legacy SASL profile of RFC 6120, an account can authenticate through that path without this, or any other, SASL2 task ever being evaluated. A server that needs to guarantee acceptance before granting access MUST NOT offer such a path to accounts this task applies to, or MUST enforce the same requirement by some other means there. This limitation applies equally to any mandatory SASL2 task, not just this one.
A server that cannot durably persist an acceptance, for example due to a transient failure of its own backing store, MAY still let the negotiation continue rather than fail it outright (see Outcome): the peer did explicitly accept during this negotiation, which is what the task exists to establish. Since no durable record exists in that case, the server SHOULD offer the task again on the account's next authentication attempt, so that a persistence failure results in the user being asked again rather than the requirement being silently and permanently bypassed.
Because completion of this task changes an account's compliance record, a server SHOULD only offer, and only accept a response to, this task over a channel that satisfies its usual requirements for authenticated sessions, per whatever channel-binding or TLS policy already governs the SASL2 negotiation in which it is offered; this specification does not introduce a separate requirement.
The terms URL communicated in the <terms/> element is typically dereferenced by a human outside of the XMPP session (for example by opening it in a browser). Server operators should serve it over a secure and integrity-protected transport, but validating that is outside the scope of this specification.
This document requires no interaction with the Internet Assigned Numbers Authority (IANA).
This specification defines the following XML namespace, which the XMPP Registrar shall add to its registry of protocol namespaces (XMPP Registrar Function (XEP-0053) [2]):
This specification also defines the SASL2 task token TOS-ACCEPT. Extensible SASL Profile (XEP-0388) [1] defines no central registry of task tokens; as with the UPGR-* tokens defined by SASL Upgrade Tasks (XEP-0480) [3], uniqueness is expected to follow from the token being sufficiently distinctive, checked against existing task-defining specifications during the XSF's normal review process.
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:tos:0'
xmlns='urn:xmpp:tos:0'
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='terms'>
<xs:annotation>
<xs:documentation>
Identifies the current terms of service. Sent by the server, as the
content of a <task-data/> element, after this task has been selected.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:anyURI'>
<xs:attribute name='version' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name='accept'>
<xs:annotation>
<xs:documentation>
Sent by the client, as the content of a <task-data/> element, to accept
the identified version of the terms of service.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:attribute name='version' type='xs:string' use='required'/>
</xs:complexType>
</xs:element>
</xs:schema>
This document in other formats: XML PDF
This XMPP Extension Protocol is copyright © 1999 – 2024 by the XMPP Standards Foundation (XSF).
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.
## 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. ##
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.
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).
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.
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.
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>.
The key words "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 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
1. XEP-0388: Extensible SASL Profile <https://xmpp.org/extensions/xep-0388.html>.
2. XEP-0053: XMPP Registrar Function <https://xmpp.org/extensions/xep-0053.html>.
3. XEP-0480: SASL Upgrade Tasks <https://xmpp.org/extensions/xep-0480.html>.
Note: Older versions of this specification might be available at https://xmpp.org/extensions/attic/
First draft.
@report{der kinderen2026xepxxxx,
title = {SASL2 Terms of Service Acceptance Task},
author = {der Kinderen, Guus},
type = {XEP},
number = {xxxx},
version = {0.1.3},
institution = {XMPP Standards Foundation},
url = {https://xmpp.org/extensions/xep-xxxx.html},
date = {2026-09-12/2026-09-12},
}END