ARPA2 Common Libraries  2.6.2
Access Control as an Actor

Actors are a renamed identity that a user may assume. To be permitted to switch to an Actor Identity, the user needs to have permission, so this switch is subject to Access Control.

This document is about libarpa2access.so, the Access Control library, and more specifically about the ability of an authenticated user to switch to another identity and act on behalf of that.

Generic parts of the ARPA2 framework come out in this, namely aliases, pseudonyms and group members. Also, there are special rules for services.

The idea of acting from another identity is to be implemented by the software of an application, possibly as part of a protocol definition. The descriptions below only state when such a switch can be made.

Acting from an Alias

Users such as john@example.com can create any number of aliases, by adding a plus symbol and another word, possibly multiple levels deep, to form new identities such as john+cook@example.com or john+cook+vegan@example.com.

Users can switch to more specific aliases, so the examples above may move down but not up in the following list:

  • john@example.com
  • john+cook@example.com
  • john+cook+vegan@example.com

Examples of what john@example.com cannot switch to (without another reason elsewhere) are:

  • jo@example.org because the original username was not reproduced
  • johnny@example.com because there is no + right after john
  • johnny+cook@example.com because there is no + right after john
  • mary@example.com because the username was changed
  • john@example.org because the domain name was changed

Acting from and as Services

The alias approach may also be used by services, whose username starts with a + and whose first word counts as a selector for the service, while the rest are usually interpreted similarly to commandline arguments. An example of identity changes a service can make going down, but not up, are:

  • +mail@example.com
  • +mail+archive@example.com
  • +mail+archive+john@example.com

This is the only identity change that a service can perform via Actor Access. Anything else is rejected.

Actor Access does not support switching between a service identity and a plain user identity.

Note however, the services may be assigned an Actor Identity as part of other calls like access_comm() or access_document(); the above relates to the Actor Access facility.

Acting from a Group Member

Users such as john@example.com may be members of a group cooks@example.org and they would have a membership name underneath that group, such as cooks+johann@example.org. If this is the case, then this user may switch to the latter Actor Identity. Doing this requires the GROUP_PROVE mark on the group member, a very simple right to learn about the identity mapping.

Note that the member must supply its own name in this situation, there is no automatic derivation as is done in access_comm() and access_document(). Therefore, the only output is a boolean expressing that a match was found.

Since group members have no aliases, this check is made by splitting off the last + alias word and treating that as the member name. Though it is not currently supported, future versions may support group+subgroup+member notations in the username portion of group member identities.

Acting from a Pseudonym

TODO: This is currently not implemented.

Pseudonyms are usernames that appear to outsiders are unrelated to the login identity. There is some overlap with groups, but they are not the same. For one, a pseudonym is only represented in a first + word, and furthermore there is an option of adding aliases. For this reason, the internals are different and this shows up especially with Actor Access.

When the requested Actor Identity is johann+dancer+disco@example.com then all that is checked for pseudonym access is whether johann@example.com is a reachable pseudonym for the current user identity. If this is the case, then the additional +dancer+disco is implicitly granted, because this is the pseudonym acting from an alias.

Of course, it is possible to do such things in multiple steps, like this order (starting with a presumed acceptable user for the pseudonym):

  • john@example.com
  • johann@example.com
  • johann+dancer@example.com
  • johann+dancer+disco@example.com

Whether this makes sense or not is up to the user, and up to the confines of the protocol or service.

Functions to check Actor Access

The most general function is access_actor_general() but it is usually more pleasant to call one of the simpler functions.

The simplest form assumes no encryption on the Rules DB and so it can derive all the service keys:

#include <arpa2/identity.h>
#include <arpa2/access_actor.h>
a2id_t current_id = ... a2id_parse_remote (...) ...;
a2id_t desired_id = ... a2id_parse (...) ...;
bool ok = access_actor (&current_id, &desired_id);

This is the fallback behaviour for anything set to NULL in the following forms. If you want to avoid default behaviour, you should supply explicit values for the extra parameters, even if they cause trivial results.

When the Rules DB is encrypted, there is a need to supply service keys for (1) the group membership determination, and (2) pseudonym mapping. This may be done with either or both service keys with their lengths:

#include <arpa2/identity.h>
#include <arpa2/digest.h>
#include <arpa2/access_actor.h>
a2id_t current_id = ... a2id_parse_remote (...) ...;
a2id_t desired_id = ... a2id_parse (...) ...;
rules_dbkey group_svckey = ...;
rules_dbkey pseudo_svckey = ...;
bool ok = access_actor_svckey (&current_id, &desired_id,
group_svckey, sizeof ( group_svckey),
pseudo_svckey, sizeof (pseudo_svckey));

In rare cases, when the rules are part of a configuration context, and presumably pulled up along with application data, it may be desirable to address groups and pseudonyms through explicit rule sets, and not address the database for those elements.

Note that this is ill-advised, because it considers only local data and cannot scale up to plugin services that host on behalf of independently administered domains. Think carefully!

The form relies on rule sets, where each rule is an ASCII string with a ‘’\0'` trailer. Multiple of the these rules can be appended to form a ruleset. The total length of the ruleset, including the last trailing ‘’\0'` byte, is provided as the ruleset length. Rulesets can be provided for the group and/or pseudonym handling.

#include <arpa2/identity.h>
#include <arpa2/digest.h>
#include <arpa2/access_actor.h>
a2id_t current_id = ... a2id_parse_remote (...) ...;
a2id_t desired_id = ... a2id_parse (...) ...;
char group_rules [] = "...\0...\0...\0";
char pseudo_rules [] = "...\0...\0";
bool ok = access_actor_rules (&current_id, &desired_id,
group_rules, sizeof ( group_rules),
pseudo_rules, sizeof (pseudo_rules));

Finally, the form access_actor_general() has parameters for both rulesets and Service Keys. This could be used to use different mechanisms for the group handling than for the pseudonyms. This is bound to be confusing and, since it holds explicit rules, it is just as ill-advised as that variant.

There is a separate call which is mostly needed to evaluate the right to change the Pseudonym policy (its administrative rights):

#include <arpa2/identity.h>
#include <arpa2/access_actor.h>
a2id_t login_id = ... a2id_parse_remote (...) ...;
a2id_t acl_id = ... a2id_parse (...) ...;
access_rights pseudonym_rights = ACCESS_VISITOR;
bool ok = access_actor (&login_id, &acl_id,
NULL, 0, /* optional: service key */
NULL, 0, /* optional: policy ruleset */
&pseudonym_rights);