Route.Allow or Plugin.Allow.
Access layers
| Layer | Defined by | Protects |
|---|---|---|
| User identity | Users and Groups | The identity and group membership attached to a request |
| Host route | Route.Allow in config.toml | An HTTP path before it reaches a host or plugin handler |
| Plugin | Allow under Plugins.<name> | Every HTTP route, static mount, namespace, and event owned by a plugin |
| Plugin resource | The plugin’s registration data | One HTTP route, static mount, Socket.IO namespace, or event |
User identity
For HTTP requests, the Kernel checks thearupa-auth session cookie first and
then the Authorization header. A valid session resolves to a username. The
Kernel looks up that username in Groups and creates a host-verified identity
containing:
- the username;
- the groups that contain that username; and
- the
Authenticatedstate.
Authorization header.
Policy semantics
All access checks use the same policy model:- An empty policy is public. It allows unauthenticated users.
RequireAuth = truewith no groups allows any authenticated user.- A non-empty
Groupslist requires authentication and membership in at least one listed group. - A user who is authenticated but belongs to none of the listed groups is forbidden.
Groups = ["root", "staff"]
allows a user in root or staff; the user does not need to belong to both
groups.
The two rejection states are different:
- An unauthenticated request is an authentication failure and produces
401 Unauthorized. - An authenticated user who does not satisfy the group requirement is an
authorization failure and produces
403 Forbidden.
Host route access
Route.Allow protects HTTP paths before the request reaches either a host
handler or a plugin handler:
Route.Allow map uses the Kernel’s shared path-pattern implementation. A
normal path is an exact match, while a pattern ending in / matches that path
subtree. The /* is not a valid configuration; it doesn’t support wildcard.
When multiple Route.Allow patterns match, the longest matching pattern wins.
The Kernel does not combine groups from multiple matching patterns. See
Route for the complete path-pattern rules,
root-path behavior, and validation details.
If no rule matches, Route.Allow does not restrict the request. If a matching
rule has an empty group list, its policy is also effectively public because an
empty access policy allows everyone; an empty list does not mean “deny all”.
Route.Allow is evaluated for every HTTP request by the outer auth middleware.
When it rejects a request, it returns the normal JSON 401 or 403 response.
It does not use the configured Pages redirect. See Pages
for browser redirects used by plugin-protected resources.
Plugin-wide access
Allow under [Plugins.<name>] applies to the plugin as a whole:
- the plugin’s HTTP routes;
- the plugin’s static file mounts;
- connections to the plugin’s Socket.IO namespaces; and
- events received in those namespaces.
Allow list leaves the plugin open at this layer. A non-empty list
requires the user to belong to at least one of the listed groups.
[Plugins.default] provides the base plugin configuration. A non-empty
Allow list in [Plugins.<name>] replaces the default group list for that
plugin. If the per-plugin list is omitted or empty, the current implementation
keeps the default list.
The plugin policy is refreshed when the Kernel reloads its configuration, so a
loaded plugin uses the updated group list for subsequent requests and events.
Plugin resource access
Plugins can add another policy when they register a resource. These policies are not written inconfig.toml; they are part of the plugin’s registration
contract.
An HTTP route and a static mount each have their own Access policy. The
Kernel checks the plugin-wide policy first and the resource policy second:
staff from
Plugin.Allow and operators from a route’s Access.Groups to reach that
route.
Example
With the following configuration:admin user can pass the /api/plugins host-route rule because they are
in root. alice is authenticated but receives 403 Forbidden for that
path because they are not in root. An unauthenticated request receives
401 Unauthorized.
The same admin user cannot access any resource protected by the hello
plugin’s Allow = ["staff"] because admin is not in staff. Being
authenticated is not enough when a policy names groups.