Skip to main content

require_auth_public_data

Function require_auth_public_data 

Source
pub async fn require_auth_public_data(
    __arg0: State<App>,
    req: Request<Body>,
    next: Next,
) -> ClResult<Response<Body>>
Expand description

Like require_auth, but skips the scope gate. It relaxes scope, never validity: an expired, forged, wrong-tenant or unparseable token is rejected here exactly as require_auth rejects it.

§The admission rule — read before mounting anything here

Mount a route under this layer only if every field of its response is already obtainable without authentication elsewhere.

That rule is what makes the admission safe, and the admission is total: any valid credential reaches this tier with no scope filtering. Exhaustively —

  • every file:{file_id}:{R|C|W} share-link token,
  • every apkg:publish token,
  • every carddav:* / caldav:* capability key,
  • every scope string crate::scope::scope_permits does not recognise — the case it exists to fail closed on, since tenant API keys are minted with the full owner role set regardless of their scopes column,
  • and every scope family added in future, admitted the day it is added with no diff touching this file.

The share-link token is the worked example because it is the most adversarial: a credential handed to an untrusted third party for one document, which scope_permits otherwise confines to /api/files/**, /api/search and the CRDT/RTDB sockets. Mounting a route here hands that third party the route, with no ABAC behind it unless the compose site adds one.

It exists because crate::scope::scope_permits is a central path list, and growing it is how a scope quietly widens: the list drifts away from the routes it governs and no reviewer of a route change ever sees it. Expressing the relaxation as a mount puts the decision in the diff that adds the route, and leaves scope.rs untouched — so every other /api/profiles/* route stays denied to a file-scoped token.

The mounted set is pinned by crate::routes::protected::tests::public_data_tier_holds_exactly_the_admitted_tables in the cloudillo crate. Currently: GET /api/profiles/batch — the reduced 4-field profile projection, which is GET /api/me minus keys.