DESCRIPTION
These files are part of the DACS suite.
The m[blue]dacs_notices(8)m[][1] web service implements selected parts of this specification.
Introduction
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.
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.
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:
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 2396m[]
The Augmented BNF of
m[blue]RFC 2616m[]
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.
Purpose
[2],
m[blue]RFC 3986m[][3]).
[4]
(Section 2.1) is used to specify syntax.
The Notice Acknowlegement Token
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.
A notice acknowledgement token has the following general format:
NAT Syntax
nat = nat-name "=" nat-value
Following m[blue]RFC 2109m[][5] (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.6m[][6]). 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.
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:
NAT Names
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.
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:
NAT Reserved Attributes
resource-uri = URI | relative-uri | uri "/*" | relative-uri "/*"
-
1.
-
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"
-
-
2.
-
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"
-
-
3.
-
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.4m[][7].
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*.
-
-
4.
-
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".
-
-
5.
-
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]OpenSSLm[][8], 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
-
-
6.
-
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.
-
-
7.
-
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.
-
1.
-
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)
-
-
2.
-
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.
-
-
-
8.
-
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.
-
-
9.
-
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.
-
-
10.
-
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.
-
-
11.
-
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.
-
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.
This section and its subsections have not been completed.
Encryption Algorithms.
Message Digest Algorithms.
HMAC - Keyed Message Authentication Code.
Encryption.
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 2045m[]
URI Matching
[9]
(Section 6.8). While not providing additional security, this encoding offers some protection against casual inspection of
NAT
contents.
Implementation Notes
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:
NAT HTTP Header Syntax
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 2616m[][4] (Section 4.2).
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.
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.
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 sectionm[]
A server may return multiple
NATs, adding new ones and deleting or replacing existing ones.
The path components of two
URI
are compared case sensitively. The scheme and authority components are compared case insensitively.
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.
A minimal server implementation would issue and recognize
NATs that consist simply of a base-64 encoded
ResourceURIs
attribute:
Multiple NATs
[10], a server might replace the existing
NAT
for
R1
with one that lists both
R1
and
R2.
"NAT-DSS=" mime_encode("ResourceURIs=" ResourceURIs)
In support of thick clients and middleware architectures, an implementation might include two useful web services:
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)
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.
Middleware Support
AUTHOR
Distributed Systems Software (m[blue]www.dss.cam[][11]) and m[blue]Metalogic Software Corp.m[][12]
-
Note
Dss and Metalogic, the authors of this specification, hereby permit anyone to implement this specification without fee or royalties.
COPYING
Copyright2003-2012 Distributed Systems Software. See the m[blue]LICENSEm[][13] file that accompanies the distribution for licensing information.
NOTES
- 1.
- dacs_notices(8)
- 2.
- RFC 2396
- 3.
- RFC 3986
- 4.
- RFC 2616
- 5.
- RFC 2109
- 6.
- Section 2.6
- 7.
- Section 2.4
- 8.
- OpenSSL
- 9.
- RFC 2045
- 10.
- previous section
- 11.
- www.dss.ca
- 12.
- Metalogic Software Corp.
- 13.
-
LICENSE