← The board

C6 Web UI security & binding policy

Area
C — Trust & correctness
Audience
operator
Kind
feature
Status
accepted
Maturity
building
Labels
security, web
Relates to
A7B6C1D6

The feature in the specification · Read at

Requirements

  1. C6-R1acceptedMUST

    Admin services MUST bind to loopback by default.

    locked by
    0.9.0 met
    recorded done
    lemonfibercrates/lemonfiber/tests/integration/publishing.rs
    recorded partial
    lemonfiber-media-stackstack.tomlscripts/manifest_rules.py::bind must be one of
    cited by
    lemonfiber@ebab0d89be
  2. C6-R2acceptedMUST

    Household-facing services MUST bind to the LAN by default.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber/tests/integration/publishing.rs
    recorded partial
    lemonfiber-media-stackstack.tomlscripts/manifest_rules.py::bind must be one of
    cited by
    lemonfiber@b23c61d182lemonfiber-media-stack@e019b4e3e4
  3. C6-R3acceptedMAY

    No admin service MAY bind to all interfaces by default.

    locked by
    0.9.0 met
    recorded done
    lemonfibercrates/lemonfiber/tests/integration/publishing.rs
    cited by
    lemonfiber@ebab0d89be
  4. C6-R4acceptedMUST

    LAN binding of lemonfiber's UI MUST be refused unless authentication is configured.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/admission.rscrates/lemonfiber/tests/architecture/where_the_outside_world_is_reached.rscrates/lemonfiber/src/ui/password.rscrates/lemonfiber/src/ui/reach.rscrates/lemonfiber/src/ui.rscrates/lemonfiber-api/src/admission/sessions.rs
    cited by
    lemonfiber@a8028cccbb
  5. C6-R5acceptedMUST

    Removing authentication while LAN-bound MUST immediately revert to loopback.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber/src/ui/reach.rs
    cited by
    lemonfiber@3dbd0d3966lemonfiber@8088b55d4a
  6. C6-R6acceptedMUST

    lemonfiber MUST state plainly when it is serving unencrypted HTTP.

    locked by
    0.9.0 met
    recorded done
    lemonfibercrates/lemonfiber/src/ui.rscrates/lemonfiber-core/src/certificate.rscrates/lemonfiber/src/ui/said.rscrates/lemonfiber/tests/architecture/where_it_listens.rs
    cited by
    lemonfiber@482a7476ac
  7. C6-R7acceptedMUST

    Self-signed TLS MUST NOT be enabled by default.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/certificate.rscrates/lemonfiber/src/ui/said.rscrates/lemonfiber/tests/architecture/where_it_listens.rs
    cited by
    lemonfiber@59edb5b826lemonfiber@8088b55d4a
  8. C6-R8acceptedMUST

    Stored authentication credentials MUST use a modern password-hashing function and MUST NOT be recoverable.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/admission.rscrates/lemonfiber/tests/architecture/where_the_outside_world_is_reached.rscrates/lemonfiber/src/ui/password.rscrates/lemonfiber/src/ui/reach.rscrates/lemonfiber/src/ui.rscrates/lemonfiber-api/src/admission/sessions.rs
    cited by
    lemonfiber@4eea2ac994lemonfiber@a8028cccbb
  9. C6-R9acceptedMUST

    Sessions MUST expire, and MUST be invalidated on credential change.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-api/src/admission.rscrates/lemonfiber-api/src/admission/sessions.rscrates/lemonfiber/src/ui/reach.rscrates/lemonfiber/src/ui.rs
    cited by
    lemonfiber@3dbd0d3966lemonfiber@a8028cccbblemonfiber-web@328cf29f61
  10. C6-R10acceptedMUST

    State-changing requests MUST be protected against cross-site request forgery.

    locked by
    0.9.0 met
    recorded done
    lemonfibercrates/lemonfiber-api/src/guard.rscrates/lemonfiber-api/src/serve.rs
    cited by
    lemonfiber@82b419e23dlemonfiber@6276921665
  11. C6-R11acceptedMUST

    Failed authentication attempts MUST be rate-limited.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-api/src/admission/attempts.rscrates/lemonfiber/src/ui/answering.rsspec:10-functional/features/d-content/d6-household-identity.mdcrates/lemonfiber/src/render/invitation.rscrates/lemonfiber-core/src/invitation.rs
    cited by
    lemonfiber@951e9ec617lemonfiber@aba9f8a468lemonfiber@3dbd0d3966lemonfiber@3c595bb599lemonfiber-web@328cf29f61
  12. C6-R12acceptedMUST

    lemonfiber's UI MUST NOT proxy or tunnel to admin service interfaces.

    locked by
    0.9.0 met
    recorded done
    lemonfibercrates/lemonfiber-api/tests/integration/nothing_is_carried_through.rs
    cited by
    lemonfiber@6276921665
  13. C6-R13acceptedMUST

    Actual listening bindings MUST be verified against policy by a diagnostic check.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/doctor/bindings.rscrates/lemonfiber-ports/src/docker.rscrates/lemonfiber/tests/architecture/where_it_listens.rscrates/lemonfiber/src/ui/reach.rscrates/lemonfiber/src/ui.rscrates/lemonfiber-api/src/admission/sessions.rs
    cited by
    lemonfiber@a8028cccbb
  14. C6-R14acceptedMUST

    Binding policy MUST apply equally to IPv4 and IPv6.

    locked by
    0.10.0 uncited
    recorded done
    lemonfibercrates/lemonfiber/tests/architecture/where_it_listens.rs
  15. C6-R15acceptedMUST

    Deliberate exposure of an admin service MUST require explicit acknowledgement and MUST be recorded.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/doctor/guarded.rscrates/lemonfiber-core/src/config/keys.rscrates/lemonfiber-core/src/doctor/guarded/tests.rs
    cited by
    lemonfiber@9c7e6667dflemonfiber@56f38c73a1
  16. C6-R16acceptedMUST

    Where Docker port publishing bypasses the host firewall, lemonfiber MUST warn.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/doctor/bindings.rs
    cited by
    lemonfiber@f423064a03lemonfiber@aa93ced828
  17. C6-R17acceptedMUST

    The interface household services publish on MUST be operator-configurable through a single documented setting, and where it defaults to all interfaces that MUST be stated plainly alongside its consequences.

    locked by
    0.10.0 met
    recorded done
    lemonfibercrates/lemonfiber/tests/integration/publishing.rs
    recorded partial
    lemonfiber-media-stack.env.example::LAN_BIND
    cited by
    lemonfiber@d852edd086lemonfiber-media-stack@e019b4e3e4
  18. C6-R18acceptedMUSTClaim it

    A service an installed plugin adds MUST be bound by the tier lemonfiber assigns from the classification the plugin declared, and a plugin MUST NOT be able to declare an address, an interface or a published port mapping.

    locked by
    0.18.0 uncited
    recorded done
    lemonfibercrates/lemonfiber-plugin/src/schema.rscrates/lemonfiber-core/src/plugin/container.rs
  19. C6-R19acceptedMUST

    Replacing a certificate a companion may have pinned MUST be announced before it is replaced, naming re-pairing as the consequence; where renewal is performed by something lemonfiber does not control, that MUST be stated when the pairing material is produced rather than discovered at the next renewal (ADR-0025).

    locked by
    0.17.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/companion.rscrates/lemonfiber/src/ui/encrypted.rscrates/lemonfiber/src/exit/reporting.rs
    recorded partial
    lemonfiber-companiontests/Feature/NothingReachesAStackUnpinnedTest.php
    cited by
    lemonfiber@59edb5b826
  20. C6-R20acceptedMUST

    A household-tier service MAY hold a credential that is administrative on another service only where one operation must be answerable at household reach at any hour. It MUST then hold that credential alone, MUST perform only that operation through a fixed set of calls, and MUST be confined: no data mount, a read-only root, no kernel capabilities, and no network reach beyond the service it acts on and the port it publishes. No other household-tier service MAY hold such a credential or an administrator's session on another service, and one that acts on another service's API MUST do so only through the request gate (ADR-0032).

    locked by
    0.17.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/seed/run/decline.rscrates/lemonfiber-core/src/seed/run/taken_back.rs
    recorded partial
    lemonfiber-media-stackservices/decline.toml::confinedscripts/check_configs.py::the dashboard holds no credential
    recorded partial
    lemonfiber-request-gatesrc/arr.rssrc/jellyfin.rssrc/arr/tests/forwarding.rs::a_call_off_the_list_or_on_the_other_arrs_route_is_refused
    cited by
    lemonfiber@07b0fd1c77lemonfiber@d089bab2cblemonfiber@7008624f60lemonfiber-request-gate@f6b801c7e4lemonfiber-media-stack@4c7bc56170lemonfiber-media-stack@bd94d60204lemonfiber-media-stack@ca0baba8f8
  21. C6-R21acceptedMUST

    Jellyfin's cross-origin allow-list MUST name the household front door's origin and nothing else, MUST follow a change of that address, and MUST NOT be written empty or as a wildcard.

    locked by
    0.17.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/seed/run/cors.rscrates/lemonfiber-contract/src/capabilities/media.rs
    cited by
    lemonfiber@dc3ad2e459
  22. C6-R22acceptedMUST

    The request gate MUST publish no port and MUST be reachable only from the request service, which MUST have no other network path to Sonarr, Radarr or Jellyfin. It MUST be confined: no data mount, no engine socket, a read-only root, no kernel capabilities, no egress, and network reach only to the services it acts on (ADR-0032).

    locked by
    0.17.0 unmarked
    recorded partial
    lemonfiber-media-stackservices/request-gate.toml::confinedscripts/test_service_model.py::ARCH-R233 a confined service its image runs as
    recorded partial
    lemonfiber-request-gateDockerfilesrc/main.rs
    cited by
    lemonfiber@07b0fd1c77lemonfiber@d089bab2cblemonfiber-request-gate@9b57dbd1f3lemonfiber-request-gate@750de41e1clemonfiber-media-stack@4c7bc56170
  23. C6-R23acceptedMUST

    The request gate MUST answer only the calls ADR-0032 lists, by method and path, MUST build every upstream request itself from the parameters and body fields that list names, checking each write's body against what the upstream holds, MUST refuse every other call without forwarding it, and MUST NOT pass an upstream administrator's session to the request service.

    locked by
    0.17.0 met
    recorded done
    lemonfiber-request-gatesrc/arr.rssrc/arr/written.rssrc/jellyfin.rssrc/arr/tests/forwarding.rs::a_call_off_the_list_or_on_the_other_arrs_route_is_refusedsrc/arr/tests/changes.rs::a_removal_carries_the_id_and_its_two_flags_and_nothing_elsesrc/jellyfin/tests.rs::a_sign_in_on_a_device_the_request_service_does_not_assign_is_refused
    cited by
    lemonfiber@07b0fd1c77lemonfiber@6577d8c68dlemonfiber@e9dfd9f2fblemonfiber-request-gate@996fb32958lemonfiber-request-gate@f15b05f39elemonfiber-request-gate@5be17e061clemonfiber-request-gate@9b57dbd1f3lemonfiber-request-gate@750de41e1c
  24. C6-R24acceptedMUST

    The request gate MUST hold the upstream credentials itself and MUST give the request service only tokens lemonfiber minted, one per upstream, kept by the gate only as hashes and by lemonfiber nowhere; each token MUST be rotatable, proven before the one it replaces is revoked, and revocable alone.

    locked by
    0.17.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/seed/run/decline.rscrates/lemonfiber-core/src/seed/run/taken_back.rscrates/lemonfiber-core/src/seed/run/gate.rscrates/lemonfiber-core/src/seed/run/tokens.rscrates/lemonfiber-core/src/app/credentials/gating.rscrates/lemonfiber-core/src/app/credentials/tokening.rs
    recorded partial
    lemonfiber-request-gatesrc/files.rssrc/files/tests.rs::a_route_accepts_its_token_and_no_call_without_one
    cited by
    lemonfiber@3b589bfe9dlemonfiber@8ac2026c35lemonfiber@6577d8c68dlemonfiber@e9dfd9f2fblemonfiber-request-gate@996fb32958lemonfiber-request-gate@5be17e061clemonfiber-request-gate@9b57dbd1f3
  25. C6-R25acceptedMUST

    The request gate MUST record every call it refuses and every removal it forwards, with its time, route, method and path and never a token, a query string or a body, and a diagnostic check MUST report each since it last read the record.

    locked by
    0.17.0 met
    recorded done
    lemonfibercrates/lemonfiber-core/src/doctor/gating.rs
    recorded partial
    lemonfiber-request-gatesrc/files.rssrc/files/tests.rs::each_entry_is_added_after_the_last
    cited by
    lemonfiber@3b65063ccelemonfiber@e9dfd9f2fblemonfiber-request-gate@996fb32958lemonfiber-request-gate@9b57dbd1f3