Notice acknowledgement token specification
These files are part of the DACS suite.
The \m[blue]dacs_notices(8)\m[]\s-2\u[1]\d\s+2 web service implements selected parts of this specification.
This document specifies the syntax and semantics of the Notice Acknowledgement Token (NAT), which is used by parts of DACS and may be of use to other systems. Interoperating systems that adopt this specification will be able to understand NATs produced by any of the systems and will therefore be capable of avoiding unnecessary user prompting.
A system is not required to honour or even recognize another system's NAT, but doing so may benefit users.
Purpose
Some web service providers have a requirement that users must acknowledge some form of notice before access can be granted to an associated resource, in addition to usual access control constraints. A user attempting to access such a resource is shown a web page containing a notice (or notices) and asked to acknowledge reading it or accept its conditions, typically by performing an action indicating acceptance, and submitting an HTML form. These notices are commonly legal notices, such as copyright notices, licensing notices, restricted access notices, and terms-of-use notices. This idea can also be applied to alerting users (a warning about upcoming system maintenance, for example).
For the convenience of users, once an acknowledgement has been obtained by the system the user should not be re-prompted when the same resource is subsequently accessed. The user might be re-prompted, however, should there be configuration changes (e.g., a notice is revised) or if the acknowledgement is deemed to have expired. To achieve this, state information must be maintained such that the access control mechanism is able to determine which, if any, acknowledgements for a particular resource have already been obtained.
State information used to record an acknowledgement event is called a Notice Acknowledgement Token (NAT) in this document.
Design Elements
Different web service providers will have different types of web services and require solutions that differ in their details. A well-designed solution architecture will therefore need to support a spectrum of requirements. Some applications will involve saving state on the client, some will require state to be saved on the server only, and others will need a combination of both approaches.
Saving state purely on the server assumes that the server has a means of identifying a client and associating persistent state with him. Upon receiving a service request, the server knows who the client is and can retrieve the client's state, including notice acknowledgement history.
Saving state purely on the client has the advantage of requiring no maintenance of state at the server, thereby reducing its complexity. For brower-based applications, HTTP cookies will be the usual mechanism for maintaining state at the client; after being returned by the server, notice acknowledgement tokens will thereafter be automatically transmitted by the browser together with future requests. Because browsers have implementation-dependent limits on the number of cookies (total, and per-server or domain name), as well as the maximum cookie size, the principle failing of this approach is that a browser may unilaterally delete HTTP cookies, thereby "forgetting" notice acknowledgements. HTTP cookies also have the disadvantage of being tied to a specified domain name, which may limit how notice acknowledgement tokens can be shared among servers.
A combined approach shares the advantages and disadvantages of the individual approaches, but reduces memory requirement at the client. Rather than storing all of the information at the client, the client is given a much smaller data structure that is essentially just a pointer to information maintained at the server.
Our concern here is specifying the syntax and semantics of client-side state information in support of building notice acknowledgement architectures.
The following features are examples of the kinds of functionality that a web service provider might want:
One or more notices may need to be associated with a single resource.
The same notice(s) may apply to multiple resources but those resources may have different access control requirements.
A different notice (or notices) may apply to resources having identical access control requirements.
If a new notice is added for a resource, a user having previously accessed the resource and acknowledged its notice should be presented with (only) the new notice upon his next access.
If a notice is modified for a resource, a user having previously acknowledged the notice should be presented with the modified notice upon his next access.
It may be necessary to periodically require users to re-acknowledge a notice (acknowledgements may expire).
Whether any notices exist for a particular resource, and exactly which notices must be shown, can be very simple or highly application- and data-dependent. A solution will therefore sometimes involve the web service provider having to write some custom code to supply this information.
Obtaining the appropriate notice to be presented to a user may be as simple as retrieving the contents of a file. But notices may need to be generated on the fly by a program and therefore ought to be named by, and obtained through, URLs.
Safeguards may be required to ensure that it is difficult to bypass the notice acknowledgement mechanism.
Safeguards may be required to ensure that information within a notice acknowledgement token remains private.
State information must be extensible to accommodate future and unforeseen needs.
Terminology
We use the terms "web server", "server", and "application" interchangeably to refer to an entity that receives and processes web service requests.
We use the terms "client", "user", "user agent", and "browser" to refer to an entity that generates web service requests and transmits them to a server.
A resource that can be associated with an acknowledgement is identified by a URI (\m[blue]RFC 2396\m[]\s-2\u[2]\d\s+2, \m[blue]RFC 3986\m[]\s-2\u[3]\d\s+2).
Notational Conventions
The Augmented BNF of \m[blue]RFC 2616\m[]\s-2\u[4]\d\s+2 (Section 2.1) is used to specify syntax.
Summary
The remainder of this document specifies the NAT, a system-independent data structure for representing and sharing notice acknowledgement state information. The NAT provides a simple, extensible representation of an acknowledgement event. For environments where security and tamper-resistance are required, appropriate elements are defined; environments where this is not required need not use or implement these capabilities. The NAT can be transmitted with a request as the payload of an HTTP cookie or the value of an HTTP extension header. Cooperating web services that follow this specification will be capable of understanding each other's NATs.
The format of a NAT is described in this section. NATs are constructed by a server either strictly for its own use or with the intent of sharing state information amongst a set of cooperating servers.
Servers that fulfill part or all of a user's service request by making one or more service requests to other servers ("cascaded operation") are required to forward NATs provided to them by the user or another server. When used in this environment, and any environment where servers are loosely associated, an implementation must select NAT attribute types carefully to maximize interoperability.
A server is free to ask a client to delete a NAT (e.g., by setting an expired cookie with the same name) or replace a NAT with a newer instance.
NAT Syntax
A notice acknowledgement token has the following general format:
nat = nat-name "=" nat-value
Following \m[blue]RFC 2109\m[]\s-2\u[5]\d\s+2 (Section 4.3.4), an (unordered) set of NATs is represented as
nats = nat *((";" | ",") nat)
That is, two or more NATs can be combined for transmission by separating them with a ";" or "," character.
A NAT with an invalid nat-name or nat-value is ignored.
nat-value = mime_encode(unsecure-nat) | mime_encode(secure-nat) nat-name = token unsecure-nat = av-pairs secure-nat = hmac hmac-nat hmac = "HMAC=<">" hmac-value <"> hmac-nat = ";" clear-nat ";" enc-method(av-pairs) clear-nat = *1("Version=<">" version <"> ";") "Secure=<">" enc-method <">
Security
The secure-nat syntax, which is optional, has been carefully designed to be secure, incur reasonable encoding overhead, and simplify implementation. The secure-nat syntax is used to protect integrity and provide privacy. Integrity is guarded through a cryptographically-secure keyed message authentication code; in addition, attributes may optionally be kept private by encipherment.
In the absence of precautions to maintain privacy, inspection of NATs can reveal a portion of a user's access history. In situations where NATs are not transmitted over secure end-to-end connections, such as those that can be provided by SSL, the secure-nat syntax should be considered. Definitions of encryption and message digest algorithms, and sharing and management of encryption keys are outside the scope of this document.
The mime_encode function represents the application of base-64 encoding to the given syntactical element (see \m[blue]Section 2.6\m[]\s-2\u[6]\d\s+2). This encoding prevents elements of the cookie value from conflicting with the syntax of the Cookie header or an HTTP message-header and allow binary data to be sent reliably over networks and heterogeneous platforms.
av-pairs = av-pair *(";" av-pair) av-pair = attr-name "=" attr-value attr-name = token attr-value = quoted-string quoted-string = <"> text-subset <"> text-subset = <any TEXT except separators> TEXT = *<any CHAR except CTLs but including SP> escaped-char = "%" HEXDIGIT HEXDIGIT HEXDIGIT = "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT DIGIT = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" HEXSTRING = 1*(HEXDIGIT) token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> CHAR = <any US-ASCII character (octets 0 - 127)>
Attributes (attr-name) are case-insensitive. One or more spaces are permitted before and/or after a ";" and before and/or after a "=".
An attr-value can contain arbitrary OCTETs through the escaped-char syntax. A literal "%" character must itself be escaped as the three characters "%25" and a literal ";" character must be escaped as "%3b".
This syntax allows a NAT to appear as the value of the Cookie request header or of an HTTP extension header. It is beyond the scope of this document how NATs are passed from system to system, however.
NAT Names
It is recommended that NAT names (nat-name) begin with the four-character long prefix "NAT-" so that they can be readily recognized. For example, HTTP Cookie headers bearing two NATs might use any of the following cookie name syntaxes:
Cookie: NAT-METALOGIC=... ; NAT-DSS=... Cookie: NAT-METALOGIC.COM=... ; NAT-DSS.CA=... Cookie: NAT-METALOGIC.COM-17=... Cookie: NAT-METALOGIC.COM-WMS-17=...
The goal in selecting a syntax is to provide a way for applications to quickly locate NATs that they generated or are interested in. Since a server may issue multiple NATs as HTTP cookies, each such cookie must have a distinct nat-name. This may be achieved by appending a sequence number, time of day, or hash value, for example.
NAT Reserved Attributes
All of the attribute names (attr-name) defined in this section are reserved. All of the attributes are optional, except HMAC and Secure, which are required only when forming a secure-nat.
An implementation may use syntactically valid, unreserved attribute names for its own purposes. Unrecognized and invalid attribute names should be ignored by servers. Attribute names are case insensitive. The relative ordering of attributes is immaterial, except as stated otherwise.
A syntactically invalid nat will be ignored. If duplicate attribute names appear in a nat, a server should treat the nat as invalid and ignore it.
A resource-uri, which is used below, is defined as follows:
resource-uri = URI | relative-uri | uri "/*" | relative-uri "/*"
Attribute Name: CreatorURI (optional) Attribute Value: a URI
This URI identifies the server, application, or jurisdiction that created this NAT. If it is an absolute URI, it also establishes a base URI for relative URIs within this NAT. Examples:
CreatorURI="https://example.com:8443" CreatorURI="http://example.com/cgi-bin/dacs" CreatorURI="MYFED::MYJURISDICTION"
Attribute Name: BaseURI (optional) Attribute Value: a URI
This absolute URI establishes a base URI for relative URIs within this NAT. If CreatorURI is present, this URI overrides it as the base URI. Examples:
BaseURI="https://example.com:8443" BaseURI="http://example.com/cgi-bin/dacs"
Attribute Name: ResourceURIs (optional) Attribute Value: resource-uri *(SP resource-uri)
This attribute identifies one or more resources that have been acknowledged (that is, for which one or more acknowledgements have been received). If resource-uri is an absolute URI, it identifies the resource. If resource-uri is a relative-uri and neither the BaseURI nor the CreatorURI attribute are present, the implied default base URI is effectively "any server". For example, if no BaseURI and CreatorURI attributes are present, a relative-uri of "/index.html" refers to a resource of that name anywhere. This behaviour can be useful in environments where web content and resource naming are coordinated across servers.
If a resource-uri ends in the two characters "/*", it refers to all URI that are subordinate or equivalent to the absolute or relative URI. Either or both of the characters "/*" may be URL-encoded ("/" by "%2f" and "*" by "%2a") to prevent this interpretation. Refer to \m[blue]Section 2.4\m[]\s-2\u[7]\d\s+2.
It is possible for a particular resource to be known by more than one URI. There is no requirement for two distinct URI to be recognized as referring to the same resource, therefore each may need its own acknowledgement. It is left to each server to decide whether a request URI matches a resource-uri. For example, domain names may not need to match exactly, such as when a web site is mirrored, or some general mapping might be applied to determine whether a request URI matches a resource-uri.
Example: ResourceURIs="https://example.com/index.html" -- This identifies a single web page. Example: ResourceURIs="/foo.html /bar.html /baz.html" -- If BaseURI="https://example.com", ResourceURIs identifies https://example.com/foo.html, https://example.com/bar.html, and https://example.com/baz.html. Example: ResourceURIs="/images/*" -- Assuming that BaseURI="https://example.com", this specifies all URI that are subordinate or equivalent to the absolute URI https://example.com/images, such as https://example.com/images/dog.gif, https://example.com/images/lines/dotted.gif, and https://example.com/images. Example: ResourceURIs="https://example.com/*" -- This identifies all URI under https://example.com. Example: ResourceURIs="https://example.com/foo/%2a" -- This specifies exactly one URI, namely https://example.com/foo/*. Example: ResourceURIs="https://example.com/foo*" -- This specifies exactly one URI, namely https://example.com/foo*.
Attribute Name: Version (optional) Attribute Value: "1"
This attribute specifies the version of the specification used for this nat-value. If present, this attribute must appear first. If absent, the attribute defaults to:
Version="1"
The only attr-value permitted by this version is "1".
Attribute Name: Secure (required for secure-nat) Attribute Value: "no" | enc-method
If the value is "no", the av-pairs have not been encrypted and no HMAC attribute is present. A value other than "no" describes the method used to encrypt the following text and the digest algorithm used to compute the value of the HMAC attribute. Its syntax, borrowed from that used by \m[blue]OpenSSL\m[]\s-2\u[8]\d\s+2, is:
cipher-name *1(cipher-mode) *1(digest-name)
Examples of enc-method: aes128-cbc-sha1, aes128-cfb, aes192-cbc, aes256-ofb, des-md5, des3, desx-sha256
Attribute Name: HMAC (required for secure-nat) Attribute Value: hmac-value
This is the Keyed-Hash Message Authentication Code (HMAC), represented as a HEXSTRING, computed using the digest algorithm specified or implied by the Secure attribute's value and computed over hmac-nat. SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 are recommended for this purpose. The HMAC is used to authenticate the NAT and protect integrity by detecting tampering.
Attribute Name: State (optional) Attribute Value: a URI | local-state-identifier
This attribute identifies server-side state information for this NAT. Rather than building a large NAT, the creator of the NAT may construct a NAT that simply points to state information. There are two types of state information: public and private.
Public state:
If the attr-value is a URI, it identifies a resource that contains additional information (TBD, but presumably it is an XML document). Other cooperating servers may be able to use this URI to obtain attributes described here but not included in the NAT at the discretion of the creating server. (TBD: this service might be used to decrypt and/or validate a NAT associated with it)
Private state:
If the attr-value is not a URI (e.g., it is not prefixed by a recognized scheme), it identifies information local to the creating server (not available to other servers). This might be a unique database key, for example.
Attribute Name: NoticeURIs (optional) Attribute Value: notice-uri *(SP notice-uri) where notice-uri = a URI | relative-uri
This is a space-separated list of URIs, each of which represents the text of a notice that is associated with ResourceURIs and that has been acknowledged by the user. Each relative-uri is relative to the CreatorURI, which must be provided. To test if a notice-uri matches the URI of a notice associated with a service request, the two URI are compared for equality.
Attribute Name: NoticeDigestMethod (optional) Attribute Value: digest-name
This attribute value is the digest algorithm (see the Secure attribute) used to compute the NoticeDigest attribute value elements. If not provided, the digest-name given by the Secure attribute's value must be available and will be used; a weaker but more efficiently computed digest might be sufficient for this purpose, however, such as a 32-bit CRC or MD5.
Attribute Name: NoticeDigest (optional) Attribute Value: a space-separated list of HEXSTRINGs
This is a space-separated list of HEXSTRINGs, each corresponding to an element of NoticeURIs, that is the message digest of that NoticeURIs computed using NoticeDigestMethod (or failing that, the algorithm given by the Secure attribute's value). There must be exactly as many elements in this list as are in NoticeURIs, otherwise the NAT is invalid. The purpose of this attribute is to help detect if any NoticeURIs has changed and therefore might need to be acknowledged by the user again.
Attribute Name: Expires (optional) Attribute Value: a date string
This is a date field, as specified in the Netscape HTTP Cookie Spec:
Wdy, DD-Mon-YYYY HH:MM:SS GMT
While clients are advised of the lifetime of an HTTP cookie at the time it is issued, nothing compels a client to destroy the cookie at that time. An explicit expiry date can be enforced by a server, however, and can be used with mechanisms other than HTTP cookies. The NAT is invalid if this field is incorrectly formatted.
URI Matching
For an otherwise valid NAT to potentially be applicable to the URI of a service request, one of the NAT's resource-uri must either be the same as the service request URI or, if a resource-uri ends in "/*", match as an ancestor of the URI. The latter case is called a "wildcard match".
The URIhttps://example.com/cgi-bin, for example, is considered to be an ancestor or parent of the URI "https://example.com/cgi-bin/program". The former URI's path component has two elements, the latter has three elements. The one-element URI path "/" is considered to be the ancestor of all other paths.
The "*" operator, which matches zero or more elements, has special meaning only when it appears as a path element at the end of a resource-uri. For instance, the URI path "/cgi-bin/*" is considered to be the ancestor of all paths having the prefix "/cgi-bin/" and matches service requests for "/cgi-bin/printenv", "/cgi-bin/", and "/cgi-bin".
Before matching a service request URI against NATs, the URI is converted into a canonical form. Any trailing "/" characters are stripped off. As a special case, the URI path "/" is unchanged.
The server examines the resource-uri of NATs to find one having the most specific URI path that applies to the service request URI; that is, it conducts a search to find the resource-uri that has the greatest number of components in common with the service request. If no exact match is found, the search will consider increasingly general resource-uri. The resource-uri that matches the URI most closely (i.e., has the greatest number of matching components) determines the applicable NAT, if any.
If two or more resource-uri "tie" (e.g., because of duplicates), one will be chosen arbitrarily.
Cryptographic Elements
This section and its subsections have not been completed.
Encryption Algorithms.
Message Digest Algorithms.
HMAC - Keyed Message Authentication Code.
Encryption.
Encoding for Transport
To ensure that a NAT can be safely transmitted between systems, it is encoded using Base64 Content-Transfer-Encoding, as specified by \m[blue]RFC 2045\m[]\s-2\u[9]\d\s+2 (Section 6.8). While not providing additional security, this encoding offers some protection against casual inspection of NAT contents.
NAT HTTP Header Syntax
A NAT need not be transmitted as the payload of an HTTP cookie, although that will likely be the most common method. Instead, NATs can be transmitted using an HTTP entity-header extension header. The field name "NoticeAcknowledgements" is recommended:
NoticeAcknowledgements: NAT-METALOGIC=..., NAT-DSS=...
Like all entity-headers, this name is case-insensitive.
This header may not be repeated unless "," is used as the separator instead of ";". See \m[blue]RFC 2616\m[]\s-2\u[4]\d\s+2 (Section 4.2).
Multiple NATs
When there are multiple NATs, no relative ordering is imposed. In the event that more than one NAT in a list corresponds to the same resource, the resulting behaviour is undefined and may depend on the order in which the NATs are processed.
Resource Name Mapping
It is up to a server whether the acknowledgement of a particular notice for one resource can automatically be applied to another resource. For example, suppose that a user acknowledges notice N1 upon requesting resource R1. Subsequently, the user requests resource R2 from the server and it happens that notice N1 also applies to R2, although this fact is not recorded in a NAT. It is implementation and context dependent in cases like this whether the server requires the user to acknowledge N1 again specifically for R2 or automatically accepts the earlier acknowledgement. Similarly, if a user's NATs collectively indicate that all notices associated with a request have been acknowledged but no single NAT asserts this for the request, the outcome is server-dependent.
NAT Creation and Merging
Although a NAT may exist that indicates that an acknowledgement has already been obtained, a server may issue a new, more specific NAT or a NAT with a different Expires field. For example, in the example scenario described in the \m[blue]previous section\m[]\s-2\u[10]\d\s+2, a server might replace the existing NAT for R1 with one that lists both R1 and R2.
A server may return multiple NATs, adding new ones and deleting or replacing existing ones.
Case Sensitivity
The path components of two URI are compared case sensitively. The scheme and authority components are compared case insensitively.
Server Autonomy
Having received a NAT as a result of accessing a given resource, a client should not assume that a later request for the same resource will not involve notice acknowledgements. A server may arbitrarily decide that acknowledgements are needed, a notice may have been modified, a new notice may have been added, or the NAT may have expired.
Minimal Implementation
A minimal server implementation would issue and recognize NATs that consist simply of a base-64 encoded ResourceURIs attribute:
"NAT-DSS=" mime_encode("ResourceURIs=" ResourceURIs)
Middleware Support
In support of thick clients and middleware architectures, an implementation might include two useful web services:
NAT creation request
An authorized client would request that a NAT be created by the server and returned. The request's arguments would describe the content of the NAT and possibly select a format for the returned NAT (HTTP cookie, HTTP header, XML document, and so on)
NAT decoding request
An authorized client, sending a NAT as an argument to this web service, would receive an indication of whether the NAT was valid and of its contents (e.g., as an XML document).
These hypothetical services are not described further here.
\m[blue]dacs_notices(8)\m[]\s-2\u[1]\d\s+2
Distributed Systems Software (\m[blue]www.dss.ca\m[]\s-2\u[11]\d\s+2) and \m[blue]Metalogic Software Corp.\m[]\s-2\u[12]\d\s+2
Note
Dss and Metalogic, the authors of this specification, hereby permit anyone to implement this specification without fee or royalties.
Copyright2003-2012 Distributed Systems Software. See the \m[blue]LICENSE\m[]\s-2\u[13]\d\s+2 file that accompanies the distribution for licensing information.
http://dacs.dss.ca/man/dacs_notices.8.html
RFC 2396
http://www.rfc-editor.org/rfc/rfc2396.txt
RFC 3986
http://www.rfc-editor.org/rfc/rfc3986.txt
RFC 2616
http://www.rfc-editor.org/rfc/rfc2616.txt
RFC 2109
http://www.rfc-editor.org/rfc/rfc2109.txt
Section 2.6
http://dacs.dss.ca/man/#Encoding
Section 2.4
http://dacs.dss.ca/man/#URI-matching
OpenSSL
http://www.openssl.org
RFC 2045
http://www.rfc-editor.org/rfc/rfc2045.txt
previous section
http://dacs.dss.ca/man/#resource-name-mapping
www.dss.ca
http://www.dss.ca
Metalogic Software Corp.
http://fedroot.com/admin/about-metalogic.shtml
LICENSE
http://dacs.dss.ca/man/../misc/LICENSE