No description
Find a file
Claus Lohmar 4d5d1f674e fix(security): gate /setup per request and pin the setup module
REVIEW-001 (M0) HIGH H2: loopback was enforced only at BIND, so a reverse
proxy on 127.0.0.1 relaying remote clients reached /setup and could create
the top admin — exactly the first-visitor-wins D-025 claims to close "in
code". In setup mode, reject any request whose RESOLVED client IP is not
loopback (404 before dispatch); an unparseable/empty client IP fails closed.
The resolved IP is the one XFF produces, so a trusted proxy forwarding a
remote client does not launder it (see the new test).

Also:
- M1c/L3s: pin the setup module at the door. serveSetupAction rejects
  Module != "setup", and any other resolution naming it (a GUID path, a
  reserved workflow) 404s instead of falling through to serveGUID.
- L1s: read/clear the session cookie under its transport-correct name.

Tests: the harness speaks from a loopback peer by default (the operator
reaches /setup over a tunnel) and configures a public base_url where the
nudge must fire (L7c). New tests cover the per-request setup gate (including
the trusted-proxy relay and the loopback tunnel) and the module pin, both of
which fail without the fix.
2026-10-14 11:30:13 +00:00
.opencode chore: bootstrap MyDay repository 2026-10-13 11:52:30 +00:00
cmd/myday fix(security): sign the setup ceremony with startup-generated keys 2026-10-14 11:30:09 +00:00
docs/specs docs: add the project plan, M0/M0.1 specs, agent guide and README 2026-10-14 10:53:44 +00:00
internal fix(security): gate /setup per request and pin the setup module 2026-10-14 11:30:13 +00:00
.gitignore chore(gitignore): ignore only the root build binary, not the cmd/myday source 2026-10-14 10:53:46 +00:00
AGENT.md docs: add the project plan, M0/M0.1 specs, agent guide and README 2026-10-14 10:53:44 +00:00
config.example.yaml refactor(config): drop the dead secrets.session_key 2026-10-14 11:30:06 +00:00
go.mod chore(go): add the Go module manifest 2026-10-14 10:53:46 +00:00
go.sum chore(go): add the Go module manifest 2026-10-14 10:53:46 +00:00
PROJECT_PLAN.md docs: add the project plan, M0/M0.1 specs, agent guide and README 2026-10-14 10:53:44 +00:00
README.md docs: add the project plan, M0/M0.1 specs, agent guide and README 2026-10-14 10:53:44 +00:00

MyDay

A self-hosted employee time, absence & reporting app by Sechpoint. Delivered as a PWA for mobile and desktop. Single-tenant — one company per instance.

Status: 🚧 planning / pre-alpha. No application code yet. The design of record is PROJECT_PLAN.md.


What it will do

Area
Org structure users, the manager hierarchy, departments, positions
Time presence and timesheets (a per-user mode)
Absence leave requests, approvals, balances
Reporting rollups and aggregations

Built as one Go binary: a small core (MyDay.auth — identity, sessions, the door) plus drop-in modules.


Running it

Not yet available — nothing is built. These are the intended steps.

# 1. configure
cp config.example.yaml config.yaml     # then edit; config.yaml is gitignored
# 2. build
go build -o myday ./cmd/myday
# 3. run
./myday

⚠️ First run — do NOT expose it publicly

The first user becomes the top admin (the root of the chain). So the instance bootstraps loopback-only, running a /setup wizard until that admin exists.

# on the server it listens on 127.0.0.1:8080 only (config.example.yaml)
ssh -L 8080:127.0.0.1:8080 user@server        # from your workstation
# then open  http://127.0.0.1:8080/setup  and complete the wizard

Reach the app over localhost / 127.0.0.1 — not a hostname. With an https:// base_url the CSRF and session cookies are marked Secure, so they are not sent over plain http://; and only a loopback origin counts as a trustworthy/secure context for the browser's WebAuthn dialogs. So for first run and any human testing, open the app at http://localhost:8080 or http://127.0.0.1:8080 (via the tunnel above) — never at a bare server hostname.

Only after the top admin exists should you put MyDay behind a reverse proxy and expose it.


Documentation

PROJECT_PLAN.md the plan & decision log of record
AGENT.md instructions for AI agents working here
docs/specs/ implementation specs
config.example.yaml configuration template

Security

  • Secrets live in config.yaml (gitignored) — never commit them.
  • Auth is Passkey (primary) + TOTP (fallback).
  • See PROJECT_PLAN.md §10 for the deferred-security register and its beta gate.

License

TBD.