ARPA2 Common Libraries
2.6.2
|
Groups are a special form of Rules that allow selected targets to iterate over group members, perhaps to relay messages to each member. Groups themselves also have semantics, but they may also be considered just a target address.
A straightforward use of a group is as a destination address for Communication Access, which is in no way special, except that it specifies a group attribute =g<group>+<member>
to find the group under the same domain as the destination. Access to the group falls under the same constraints as access to any other address.
The Communication Access cannot modify the sender address, as that is the constant Remote Identity. It does however change this address to an Actor Identity which starts with the group name with one member identity parsed into the alias field. This parsed Actor now functions in a Group as a member, or after removal of the +alias part it functions as a group address.
It is also meaningful to use groups in Document Access, except that this is typically a Pull Function. The Remote Identity is once more translated to an Actor Identity though this time by the access_document()
based on a longer =g<group>+<member>@<xsdomain>
attribute because the Access Domain or <xsdomain>
is not known to this function call. Document Access can benefit from the Actor Identity for logging and linking, so other group members can use the member identity instead of the Remote Identity.
The iteration over group members is a matter of privacy, and not permitted to just anyone. It is necessary to install a separate Service Key to iterate the database or to supply a separate Ruleset for direct processing.
Note that a Service Key is independently derived, so that it takes access to the Database Key to resolve things like delivery addresses for group members. This helps to protect the privacy of these members.
The group name <group>
as supplied through the =g<group>+<member>
attribute is the Access Name under this Service Key or, if direct Rulesets are used, it selects what direct Ruleset to employ. The <group>
is assumed to reside under the same domain as for Communication Access and might include a plus, though that might confuse users. The <member>
cannot hold a plus and is not part of the Access Name.
The separation allows service frontends to lookup the <group>
name under Access Control, but it may be delegated to better shielded software components to iterate over members. When the Service Key for the group is only configured in such a component, then it is rather straightforward to protect groups from iteration, and thus breaking member privacy in this kind of layered setup.
The =g<group>+<member>
attribute defines the part before @
for the sender when used in Communication Access; it needs this Access Domain in Document Access. Destination addresses that start with <group>
and possibly followed with +
and more can now be interpreted as recipes to deliver to the entire group, or possibly to one or more specific members of the group. This is the core group iteration functionality:
+
and one or more member names separated by +
indicates a desire to address only the given members. The form can be used to explicitly include a member who is not listening in by default, such as an archiver or the moderator. One special form is just a single member to be addressed; this form is also used as a single sender address.-
, which looks like +-+
with the surrounding separators, then it means that the given member names are removed from the usual list of recipients (if used again it switches back to adding members). Negative members support talking behind someone's back, for instance to bypass an archiving bot or discuss an excluded member's birthday gift.The Rules for a group contains ^<member>@<address>
triggers, where each <member>
is an address or alias that the member uses for the communication related to this group. The address takes the form of an ARPA2 Identity, so it will contain a second @
symbol.
While iterating over the Ruleset for a group, these triggers are called for the respective group members, allowing such actions as forwarding communication or initiating media connections.
When triggers are detected, they are matched against the aliases to see if traffic should be relayed to the respective recipient. This implies that a single message is not forwarded more than once to any member. When multiple target addresses exist and the same group occurs more than once, but this takes some extra work when multiple target addresses point to the same group (which is easily detected thanks to the =g<group>+<member>
containing a group name).
Group Iteration only handles the discovery of (other) members in a group, and will provide both the member alias and the underlying delivery address. The privacy of a group hinges on change of the Remote Identity addressing the group, and rewriting it to a <group>+<member>@<xsdomain>
form; see Actor for the details of this change from Remote Identity to Actor Identity.
The combined information of member alias and delivery address within a group allows the reversal of the Actor's NAT approach to Identities. What looks like a member address, such as cooks+piecrust@example.com
, gets translated to a delivery address like mary@example.org
in a one-on-one, bidirectional mapping. That is, when a message is sent to the first address it translates to the latter for delivery, and when a message is sent from the latter addresses it translates to the former address. This outer-to-inner translation of destination addresses and inner-to-outer translation of source addresses mirrors what NAT does in the IP space, but with practically unlimited name spaces (so there is no risk of exhaustion such as for the IP port space, which causes a need for timeouts and dynamicity, leading to unreliable behaviour).
It is quite possible to use this mechanism for aliases, such as for an address info@example.net
to john+helpdesk@example.com
. The responses, when sent through the group mechanism, could aim to return the traffic to the caller when that has been assigned an address. This could be done by adding a numeric member name so that it falls under the group. The number could double as a case number and might be closed at some point. This mechanism causes the reply to be from the group address, making it much easier for the sender to process than a casual one-way alias that is commonly used in these cases.
The following attributes may be used in the Ruleset for a group:
When MARKS
flags are setup in a Rule, it affects those ^member@address
triggers that follow. New settings replace older ones; every Rule starts freshly without any marks, so setting those is usually the first thing a Rule needs to do.
Which markers are set, may not be completely in the hands of users. It is very likely that group-administrative code dictates some or all of the flags.
GROUP_RECV
or ACCESS_READ
or R
to let the member read group data by defaultGROUP_SEND
or ACCESS_WRITE
or W
to indicate members prone to write/respond to the groupGROUP_ROBOT
or ACCESS_SERVICE
or F
for bots that process commands; when the GROUP_RECV
right is added, the bot is assumed to be an archiverGROUP_MODERATOR
or ACCESS_ADMIN
or A
for human moderatorsGROUP_ADDMEMBER
or ACCESS_CREATE
or C
for those who may add members; this flag may inform of powers of a bot or moderatorGROUP_DELMEMBER
or ACCESS_DELETE
or D
for those who may remove members; this flag may inform of powers of a bot or moderatorGROUP_OPERATE
or ACCESS_OPERATE
or T
is the right to start and stop group service, without dropping its member list; this could be used to suspend and resume group serviceGROUP_KNOW
or ACCESS_KNOW
or K
is the right to test the existence of a member name on the listGROUP_PROVE
or ACCESS_PROVE
or P
is the right to test if a certain member has a given rightGROUP_VISITOR
or ACCESS_VISITOR
or V
is set for list members who welcome group interactions from non-membersThe framework of Policy Rules identifies the following coordinates:
5a1a2596-1763-36bf-a7b2-814ad98083ca
=g
in Communication Access and commonly set to the identity of a group, a +
symbol and a member namerules_dbkey_domain()
and rules_dbkey_service()
; this mixes an optional Database Secret with the Access Domain and Access Type to derive a domain-specific start for database lookups; this value is commonly exchanged in hexadecimal notation and mapped back to binary form before looking up the database entry@.
will be used in the computation of rules_dbkey_selector()
; the only overhead is that these two characters are added to the message digest that is needed to incorporate the Access NameThe logic of groups consists of these steps:
The ARPA2 Identity framework involves a call to parse a group:
The inlen
may be 0 to have it computed as strlen(in)
, otherwise only inlen
characters of in
are used. The out
structure holds the Group Member Identity, which is a variant of an ARPA2 Identity; namely, there must be nact
signs +
that end up as the alias and anything before it counts as the userid, even if it involves +
signs (which may confuse users and is ill-advised, but nonetheless formally possible).
The common practice of addressing out->txt
for a full string will work as for any ARPA2 Identity. Iteration will also yield a2act_t
elements for the list members to address, along with the delivery address of each member.
To perform Access Control with possible discovery of a member alias as an Actor, run
The test a2act_isempty(optout_actor)
is false when a member alias was stored in optout_actor
. It will be an invalid identity in any other case.
The optout_actor
structure can now be used as a sender to the group defined in its structure. The general procedure is to have callbacks triggered for members, where required and forbidden marks may be set as desired.
The function returns true
on success, or otherwise false
with errno set to a com_err code.
The sender
is a member alias, consisting of a group as its userid and a single alias representing the member name. The group is used for iteration, with limitations imposed by filters
, required_marks
and forbidden_marks
. The rules are either specified with the opt_rules
and ruleslen
parameters or retrieved from the database with the opt_svckey
and svckeylen
, using the group name from the sender
as the Access Name. More details of these parameters are defined by the group_iterate()
API.
The required_marks
must all be set for a member for it to pass through, and none of the forbidden_marks
must be set. This can be used to do quickly implement privacy controls in your application, and possibly to steer the content only to suitable parties. For instance, it might be possible to generate a listing of moderators, or service bots, for a group.
The filters
form an array of strings that help to select members, possibly refusing some. Each of the strings can be derived from its own destination address; this was done to support protocols that already support multiple recipients (like email). This can help to avoid multiple deliveries of one message that happens to be acceptable to multiple destination addresses, where all the complexity is dealt with inside of the group_iterate()
call.
The callback function supplied in upcall
, with abstract data pointer being passed in updata
, listens to the following profile:
This routine is called for every single sender/recipient pair that it finds during iteration, and that filters through. The updata
and sender
are literally taken from group_iterate()
arguments. The marks
are the markings for the current member. The recipient
is a member address, like sender
is, for one member, whose delivery
address of length deliverylen
is provided for further message routing.
For reasons of future compatibility, these upcall functions must always return true
.
Since Group Iteration suggests collecting the filters for a number of recipients, it can be convenient to look for a match of a sender to see if it is a Group Member. This can be done with
The potential_member
would be parsed with a2act_parse()
with nact=1
to capture the single alias level that applies to all Group Members. The out_marks
are set to the Group Marks assigned and may be tested to have any of the GROUP_xxx
flags set.
Finally, there are setup and teardown calls for group logic,