Skip to content

gate-5 (route-auth): false positive on ADR-040 AppHost apps, and it is not diff-scoped #153

Description

@rubenvdlinde

Summary

Gate 5 (route-auth) resolves a route name to lib/Controller/<Name>Controller.php by Nextcloud's default naming convention. That mapping is wrong for any app that adopts ADR-040 AppHost, where the generic controllers are aliased onto the app's conventional controller class names at runtime by \OCA\OpenRegister\AppHost\Bootstrap::register(). The file the gate looks for does not exist in the consuming app by design.

The gate reports this as missing, which reads as "this routed method has no auth attribute" — a security finding — when the truth is "the gate could not resolve the controller".

Reproduction

ConductionNL/scholiq @ development (7f7feea), gate package v1.0.1:

[gate-5] route-auth: FAIL — 4 routed method(s) missing auth attribute

health#index — lib/Controller/HealthController.php missing
metrics#index — lib/Controller/MetricsController.php missing
preferences#getPreference — lib/Controller/PreferencesController.php missing
preferences#setPreference — lib/Controller/PreferencesController.php missing

scholiq/lib/Controller/ contains no HealthController.php, MetricsController.php or PreferencesController.php, and grep -rl HealthController lib/ returns nothing. appinfo/routes.php says so explicitly:

AppHost adoption (ADR-040): the settings, preferences, health and metrics controllers are the OpenRegister AppHost generics, aliased onto Scholiq's conventional controller class names in lib/AppInfo/Application.php via \OCA\OpenRegister\AppHost\Bootstrap::register().

lib/AppInfo/Application.php:73 imports OCA\OpenRegister\AppHost\Bootstrap and calls Bootstrap::register(...) at line 136.

The auth attributes for those methods live on the generic controllers inside the openregister package. The gate never looks there, so it cannot see them either way — it is not that the attributes are absent, it is that the gate is looking in the wrong repository.

Second, separable defect: gate 5 is not diff-scoped

The run above was scoped to a diff of package.json + package-lock.json — a @conduction/nextcloud-vue dependency bump, zero PHP touched. Gate 5 still fired with 4 findings.

ADR-020 diff-scoping is what makes this tier safe to switch on in a repo with inherited debt (gates 16, 19, 26 and 61 honour it). Gate 5 scanning appinfo/routes.php wholesale means that on scholiq every PR, including a Dependabot bump, is blocked by a finding it did not introduce and cannot fix.

Impact

This is why enable-hydra-gates has not been switched on for scholiq. Any AppHost-adopting app will hit the same wall on its first run.

Suggested direction (not applied — this is a gate defect, not app debt)

  1. Distinguish "controller class not resolvable in this repo" from "auth attribute absent". They are different findings and only one of them is a security signal. A SKIP/UNRESOLVED verdict naming the unresolved class would be honest; a silent missing is not.
  2. Teach the resolver about AppHost\Bootstrap::register() aliasing, or read the alias map, so aliased routes resolve to the generic controller.
  3. Diff-scope gate 5 per ADR-020 so inherited routes cannot block an unrelated PR.

Deliberately not doing the obvious workaround of adding stub controllers or auth attributes to scholiq to satisfy the check — that would be changing correct code to satisfy a broken gate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions