RFC 3341
The Application Exchange (APEX) Access Service
RFC 3341: The Application Exchange (APEX) Access Service โจ
Okay bestie, let's get the basics down first ๐
- Number: RFC 3341
- Title: The Application Exchange (APEX) Access Service
- Stream: Network Working Group
- Category: Standards Track, so this is an Internet standards track protocol ๐ฅ
- Date: July 2002
- Authors:
- M. Rose, Dover Beach Consulting, Inc.
- G. Klyne, Clearswift Corporation
- D. Crocker, Brandenburg InternetWorking
- Obsoletes / Updates: the title block doesn't list anything it obsoletes or updates ๐
Status of This Memo
Okay so this doc is an Internet standards track protocol for the whole Internet community, and it's literally asking people for discussion and suggestions for improvements ๐ซถ For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited ๐
Copyright Notice
Copyright (C) The Internet Society (2002). All Rights Reserved.
Abstract
Here's the vibe: this memo describes the Application Exchange (APEX) access service, which is addressed as the well-known endpoint apex=access ๐ฆ The access service is the one that controls use of both the APEX "relaying mesh" and other APEX services. Main character energy, honestly ๐
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Use and Management of Access Information . . . . . . . . . . . 3
2.1 Querying Access Information . . . . . . . . . . . . . . . . . 3
2.2 Retrieval of Access Information . . . . . . . . . . . . . . . 4
2.3 Update of Access Information . . . . . . . . . . . . . . . . . 5
3. Format of Access Entries . . . . . . . . . . . . . . . . . . . 9
3.1 Finding the Appropriate Entry: Matching Owners and Actors . . 11
3.2 Creating and Updating Access Entries . . . . . . . . . . . . . 14
4. The Access Service . . . . . . . . . . . . . . . . . . . . . . 14
4.1 Use of XML and MIME . . . . . . . . . . . . . . . . . . . . . 15
4.2 The Query Operation . . . . . . . . . . . . . . . . . . . . . 16
4.3 The Get Operation . . . . . . . . . . . . . . . . . . . . . . 17
4.4 The Set Operation . . . . . . . . . . . . . . . . . . . . . . 18
4.5 The Reply Operation . . . . . . . . . . . . . . . . . . . . . 20
5. Registration: The Access Service . . . . . . . . . . . . . . . 20
6. The Access Service DTD . . . . . . . . . . . . . . . . . . . . 21
7. Security Considerations . . . . . . . . . . . . . . . . . . . 23
References . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 24
A. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 25
Full Copyright Statement . . . . . . . . . . . . . . . . . . . 26
1. Introduction โจ
So this memo describes an access service that's built on top of the APEX [1] "relaying mesh" ๐ธ๏ธ The APEX access service is the thing that controls use of both the relaying mesh and other APEX services.
APEX is basically a best-effort datagram service at its core ๐ฆ Within one administrative domain, all relays must be able to handle messages for any endpoint in that domain. APEX services are logically defined as endpoints, but since they have such ubiquitous semantics, they don't necessarily have to be tied to a single physical endpoint. So they may be provisioned co-resident with each relay inside an administrative domain, even though they're logically provided on top of the relaying mesh, i.e.,
+----------+ +----------+ +----------+ +---------+
| APEX | | APEX | | APEX | | |
| access | | presence | | report | | ... |
| service | | service | | service | | |
+----------+ +----------+ +----------+ +---------+
| | | |
| | | |
+----------------------------------------------------------------+
| |
| APEX core |
| |
+----------------------------------------------------------------+
That is, applications talk to an APEX service by exchanging data with a "well-known endpoint" (WKE) ๐ง
APEX applications talk to the access service by exchanging data with the well-known endpoint apex=access in the matching administrative domain. For example, apex=access@example.com is the endpoint for the access service in the example.com administrative domain ๐
Note that within a single administrative domain, the relaying mesh uses the APEX access service to figure out whether an originator is allowed to transmit data to a recipient (c.f., Step 5.3 of Section 4.4.4.1 of [1]). Lowkey a very important job ๐ญ
2. Use and Management of Access Information ๐
Access information is organized around access entries. Each one contains:
- an owner: an APEX address that the entry is associated with;
- an actor: an APEX address that's granted permission to perform some action in the context of the owner;
- a list of actions; and,
- a timestamp showing when the service last created or modified the access entry.
The access entry for a given owner controls access to a potentially large range of different APEX services, like data delivery, access control, and presence information ๐ Section 4.5 of [1] also talks about APEX access policies that govern things like peer authentication, message relaying, and so on.
Managing access information falls into three categories:
- applications may query the access service to see if one or more actions are allowed;
- applications may retrieve access information associated with an owner/actor combination; and,
- applications may modify (i.e., create, replace, or delete) access information associated with an owner/actor combination.
Each one gets its own section, so let's go through them in order ๐
2.1 Querying Access Information
When an application wants to figure out whether one or more actions are allowed for an owner/actor combination, it sends a "query" element to the service. Like this ๐
+-------+ +-------+
| | -- data -------> | |
| appl. | | relay |
| | <--------- ok -- | |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='fred@example.com' />
<recipient identity='apex=access@example.com' />
<data-content Name='Content'>
<query owner='fred@example.com' transID='1'
actor='barney@example.com'
actions='core:data presence:subscribe' />
</data-content>
</data>
S: <ok />
The service responds right away with either an allow or a deny operation, and it uses the same transaction-identifier. "allow" means that all of the actions listed in the query are permitted ๐ For example:
+-------+ +-------+
| | <------- data -- | |
| relay | |access |
| | -- ok ---------> | svc. |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='fred@example.com' />
<data-content Name='Content'>
<allow transID='1' />
</data-content>
</data>
S: <ok />
or
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='fred@example.com' />
<data-content Name='Content'>
<deny transID='1' />
</data-content>
</data>
S: <ok />
2.2 Retrieval of Access Information
When an application wants to pull up the access entry for an owner/actor combination (usually so it can update that access information afterwards), it sends a "get" element to the service ๐ Here's how that looks:
+-------+ +-------+
| | -- data -------> | |
| appl. | | relay |
| | <--------- ok -- | |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='fred@example.com' />
<recipient identity='apex=access@example.com' />
<data-content Name='Content'>
<get transID='2'
owner='fred@example.com'
actor='*@example.com' />
</data-content>
</data>
S: <ok />
The service responds right away with a set operation that has the access entry and the same transaction-identifier ๐ง For example:
+-------+ +-------+
| | <------- data -- | |
| relay | |access |
| | -- ok ---------> | svc. |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='fred@example.com' />
<data-content Name='Content'>
<set transID='2'>
<access owner='fred@example.com'
actor='*@example.com'
actions='core:data presence:subscribe'
lastUpdate='2000-05-14T13:02:00-08:00' />
</set>
</data-content>
</data>
S: <ok />
2.3 Update of Access Information ๐
okay so this is where the access entries get updated ๐ซถ when an app wants to create or modify an access entry for an owner/actor combo, it sends a set element to the service with the new entry in it. here's the vibe:
+-------+ +-------+
| | -- data -------> | |
| appl. | | relay |
| | <--------- ok -- | |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='wilma@example.com' />
<recipient identity='apex=access@example.com' />
<data-content Name='Content'>
<set transID='1'>
<access owner='fred@example.com'
actor='*@example.com'
actions='core:data presence:subscribe'
lastUpdate='2000-05-14T13:02:00-08:00' />
</set>
</data-content>
</data>
S: <ok />
ngl the lastUpdate attribute is the main character here ๐ Step 4 of Section 4.4 says you need to supply lastUpdate in order to update an entry, so apps have to successfully retrieve an access entry before they try to modify it. no shortcuts bestie ๐ (and admins should make sure any app allowed to modify an entry is also allowed to retrieve it, iykyk ๐)
the service responds right away with a reply operation that has the same transaction-identifier:
+-------+ +-------+
| | <------- data -- | |
| relay | |access |
| | -- ok ---------> | svc. |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='wilma@example.com' />
<data-content Name='Content'>
<reply code='250' transID='1' />
</data-content>
</data>
S: <ok />
Steps 6.2 and 9.2 of Section 4.4 mean the access service has to update the lastUpdate attribute of an access entry whenever it's created or modified ๐ฆ
the service also immediately sends a set operation to the owner attribute tied to the access entry:
+-------+ +-------+
| | <------- data -- | |
| relay | |access |
| | -- ok ---------> | svc. |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='fred@example.com' />
<data-content Name='Content'>
<set transID='1'>
<access owner='fred@example.com'
actor='*@example.com'
actions='core:data presence:subscribe'
lastUpdate='2000-05-14T23:02:00-08:00' />
</set>
</data-content>
</data>
S: <ok />
now deleting ๐ฅ when an app wants to delete the access entry for an owner/actor combo, it sends a set element to the service leaving out the permitted actions:
+-------+ +-------+
| | -- data -------> | |
| appl. | | relay |
| | <--------- ok -- | |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='wilma@example.com' />
<recipient identity='apex=access@example.com' />
<data-content Name='Content'>
<set transID='2'>
<access owner='fred@example.com'
actor='*@example.com'
lastUpdate='2000-05-14T13:02:00-08:00' />
</set>
</data-content>
</data>
S: <ok />
the service immediately responds with a reply operation containing the same transaction-identifier:
+-------+ +-------+
| | <------- data -- | |
| relay | |access |
| | -- ok ---------> | svc. |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='wilma@example.com' />
<data-content Name='Content'>
<reply code='250' transID='2' />
</data-content>
</data>
S: <ok />
and then the service also immediately sends a set operation to the owner attribute on the access entry:
+-------+ +-------+
| | <------- data -- | |
| relay | |access |
| | -- ok ---------> | svc. |
+-------+ +-------+
C: <data content='#Content'>
<originator identity='apex=access@example.com' />
<recipient identity='fred@example.com' />
<data-content Name='Content'>
<set transID='2'>
<access owner='fred@example.com'
actor='*@example.com'
lastUpdate='2000-05-14T13:02:00-08:00' />
</set>
</data-content>
</data>
S: <ok />
Because there are no actions left on this access entry, the owner can tell it's been deleted ๐ซ
plot twist: deleting an access entry for one owner/actor combo might NOT actually remove permission ๐ญ that's because access control allows limited wildcarding of actors, so the delete can end up modifying permission instead. that's why there's a special action, all:none, to handle it.
for example, say we've got these two access entries:
<access owner='fred@example.com'
actor='barney@example.com'
actions='core:data presence:subscribe presence:watch'
lastUpdate='2000-05-14T13:20:00-08:00' />
<access owner='fred@example.com'
actor='*@example.com'
actions='core:data'
lastUpdate='2000-05-14T13:20:00-08:00' />
deleting the first one will not remove all permissions for the actor barney@example.com. instead, the first access entry should be modified like this:
<access owner='fred@example.com'
actor='barney@example.com'
actions='all:none'
lastUpdate='2000-05-14T13:20:00-08:00' />
3. Format of Access Entries โจ
okay now the structure ๐ง each administrative domain is responsible for keeping one or more "access entries" for each of its endpoints and their associated subaddresses, whether or not those addresses are currently attached to the relaying mesh.
you need a separate access entry for each actor, or group of actors, that you're giving access permission to. Section 6 defines the syntax for access entries. every access entry has an "owner" attribute, an "actor" attribute, an "actions" attribute, a "lastUpdate" attribute, and no content:
- the
ownerattribute is the address (endpoint or subaddress) the access entry belongs to; - the
actorattribute is an entity or group of entities that the access permissions apply to, as described below; - the
actionsattribute is the permissions granted to the actor in the context of the owner; and, - the
lastUpdateattribute is the date and time the service last created or modified the access entry.
an action is written as a service/operation pair, so presence:publish means the "publish" operation of the "presence" service. two service values are reserved:
- "all" refers to all services, e.g.,
all:data; and, - "core" refers to the service implemented by the relaying mesh, e.g., the
core:datapermission is consulted by the relaying mesh (c.f., Step 5.3 of Section 4.4.4.1 of [1]).
and two operation values are reserved too:
- "all" refers to all operations, e.g.,
presence:all; and, - "none" refers to no operations whatsoever, e.g.,
all:none.
an actor is an APEX address, written using the "entity" syntax from Section 2.2 of [1]. but both the "local" and "domain" parts can contain limited wildcarding ๐
- the "local" part is one of:
- a literal string (e.g.,
fred); - a subaddress wildcard (e.g.,
fred/*orapex=pubsub/*); or, - the value
apex=*, which means all APEX services; - the value
*, which means any address other than an APEX service.
- a literal string (e.g.,
- the "domain" part is one of:
- a FQDN (e.g.,
example.com); - a domain wildcard (e.g.,
*.example.com); or, - the value
*, which means all administrative domains.
- a FQDN (e.g.,
note that with a domain wildcard, the wildcard itself matches zero or more subdomains. so *.example.com matches example.com, foo.example.com, bar.foo.example.com, and so on.
every owner gets the following default entries ๐ but any explicitly supplied entry with the same actor value overrides them:
actor='local@domain' actions='all:all'
actor='apex=*@domain' actions='all:all'
actor='apex=*@*' actions='core:data'
actor='*@*' actions='all:none'
where local@domain is the owner the access entry is for.
for example, this explicit entry:
actor='*@*' actions='core:data'
lets endpoints from any domain use the relaying mesh to send data to the owner, but it does not override the default entry for apex=*@domain, which gives all APEX services in the owner's domain access to all actions ๐ฆ
fun fact: APEX endpoint names can legitimately contain the character *, but access entries use * for wildcarding. so the two-character sequence \* is used to avoid the ambiguity in the "actor" attribute. likewise, if you want to explicitly specify an endpoint name containing \ in the "actor" attribute, you use the two-character sequence \\.
heads up: this convention only applies to the "actor" attribute of the "get" operation and of the "access" entry inside the "set" operation. it is not used in the "query" operation, because that operation doesn't allow wildcarding.
so to specify the endpoint named a\b*c@example.com in the "get" operation or in an "access" entry, the string a\\b\*c@example.com is used. but in the "query" operation, the string a\b*c@example.com is used. (of course, name allocation is a local matter, so you can skip all this drama by just not using endpoint names with * or \ ๐โจ)
3.1 Finding the Appropriate Entry: Matching Owners and Actors โจ
Okay bestie, actor wildcarding means more than one access entry can apply to the same owner/actor combo ๐ So how does the service pick the right one when it answers a query operation? Here's the tea ๐
- Only look at the access entries tied to the given owner.
- Only keep the entries whose actor value matches the actor address in the query. If there's a wildcard character (
*) in the actor value, it's only a match if every wildcard can be swapped for a non-empty run of characters (one or more) to get exactly the address from the query ๐งฉ - Then rank whatever's left:
- Use the exactness of the match with the domain part of the actor value as the primary key; and,
- Use the exactness of the match with the local part of the actor value as the secondary key.
- When matching the domain part, an exact match is the best match. Otherwise, the shorter the wildcard match, the higher the priority.
For example, if the actor's domain is "bar.foo.example.com", a match against an entry of ".foo.example.com" is better than a match against an entry of ".example.com" ๐
- When matching the local part, an exact match is the best match. Otherwise, the shorter the wildcard match, the higher the priority. This is true whether the wildcarding is for a subaddress or a service. (Note that a local part with a wildcard subaddress does not have a non-empty match with the same local part without a subaddress ๐)
Let's look at an example with these access entries:
<access owner='fred@example.com'
actor='wilma@example.com'
actions='all:all'
lastUpdate='2000-05-14T13:20:00-08:00' />
<access owner='fred@example.com'
actor='mr.slate@example.com'
actions='core:data'
lastUpdate='2000-05-14T13:20:00-08:00' />
<access owner='fred/appl=wb@example.com'
actor='barney/appl=wb@example.com'
actions='core:data'
lastUpdate='2000-05-14T13:20:00-08:00' />
<access owner='fred@example.com'
actor='*@example.com'
actions='core:data presence:subscribe presence:watch'
lastUpdate='2000-05-14T13:20:00-08:00' />
<access owner='fred@example.com'
actor='*@*'
actions='core:data'
lastUpdate='2000-05-14T13:20:00-08:00' />
Briefly, here's who gets what ๐ฆ
- For addresses within the "example.com" administrative domain:
- "fred", "wilma", and all APEX services within the "example.com" administrative domain are allowed access to all operations for "fred@example.com" ๐
- "mr.slate" is allowed access only to send data through the relaying mesh to "fred@example.com" ๐จ
- "barney/appl=wb" is allowed access only to send data to "fred/appl=wb", a subaddress of "fred@example.com" ๐
- any other address within the "example.com" administrative domain is allowed access to send data and invoke the "subscribe" and "watch" operations of the APEX presence service with respect to "fred@example.com" ๐ธ
- For any address outside the "example.com" administrative domain, the address is allowed access to send data, regardless of whether it is an APEX service ๐
Note that although the four default entries are always available, the explicit entry for actor "@" overrides the corresponding default entry. Plot twist! ๐
3.2 Creating and Updating Access Entries โจ
The get and set operations are the basic tools for creating and updating access rules, and they do no special wildcard processing ๐ ๏ธ
An actor value for an access entry may contain limited wildcard characters. Those only have special meaning when you're doing a query operation (cf., Section 3.1). When you're retrieving or updating entries, actor values are treated simply as literal names ๐
4. The Access Service ๐ท
Section 5 contains the APEX service registration for the access service:
- Within an administrative domain, the service is addressed using the well-known endpoint of
apex=access. - Section 6 defines the syntax of the operations exchanged with the service.
- A consumer of the service starts the conversation by sending data containing a query, get, or set operation.
- The service replies to these operations.
- When an access entry is changed, the service sends a notification to the owner associated with the changed entry.
An implementation of the service must maintain information about access entries in persistent storage ๐พ
Consult Section 6.1.1 of [1] for a discussion on the properties of long-lived transaction-identifiers ๐ง
4.1 Use of XML and MIME ๐
Section 4.1 of [1] describes how arbitrary MIME content is exchanged as a BEEP [2] payload. For example, to transmit:
<data content='...'>
<originator identity='fred@example.com' />
<recipient identity='apex=access@example.com' />
</data>
where "..." refers to:
<query owner='fred@example.com' transID='1'
actor='barney@example.com'
actions='core:data presence:subscribe' />
then the corresponding BEEP message might look like this:
C: MSG 1 2 . 42 1234
C: Content-Type: multipart/related; boundary="boundary";
C: start="<1@example.com>";
C: type="application/beep+xml"
C:
C: --boundary
C: Content-Type: application/beep+xml
C: Content-ID: <1@example.com>
C:
C: <data content='cid:2@example.com'>
C: <originator identity='fred@example.com' />
C: <recipient identity='apex=access@example.com' />
C: </data>
C: --boundary
C: Content-Type: application/beep+xml
C: Content-ID: <2@example.com>
C:
C: <query owner='fred@example.com' transID='1'
C: actor='barney@example.com'
C: actions='core:data presence:subscribe' />
C: --boundary--
C: END
or this:
C: MSG 1 1 . 42 267
C: Content-Type: application/beep+xml
C:
C: <data content='#Content'>
C: <originator identity='fred@example.com' />
C: <recipient identity='apex=access@example.com' />
C: <data-content Name='Content'>
C: <query owner='fred@example.com' transID='1'
C: actor='barney@example.com'
C: actions='core:data presence:subscribe' />
C: </data-content>
C: </data>
C: END
4.2 The Query Operation ๐
When an application wants to see if a particular operation is allowed, it sends a query element to the service ๐
The query element has an owner attribute, an actor attribute, an actions attribute, a transID attribute, and no content:
- the
ownerattribute specifies the address associated with the access entry; - the
actorattribute specifies the address (without wildcarding) for which access permissions are queried; - the
actionsattribute specifies one or more actions for which permission is queried; and, - the
transIDattribute specifies the transaction-identifier associated with this operation.
When the service receives a query element, we call the owner attribute the "subject". The service runs through these steps ๐ต๏ธโโ๏ธ
- If the subject is outside this administrative domain, a
replyelement having code 553 is sent to the originator. - If the subject does not refer to a valid address, a
replyelement having code 550 is sent to the originator. - If the subject's access entry matching the originator does not contain an
access:querytoken, areplyelement having code 537 is sent to the originator. - The subject's access entry matching the actor attribute of the query element is selected (cf., Section 3.1).
- If all of the permissions in the
actionsattribute of the query element are contained in the selected access entry, then anallowelement is sent to the originator. - Otherwise, a
denyelement is sent to the originator.
Regardless of whether an allow, deny, or reply element is sent to the originator, the transID attribute is identical to the value found in the query element sent by the originator ๐ซถ
4.3 The Get Operation ๐งพ
Before creating or updating an access entry for some owner/actor combination, an application will usually need to retrieve any existing access entry. It does this by sending a get element to the service. In particular, a successful response returns a lastUpdate value that is necessary when sending a subsequent set element ๐
The get element has an owner attribute, an actor attribute, a transID attribute, and no content:
- the
ownerattribute specifies the address associated with the access entry; - the
actorattribute specifies the address (with possible wildcarding) for which access permissions are retrieved; and, - the
transIDattribute specifies the transaction-identifier associated with this operation.
When the service receives a get element, we call the owner attribute the "subject". The service runs through these steps ๐ต๏ธโโ๏ธ
- If the subject is outside this administrative domain, a
replyelement having code 553 is sent to the originator. - If the subject does not refer to a valid address, a
replyelement having code 550 is sent to the originator. - If the subject's access entry matching the originator does not contain an
access:gettoken, areplyelement having code 537 is sent to the originator. - The subject's access entry whose
actorattribute identically matches theactorattribute of thegetelement is selected. - If no such entry exists, a
replyelement having code 551 is sent to the originator. - Otherwise, a
setelement corresponding to the selected access entry is sent to the originator.
Regardless of whether a set or reply element is sent to the originator, the transID attribute is identical to the value found in the get element sent by the originator ๐
4.4 The Set Operation ๐
okay so this is where the magic happens ๐ฅ when an application wants to modify an access entry (create it, replace it, or delete it), it sends a set element to the service.
The set element has a transID attribute and contains an access element:
- the
transIDattribute specifies the transaction-identifier associated with this operation; and, - the
accesselement contains the access entry to be created, replaced, or deleted.
The access element has an owner attribute, an actor attribute, an optional actions attribute, an optional lastUpdate attribute, and no content:
- the
ownerattribute specifies the address associated with the access entry; - the
actorattribute specifies the address (with possible wildcarding) for which access permissions are specified; - the
actionsattribute (present only to add or replace an entry) specifies one or more actions for which permission is to be determined; and, - the
lastUpdateattribute (present only to replace or delete an entry) specifies the current timestamp of the access entry that is to be replaced.
when the service gets a set element, the owner attribute of the access element is called the "subject" ๐ the service then does these steps:
- If the subject is outside this administrative domain, a
replyelement having code 553 is sent to the originator. - If the subject does not refer to a valid address, a
replyelement having code 550 is sent to the originator. - If the subject's access entry matching the originator does not contain an
access:settoken, areplyelement having code 537 is sent to the originator. - The subject's access entry whose
actorattribute identically matches theactorattribute of thesetelement is selected. - If no such entry exists and the
lastUpdateattribute is present in the suppliedsetelement, areplyelement having code 555 is sent to the originator. - If no such entry exists and the
lastUpdateattribute is absent in the suppliedsetelement, then:- The access entry for the owner/actor combination is created from the supplied
accesselement. - The
lastUpdateattribute of that access entry is set to the service's notion of the current date and time. - A
replyelement having code 250 is sent to the originator. - A
setelement corresponding to the newly-created access entry is sent to the subject's address.
- The access entry for the owner/actor combination is created from the supplied
- If the selected entry exists, but its
lastUpdateattribute is not semantically identical to thelastUpdateattribute of the suppliedaccesselement, areplyelement having code 555 is sent to the originator. - If the
actionsattribute of the suppliedaccesselement is not present, then:- The selected entry is deleted.
- A
replyelement having code 250 is sent to the originator. - A
setelement corresponding to the owner/actor combination, but lacking anactionsattribute, is sent to the subject's address.
- Otherwise:
- The access entry for the owner/actor combination is updated from the supplied
accesselement. - The
lastUpdateattribute of the updated access entry is set to the service's notion of the current date and time (which should be different from thelastUpdatevalue associated with any replaced entry). - A
replyelement having code 250 is sent to the originator. - A
setelement corresponding to the newly-updated access entry is sent to the subject's address.
- The access entry for the owner/actor combination is updated from the supplied
when the service sends the reply element, the transID attribute matches the value found in the set element that the originator sent โจ
4.5 The Reply Operation ๐
while processing operations, the service might respond with a reply element. Consult Sections 10.2 and 6.1.2 of [1], respectively, for the definition and an exposition of the syntax of the reply element ๐ค
5. Registration: The Access Service ๐ฆ
- Well-Known Endpoint:
apex=access - Syntax of Messages Exchanged:
c.f., Section 6 - Sequence of Messages Exchanged:
c.f., Section 4 - Access Control Tokens:
access:query,access:get,access:set - Contact Information:
c.f., the "Authors' Addresses" section of this memo
6. The Access Service DTD ๐ง
here's the whole DTD, verbatim, because it's the one thing you can't paraphrase ๐
<!--
DTD for the APEX access service, as of 2001-06-19
Refer to this DTD as:
<!ENTITY % APEXACCESS PUBLIC "-//IETF//DTD APEX ACCESS//EN" "">
%APEXACCESS;
-->
<!ENTITY % APEXCORE PUBLIC "-//IETF//DTD APEX CORE//EN" "">
%APEXCORE;
<!--
DTD data types:
entity syntax/reference example
====== ================ =======
access actor
ACTOR an ENDPOINT or a *@example.com
wildcard
permitted actions
ACTIONS a list of access "core:any access:query"
tokens
-->
<!ENTITY % ACTOR "CDATA">
<!ENTITY % ACTIONS "NMTOKENS">
<!--
Synopsis of the APEX access service
service WKE: apex=access
message exchanges:
consumer initiates service replies
================== ================
query allow, deny, or reply
get set or reply
set reply
service initiates consumer replies
================= ================
set (nothing)
access control:
token target
========== ======
access:query for "owner" of "access" element
access:get for "owner" of "access" element
access:set for "owner" of "access" element
-->
<!ELEMENT query EMPTY>
<!ATTLIST query
owner %ENDPOINT; #REQUIRED
actor %ACTOR; #REQUIRED
actions %ACTIONS; #REQUIRED
transID %UNIQID; #REQUIRED>
<!ELEMENT get EMPTY>
<!ATTLIST get
owner %ENDPOINT; #REQUIRED
actor %ACTOR; #REQUIRED
transID %UNIQID; #REQUIRED>
<!ELEMENT set (access)>
<!ATTLIST set
transID %UNIQID; #REQUIRED>
<!ELEMENT allow EMPTY>
<!ATTLIST allow
transID %UNIQID; #REQUIRED>
<!ELEMENT deny EMPTY>
<!ATTLIST deny
transID %UNIQID; #REQUIRED>
<!--
access entries
-->
<!ELEMENT access EMPTY>
<!ATTLIST access
owner %ENDPOINT; #REQUIRED
actor %ACTOR; #REQUIRED
actions %ACTIONS; #IMPLIED
lastUpdate %TIMESTAMP; #IMPLIED>
7. Security Considerations ๐
this is the serious part, so pay attention ๐
Consult [1]'s Section 11 for a discussion of security issues.
In addition, timestamps issued by the the access service may disclose location information. If this information is considered sensitive, the special timezone value "-00:00" may be used (after converting the local time accordingly).
References ๐
[1] Rose, M., Klyne, G. and D. Crocker, "The Application Exchange Core", RFC 3340, July 2002.
[2] Rose, M., "The Blocks Extensible Exchange Protocol Core", RFC 3080, March 2001.
Authors' Addresses ๐ฎ
Marshall T. Rose Dover Beach Consulting, Inc. POB 255268 Sacramento, CA 95865-5268 US
Phone: +1 916 483 8878 EMail: mrose@dbc.mtview.ca.us
Graham Klyne Clearswift Corporation 1310 Waterside Arlington Business Park Theale, Reading RG7 4SA UK
Phone: +44 11 8903 8903 EMail: Graham.Klyne@MIMEsweeper.com
David H. Crocker Brandenburg Consulting 675 Spruce Drive Sunnyvale, CA 94086 US
Phone: +1 408 246 8253 EMail: dcrocker@brandenburg.com URI: http://www.brandenburg.com/
Appendix A. Acknowledgements ๐ซถ
the authors gratefully acknowledge the contributions of Neil Cook, Darren New, Chris Newman, Scott Pead, and Bob Wyman ๐
Full Copyright Statement โญ
Copyright (C) The Internet Society (2002). All Rights Reserved.
okay so you're totally allowed to copy this document and pass it around, and to make derivative works that comment on it, explain it, or help people implement it. You can publish and distribute those, in whole or in part, with no restriction of any kind, as long as the copyright notice and this paragraph stay on all copies and derivative works.
however, this document itself may not be modified in any way, like removing the copyright notice or the references to the Internet Society or other Internet organizations. The exceptions are when it's needed for developing Internet standards (in which case the copyright procedures in the Internet Standards process must be followed), or when it's being translated into languages other than English.
the limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns ๐
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Acknowledgement ๐
funding for the RFC Editor function is currently provided by the Internet Society โจ
๐ฆ where this page comes from
- ietf: rfc3341 2002-07
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms