We need a way to defined REST endpoints that are restricted for use by trusted clients under the control of the wiki maintainer, typically inside the local network. The driving use case for this is the need for a mechanism to execute jobs through HTTP requests from changeprop-jobrunner, see T175146.
== Proposal ==
Introduce the notions of "module designation" and "module protection" into the REST framework.
REST modules represent a collection of related endpoints covered by a versioned spec (see T362480).
Modules should be able to declare a "designation", which can then be used to deceide their level of "protection". Multiple protection mechanisms can be made availabel that can be applied separately or in combination. Three mechanisms should probably be supported from the start:
* **user-group**: This will deny access to any user not in any of the listed groups. This is a natural way of restricting access, but may be impactical or cumbersome, depending on the available authentication mechanism. //(TBD: we could also require user rights rather than groups).//
* **network**: This will allow access only for requests coming from an address matchign one of the network ranges provided. This is a convenient way to allow access to services on the local network, but can easily be misconfigured to allow access to anyone, when requests are routed through a proxy.
* **signed**: Require requests to be signed according to RFC 9421, based on a shared secret, sich as $wgSecretKey. Libraries for request signing are available for a wide range of languages (through mostly based on earlier draft versions of the RFC, which is fairly young). This is useful e.g. in the context of end-to-end testing using a framework like Mocha: a key can easily be shared between the test code and the server under test, and the same configuration will work on test systems and local development setups without having to worry about changing network addresses.
For technical reasons, it may be useful to provide a trivial protection mechanism called "allow" that can be set to either true or false.
Example:
```lang=php
// Enable HMAC authorization for private modules
$wgRestAPIProtection['private'] = [
'signed' => [
'network' => [ '192.168.0.0/24' ],
'hmac-keys' => [ 'default' => $wgSecretKey ],
],
];
```
== Additional security measures ==
As an additional level of security, private modules would not be loaded per default, they would have to be added to the RestAPIAdditionalRouteFiles setting explicitly. That way, WMF can have these modules be undefined on application servers that are publically accessible, and enable them only one servers restricted to internal use, such as jobrunners.
This would be equivalent to the way we currently restrict access to the RunSignleJob.php script (T362480). It would be sufficient for our own use in production. It's however not feasible for most third party installations, nor for testing and development.
== Rationale for supporting designations ==
All this could be achieved by having a was to flag modules as "private", and then configuring what protection should apply for private modules.
However, it seems useful to generalize the concept of "designations" to allow different levels of protection for different sets of modules. For example, beyond the very struct "private" designation, we may also have a "bots" deswignation that would limit access to certain APIs to users in the "bots" group. Or we could define very weak protectio0n bnased on the User-Agent, to (nominally) restrict access to certain modules to the Wikipedia App.
```lang=php
$wgRestModuleDesignations= [
'edit.v2' => [ 'bots' ],
'pci.v2 => [ 'apps' ],
];
$wgRestAPIProtection['bots'] = [
'user-group' => [ 'bot' ],
];
$wgRestAPIProtection['apps'] = [
'user-agent' => '/^Wikipedia-App/',
];
```