The ability for a client to take over the flow that another has initiated is referred to as substitution and clients that are specifically tasked with this as referred to as ersatz clients. We use the cognated word 𝕰𝖗s𝖆𝖙𝖟 (which just means substitute in German) because words like delegate, impersonate, substitute etc. are so overloaded in English that discourse is getting hard -- more time is spent on what the word means in context than anything else. An ersatz client has a very specific, narrow definition and there should be few if any conflicts with other nomenclature.
An ersatz client in OA4MP is a specific type of client which may substitute for another in a flow. A client that starts a flow is called the provisioning client. A provisioning client is just a standard client in OA4MP and may be confidential or public.
Definition:If A is the provisioning client and α is an ersatz client we say write A ≻ α read A provisions α or α can substitute for A. When A provisions α, we say the flow has forked to α.
The provisioning client, A, must exist. The ersatz client α must exist. A must be set as the provisioner of α. This is normally done by an administrator. The steps then are
Additional notes:
A not uncommon use is to provision all the permissions for a job with A, then have specific forks for specific permissions (say a fork for read, one for writes, one for managing capabilities, such as starting or stopping jobs.) You could even have dedicated ersatz clients α, β,...
The rest of this document is for more detail or very specialized uses.
The token exchange specification has a section on impersonation and delegation semantics. It states in toto
When principal A impersonates principal B, A is given all the rights that B has within some defined rights context and is indistinguishable from B in that context. Thus, when principal A impersonates principal B, then insofar as any entity receiving such a token is concerned, they are actually dealing with B. It is true that some members of the identity system might have awareness that impersonation is going on, but it is not a requirement. For all intents and purposes, when A is impersonating B, A is B within the context of the rights authorized by the token. A's ability to impersonate B could be limited in scope or time, or even with a one- time-use restriction, whether via the contents of the token or an out-of-band mechanism.
What this means is that our substitutions are a form of impersonation and that the trust relations are made out of band. Why not call this impersonation? Because other OAuth systems are free to implement this any way they want, and we want to be clear exactly how we do it.
You may have ersatz clients substitute for other ersatz clients, so A ≻ α, α ≻ β and β ≻ γ is perfectly fine. This means that A provisions and that α may substitute for it. Later, β may substitute for α, but cannot substitute for A (unless that relation is made explicit). This allows for chains of substitution. We may write this chain more compactly as A ≻ α ≻ β ≻ γ
Ersatz clients may be created by an admin client, just like any other. Set the property
ersatz_client to true and then set the provisioners.
In order to set up the provisioners, you set the property org.oa4mp:/ersatz/provisioners
to be either the provisioner ID (i.e., the client ID of the client that an start the flow) or
a list of IDs. The list of IDs is
provisionerID ≻ ersatzID_0 ≻ ersatzID_1 ≻ ... ≻ ersatzID_n
All of these must be administered by the same admin client and provision each other in sequence.
If you want the ersatz client to inherit the user metadata (i.e., the id token) then you should set ersatz_inherit_id_token to true. The default is true.
Normally if A ≻ α, then A starts the flow and in the token exchange, α presents the access or refresh token to the exchange endpoint. If α is presented for the first time, the flow forks. Note that A cannot resume the flow for α after this point and they become independent, meaning that if A provisions α with an access token, τ, then α exchanges it for τ', A cannot use τ'. On the other hand, if A ≻ β as well then A may provision β with τ too.
If you have a very large and complex set of substitutions, you may streamline the flow. Let us say that you have provisioning clients A, B, C, D and you need to have finer grained control. An ersatz client ξ with a specific script (say allowing Lab X) could be used as A ≻ ξ ≻ α and B ≻ ξ ≻ β, (say α and β are used by specific groups within Lab X) so that α and β have consistent behavior but can add their own logic.
Clients in OA4MP may set prototypes which are other clients from which they inherit configuration. There may be multiple prototypes (effectively yielding multiple inheritance). Note well that the order you set determines resolution. So if you have 2 prototype clients A and B (in that order) that means that the values of B override the values in A. The values of the base client override all others. This means that you can have a client that is little more than an id and secret which inherits everything else from its prototype, or just sets a single attribute even.
Since provisioning clients can form a prototype hierarchy, there is an attribute for clients namedextendsProvisioners and this means that the provisioners should be used as the prototype hierarchy. If you set this and specify prototypes, then provisioning clients are used first, followed by all specifically set prototypes.