init
This commit is contained in:
commit
b15b95781c
108 changed files with 14802 additions and 0 deletions
79
docs/agents/handoffs/01-foundation.md
Normal file
79
docs/agents/handoffs/01-foundation.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 01 - Foundation
|
||||
|
||||
Stage: Foundation
|
||||
|
||||
Date: 2026-04-13
|
||||
|
||||
## Scope
|
||||
|
||||
Set up the initial runnable Go application skeleton for the update server.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- initialized the Go module;
|
||||
- added the server entrypoint and graceful app bootstrap;
|
||||
- implemented environment-based config loading with sensible local defaults;
|
||||
- wired the base `chi` router, middleware stack, and route groups;
|
||||
- added a JSON health endpoint;
|
||||
- added template bootstrapping and the first server-rendered HTML pages;
|
||||
- added base static assets and a `Justfile` for local run/build/test tasks;
|
||||
- created the `migrations` directory placeholder for the next stage.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/.gitignore`
|
||||
- `/Users/delete/projects/update_server/go.mod`
|
||||
- `/Users/delete/projects/update_server/go.sum`
|
||||
- `/Users/delete/projects/update_server/Justfile`
|
||||
- `/Users/delete/projects/update_server/cmd/server/main.go`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/middleware.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/render.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/response.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/home.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/admin.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/migrations/README.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration files were added in this stage;
|
||||
- created `/Users/delete/projects/update_server/migrations` with a placeholder README so Agent 02 can own the first migration set cleanly.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added `GET /healthz` returning JSON status;
|
||||
- added `GET /` as the foundation landing page;
|
||||
- added `GET /admin` as the reserved admin route group entry;
|
||||
- added `GET /api/v1` as the reserved versioned API route group entry;
|
||||
- added static asset serving under `/static/*`.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./cmd ./internal` - completed successfully;
|
||||
- `go mod tidy` - completed successfully after running with normal network/cache access;
|
||||
- `go test ./...` - completed successfully;
|
||||
- `go build -o /tmp/update-server ./cmd/server` - completed successfully;
|
||||
- started `/tmp/update-server` on `127.0.0.1:18080` and verified `curl http://127.0.0.1:18080/healthz` returned `200 OK` JSON.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- no database connection or migration runner exists yet;
|
||||
- no authentication, sessions, uploads, or business modules are implemented yet;
|
||||
- template loading currently reads from the filesystem path configured by `TEMPLATES_DIR`;
|
||||
- a local `data-dev/` directory is created on startup and is intentionally ignored via `.gitignore`.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 02 should implement the SQLite foundation next: add the migration tool flow, create the initial schema files for the spec tables, and introduce the database connection/repository layer without changing the existing app bootstrap, config contract, or route-group structure.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- there were no prior stage handoff or validation reports yet; only the directory README placeholders existed;
|
||||
- pay attention to whether the app boots from the repo root, whether `/healthz` responds, and whether the route groups remain ready for later auth and feature modules.
|
||||
105
docs/agents/handoffs/02-database.md
Normal file
105
docs/agents/handoffs/02-database.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 02 - Database And Migrations
|
||||
|
||||
Stage: Database And Migrations
|
||||
|
||||
Date: 2026-04-13
|
||||
|
||||
## Scope
|
||||
|
||||
Created the SQLite data layer foundation for the update server.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added SQLite config values for `SQLITE_PATH` and `MIGRATIONS_DIR`;
|
||||
- added a database connection layer with SQLite pragmas, health checks, and transaction scaffolding;
|
||||
- implemented an ordered SQL migration runner with checksum tracking in `schema_migrations`;
|
||||
- created the initial schema for `users`, `projects`, `tags`, `project_tags`, `releases`, `api_keys`, `api_key_project_access`, `api_key_tag_access`, `sessions`, and `audit_logs`;
|
||||
- added indexes and update triggers for mutable tables;
|
||||
- added schema guards so API key project/tag access rows match the key’s selected `scope_mode`;
|
||||
- wired database open + migrate into app startup without changing the existing route-group layout;
|
||||
- added a standalone `cmd/migrate` entrypoint and `just migrate`;
|
||||
- added migration tests and refreshed the health endpoint to report SQLite readiness.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/go.mod`
|
||||
- `/Users/delete/projects/update_server/go.sum`
|
||||
- `/Users/delete/projects/update_server/Justfile`
|
||||
- `/Users/delete/projects/update_server/cmd/migrate/main.go`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/open.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/migrate.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/store.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/migrate_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/migrations/README.md`
|
||||
- `/Users/delete/projects/update_server/migrations/0001_initial_schema.sql`
|
||||
- `/Users/delete/projects/update_server/migrations/0002_indexes_and_triggers.sql`
|
||||
- `/Users/delete/projects/update_server/migrations/0003_api_key_scope_guards.sql`
|
||||
|
||||
## Database Changes
|
||||
|
||||
Added migrations:
|
||||
|
||||
- `0001_initial_schema.sql`
|
||||
- `0002_indexes_and_triggers.sql`
|
||||
- `0003_api_key_scope_guards.sql`
|
||||
|
||||
Schema notes:
|
||||
|
||||
- timestamps are stored as UTC RFC3339-like text values;
|
||||
- `api_keys.scope_mode` is constrained to the agreed modes:
|
||||
- `all_projects`
|
||||
- `project_allow_list`
|
||||
- `project_deny_list`
|
||||
- `tag_allow_list`
|
||||
- `tag_deny_list`
|
||||
- `api_key_project_access` only accepts keys in project-based modes;
|
||||
- `api_key_tag_access` only accepts keys in tag-based modes;
|
||||
- changing an API key to an incompatible scope mode is blocked if incompatible access rows already exist;
|
||||
- `sessions` stores hashed session tokens, not raw tokens;
|
||||
- `audit_logs` storage is included, but no runtime writes are wired yet.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- no new route groups or business endpoints were added;
|
||||
- `GET /healthz` now includes SQLite readiness and returns `503` if the store is unavailable;
|
||||
- updated the placeholder `/` and `/api/v1` responses to reflect database readiness.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./cmd ./internal` - completed successfully;
|
||||
- `go mod tidy` - initially failed in the sandbox due Go cache/network restrictions; completed successfully after rerunning with normal access and temporary Go caches;
|
||||
- `GOCACHE=/tmp/go-build-sqlite3 GOMODCACHE=/tmp/go-mod-sqlite3 go test ./...` - passed;
|
||||
- `GOCACHE=/tmp/go-build-sqlite3 GOMODCACHE=/tmp/go-mod-sqlite3 go build -o /tmp/update-server ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-sqlite3 GOMODCACHE=/tmp/go-mod-sqlite3 go build -o /tmp/update-migrate ./cmd/migrate` - passed;
|
||||
- `APP_BASE_URL=http://127.0.0.1:18080 DATA_DIR=/tmp/update-server-db-dev-2 /tmp/update-migrate` - applied migrations successfully to a fresh temp SQLite database;
|
||||
- `sqlite3 /tmp/update-server-db-dev-2/db.sqlite 'SELECT name FROM schema_migrations ORDER BY name;'` - confirmed all three migrations were recorded;
|
||||
- started `/tmp/update-server` on `127.0.0.1:18080` and verified:
|
||||
- `GET /` -> `200 OK`
|
||||
- `GET /api/v1` -> `200 OK`
|
||||
- `GET /healthz` -> `200 OK` with `"database":"ok"`
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- repository structs are intentionally scaffolding-only in this stage; feature-specific query methods are still for later agents to add;
|
||||
- no auth/session business logic is implemented yet beyond the schema and store foundation;
|
||||
- `audit_logs` exists in schema only; event production is deferred;
|
||||
- scope-mode enforcement now covers schema consistency for access-link rows, but full project/tag access evaluation logic is still for the API key stage;
|
||||
- existing local databases created before the final scope-guard addition need the new `0003_api_key_scope_guards.sql` migration applied, which the updated startup path now does automatically.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 03 should implement admin authentication next using the new `users` and `sessions` tables: bootstrap the first admin user from environment, hash passwords, create/invalidate session records, and protect the `/admin` route group with session middleware.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- pay extra attention to migration immutability: `schema_migrations` stores a checksum and should reject edited applied files;
|
||||
- validate that the default server startup path now opens SQLite and auto-applies `0001` -> `0003`;
|
||||
- validate that project/tag access link rows are rejected when the parent API key uses the wrong `scope_mode`;
|
||||
- the workspace is not a git repository, so diff-based review may need to rely on direct file inspection.
|
||||
92
docs/agents/handoffs/03-auth.md
Normal file
92
docs/agents/handoffs/03-auth.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 03 - Authentication And Admin Sessions
|
||||
|
||||
Stage: Authentication And Admin Sessions
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented admin authentication and session management on top of the existing `users` and `sessions` tables.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added auth-related config for bootstrap credentials, session cookie naming, session TTL, and secure-cookie detection from `APP_BASE_URL`;
|
||||
- implemented bcrypt password hashing and verification in a dedicated `internal/auth` service;
|
||||
- added admin bootstrap logic that creates the first active admin user from `ADMIN_EMAIL` and `ADMIN_PASSWORD` when no active admin exists yet;
|
||||
- implemented user/session repository methods for bootstrap lookup, login, session lookup, session touch, and logout invalidation;
|
||||
- added secure random session token generation with SHA-256 hashed token storage in SQLite;
|
||||
- wired login and logout handlers plus authenticated session middleware into the existing `chi` route-group structure;
|
||||
- protected the `/admin` route group with session and role checks;
|
||||
- replaced the placeholder admin page with a protected authenticated dashboard and added a server-rendered login form;
|
||||
- added tests for bootstrap behavior and the login/protected-route/logout flow.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/go.mod`
|
||||
- `/Users/delete/projects/update_server/go.sum`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/context.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/password.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/service_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/errors.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/time.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/users.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/sessions.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/render.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_middleware.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/home.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/admin.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/login.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration changes were required in this stage;
|
||||
- the existing `users` and `sessions` tables from Agent 02 are now actively used for bootstrap, login, session lookup, and logout invalidation;
|
||||
- session tokens continue to be stored hashed only;
|
||||
- user `last_login_at` and session `last_seen_at` are now updated by runtime auth flows.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added `GET /admin/login` for the server-rendered login form;
|
||||
- added `POST /admin/login` to authenticate an admin user and issue a session cookie;
|
||||
- added `POST /admin/logout` to invalidate the current session and clear the cookie;
|
||||
- changed `/admin` from a public placeholder to a protected route group guarded by session middleware and admin-role checks;
|
||||
- retained the existing `/api/v1` route scaffold unchanged.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./cmd ./internal` - passed;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go mod tidy` - initially failed in the sandbox due network/DNS restrictions, then passed after rerunning with approval;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go test ./...` - passed;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go build -o /tmp/update-server-auth ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-auth GOMODCACHE=/tmp/go-mod-auth go build -o /tmp/update-migrate-auth ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- CSRF protection is not implemented yet for admin forms; this remains for the hardening stage;
|
||||
- login rate limiting is not implemented yet;
|
||||
- bootstrap is environment-driven only in this stage; there is no separate one-time bootstrap CLI yet;
|
||||
- if no active admin exists and the configured `ADMIN_EMAIL` already belongs to a non-admin user, bootstrap currently logs a warning and leaves that conflict for an operator to resolve;
|
||||
- there is no admin user-management UI yet beyond the initial bootstrap/login foundation.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 04 should build project, tag, and release management on top of the now-protected `/admin` route group, reusing the authenticated session context instead of adding a parallel auth path.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that `POST /admin/login` creates a DB-backed session and stores only the token hash in SQLite, not the raw cookie value;
|
||||
- verify that `/admin` redirects when unauthenticated and succeeds when the issued session cookie is replayed;
|
||||
- verify that `POST /admin/logout` invalidates the existing session record so the old cookie no longer grants access;
|
||||
- verify bootstrap behavior both when `ADMIN_EMAIL` and `ADMIN_PASSWORD` are present and when they are absent.
|
||||
105
docs/agents/handoffs/04-projects-releases.md
Normal file
105
docs/agents/handoffs/04-projects-releases.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 04 - Projects, Tags, And Releases
|
||||
|
||||
Stage: Projects, Tags, And Releases
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented the core product data management stage on top of the existing authenticated `/admin` route group.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added artifact storage configuration rooted under `DATA_DIR/artifacts`, with validation that artifacts stay outside the public static directory;
|
||||
- implemented local filesystem artifact storage with temp-file staging and final path validation;
|
||||
- added project repository methods for create, update, list, archive toggle, and project-tag assignment queries;
|
||||
- added tag repository methods for create, update, list, delete-if-unused, and project usage queries;
|
||||
- added release repository methods for create, lookup, and per-project release listing;
|
||||
- implemented a release upload service that sanitizes filenames, streams uploads to a temp artifact, computes SHA-256 checksums, detects content type, moves the file into structured private storage, and writes release metadata to SQLite;
|
||||
- extended the protected admin router with project list/create/detail/archive routes, tag list/create/detail/delete routes, project-tag attach or detach actions, and release upload handling;
|
||||
- replaced the placeholder dashboard with project/tag/release-aware admin pages and added server-rendered templates for project list, project detail, project creation, tag list, and tag detail;
|
||||
- added integration coverage for the admin flow that logs in, creates and edits project/tag data, attaches tags, uploads a release, verifies the checksum and sanitized filename, and checks the artifact on disk.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/errors.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/tags.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/releases.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/render.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_common.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_tags.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/projects_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/releases/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/slug/slug.go`
|
||||
- `/Users/delete/projects/update_server/internal/storage/local.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/admin.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/home.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/login.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/projects.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_detail.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/tags.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/tag_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/04-projects-releases.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration changes were required in this stage;
|
||||
- the existing `projects`, `tags`, `project_tags`, and `releases` tables are now actively used by repository methods and protected admin workflows;
|
||||
- release `storage_path` values are now persisted as relative paths underneath the configured artifact root;
|
||||
- release rows now store sanitized filenames, SHA-256 checksum values, detected content type, file size, release notes, and uploader linkage.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added `GET /admin/projects` for the protected project list page;
|
||||
- added `GET /admin/projects/new` and `POST /admin/projects` for project creation;
|
||||
- added `GET /admin/projects/{projectID}` and `POST /admin/projects/{projectID}` for project detail and editing;
|
||||
- added `POST /admin/projects/{projectID}/archive` for archive or restore actions;
|
||||
- added `POST /admin/projects/{projectID}/tags` and `POST /admin/projects/{projectID}/tags/{tagID}/detach` for project-tag assignment;
|
||||
- added `POST /admin/projects/{projectID}/releases` for protected release uploads;
|
||||
- added `GET /admin/tags`, `GET /admin/tags/new`, and `POST /admin/tags` for tag list and creation;
|
||||
- added `GET /admin/tags/{tagID}`, `POST /admin/tags/{tagID}`, and `POST /admin/tags/{tagID}/delete` for tag edit and delete-if-unused behavior;
|
||||
- updated `GET /admin` to show project/tag/release summary data instead of the auth-only placeholder;
|
||||
- kept `/api/v1` unchanged and intentionally did not add API key or client update endpoints in this stage.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w ./internal ./cmd` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent04 GOMODCACHE=/tmp/go-mod-agent04 go test ./...` - initially failed in the sandbox due dependency download DNS restrictions, then passed after rerunning with approval;
|
||||
- `GOCACHE=/tmp/go-build-agent04 GOMODCACHE=/tmp/go-mod-agent04 go build -o /tmp/update-server-agent04 ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent04 GOMODCACHE=/tmp/go-mod-agent04 go build -o /tmp/update-migrate-agent04 ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- CSRF protection is still not implemented for admin forms, including the new project, tag, archive, and upload actions;
|
||||
- release deletion or disable flows are not implemented in this stage;
|
||||
- there is still no client-facing download or metadata endpoint for releases; only the protected admin upload and metadata path is present;
|
||||
- duplicate project slugs, tag slugs, and `(project_id, version, build)` release combinations are rejected rather than offering replace-in-place behavior;
|
||||
- upload handling currently relies on the standard multipart temp-file path before final storage, which is acceptable for MVP but not yet a custom streaming parser.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 05 should implement API key generation, hashing, permissions, and scope evaluation on top of the now-working project and tag data model, using the existing `projects`, `tags`, and assignment relationships for allow-list and deny-list management.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that all new admin project and tag routes remain inside the existing authenticated `/admin` route group and reuse the session context;
|
||||
- verify that uploaded artifacts land under `DATA_DIR/artifacts` and not under `web/static`;
|
||||
- verify that uploaded filenames are sanitized before persistence and that `releases.checksum_sha256` matches the actual file bytes on disk;
|
||||
- verify that release metadata rows are written to SQLite with the expected storage path, size, content type, and uploader linkage;
|
||||
- verify that project archive or restore toggles `projects.is_active`;
|
||||
- verify that tag deletion is blocked while the tag is still attached to a project.
|
||||
63
docs/agents/handoffs/05-api-keys-fix.md
Normal file
63
docs/agents/handoffs/05-api-keys-fix.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 05 - API Keys And Access Control (fix round)
|
||||
|
||||
Stage: API Keys And Access Control
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Fixed the validation findings for Agent 05 without expanding into the client API stage.
|
||||
|
||||
Completed in this fix round:
|
||||
|
||||
- added explicit anti-cache headers for the one-time raw API key reveal response so the secret-bearing HTML is marked non-cacheable;
|
||||
- changed the immediate post-create detail render to hydrate from the persisted API key record and persisted scope rows while still showing the raw key only on that one response;
|
||||
- extended HTTP integration coverage to verify:
|
||||
- the creation response includes anti-cache headers;
|
||||
- the creation response shows saved name, description, scope mode, permissions, and selected project or tag rules;
|
||||
- the raw key is present on the creation response and absent on later detail loads.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_api_keys.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/05-api-keys-fix.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no schema or migration changes were required;
|
||||
- the existing API key hash and scope storage model remains unchanged.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- no routes were added or removed;
|
||||
- `POST /admin/api-keys` now returns the one-time reveal page with explicit anti-cache headers:
|
||||
- `Cache-Control: no-store, private, max-age=0`
|
||||
- `Pragma: no-cache`
|
||||
- `Expires: 0`
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/http/admin_api_keys.go internal/http/api_keys_integration_test.go` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix GOMODCACHE=/tmp/go-mod-agent05-2 go test ./internal/http` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix-all GOMODCACHE=/tmp/go-mod-agent05-2 go test ./...` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix-build GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-server-agent05-fix ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-fix-build2 GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-migrate-agent05-fix ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- the one-time reveal still intentionally happens on the direct POST response rather than a redirect flow so the raw key never has to enter query strings or persistent storage;
|
||||
- CSRF protection is still not implemented for admin API key forms;
|
||||
- the client `/api/v1` endpoints still do not use the API key middleware yet; that remains for Agent 06.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 06 should wire the existing API key middleware into the client `/api/v1` endpoints for accessible project listing, latest release lookup, and authenticated artifact download.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that the post-create response shows persisted saved values immediately, without requiring a manual refresh;
|
||||
- verify that the raw key appears only on the secret-bearing creation response and not on later `GET /admin/api-keys/{id}` detail loads;
|
||||
- verify the one-time reveal response includes the anti-cache headers listed above.
|
||||
90
docs/agents/handoffs/05-api-keys.md
Normal file
90
docs/agents/handoffs/05-api-keys.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 05 - API Keys And Access Control
|
||||
|
||||
Stage: API Keys And Access Control
|
||||
|
||||
Date: 2026-04-14
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented the API key lifecycle and access-control stage on top of the existing authenticated admin workspace and the project or tag model from Agent 04.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added a dedicated `internal/apikeys` service for secure API key generation, SHA-256 hashing, lookup, lifecycle checks, and project scope evaluation;
|
||||
- implemented full API key repository support for create, update, list, revoke or activate, last-used tracking, project and tag rule storage, and effective access queries;
|
||||
- added minimal protected admin pages for API key list, creation, detail, update, and revoke or activate actions;
|
||||
- implemented one-time raw key reveal behavior by showing the generated key only in the immediate creation response while persisting only the short prefix and hash;
|
||||
- added permission and project-scope middleware helpers for future `/api/v1` client routes using bearer authentication;
|
||||
- added integration and unit coverage for hashed storage, expired or revoked key rejection, all five scope modes, scope transitions, middleware enforcement, and admin key management flow.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/models.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/apikeys.go`
|
||||
- `/Users/delete/projects/update_server/internal/apikeys/context.go`
|
||||
- `/Users/delete/projects/update_server/internal/apikeys/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/apikeys/service_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_api_keys.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_key_middleware.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_key_middleware_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_keys.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_key_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/05-api-keys.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no new migrations were required because the existing `api_keys`, `api_key_project_access`, and `api_key_tag_access` tables already existed from Agent 02 and the scope guard triggers already existed from migration `0003_api_key_scope_guards.sql`;
|
||||
- the new repository code now actively uses those tables and trigger rules for key lifecycle, project allow or deny lists, and tag allow or deny lists;
|
||||
- API keys are stored with a short visible `key_prefix` and a hashed `key_hash`; the raw key is never persisted.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- added protected admin routes:
|
||||
- `GET /admin/api-keys`
|
||||
- `GET /admin/api-keys/new`
|
||||
- `POST /admin/api-keys`
|
||||
- `GET /admin/api-keys/{apiKeyID}`
|
||||
- `POST /admin/api-keys/{apiKeyID}`
|
||||
- `POST /admin/api-keys/{apiKeyID}/activate`
|
||||
- added reusable middleware helpers for future client API routes:
|
||||
- `requireAPIKey`
|
||||
- `requireAPIKeyPermission`
|
||||
- `requireAPIKeyProjectAccess`
|
||||
- kept `/api/v1` client endpoints themselves out of scope for this stage so Agent 06 can wire them onto the new middleware and access-resolution layer.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/app/app.go internal/db/models.go internal/db/apikeys.go internal/apikeys/context.go internal/apikeys/service.go internal/http/router.go internal/http/handlers.go internal/http/view_data.go internal/http/admin_api_keys.go internal/http/api_key_middleware.go internal/http/auth_integration_test.go internal/apikeys/service_test.go internal/http/api_key_middleware_test.go internal/http/api_keys_integration_test.go` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-2 GOMODCACHE=/tmp/go-mod-agent05-2 go test ./...` - passed after downloading dependencies with approval;
|
||||
- `GOCACHE=/tmp/go-build-agent05-build GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-server-agent05 ./cmd/server` - passed;
|
||||
- `GOCACHE=/tmp/go-build-agent05-build2 GOMODCACHE=/tmp/go-mod-agent05-2 go build -o /tmp/update-migrate-agent05 ./cmd/migrate` - passed.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- CSRF protection is still not implemented for admin forms, including the new API key creation, update, and revoke or activate actions;
|
||||
- the admin API key UI is intentionally minimal and functional rather than polished;
|
||||
- the one-time reveal happens on the direct POST response instead of a PRG redirect because the raw key must not be placed into query strings or persistent storage;
|
||||
- no live client `/api/v1` endpoints use the new middleware yet; the groundwork is ready but the actual project list, latest-release, and download endpoints remain for Agent 06;
|
||||
- expiration input currently accepts either empty, `YYYY-MM-DD`, or full RFC3339 UTC text rather than a more polished timezone-aware widget.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Agent 06 should wire the new `requireAPIKey`, `requireAPIKeyPermission`, and `requireAPIKeyProjectAccess` middleware into the client `/api/v1` endpoints for accessible-project listing, latest release lookup, and authenticated artifact download.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that only `key_prefix` and `key_hash` are stored in SQLite and that the raw key appears only in the immediate creation response;
|
||||
- verify that revoked or expired keys are rejected by `requireAPIKey` with `401` and that missing permissions or blocked project scope return `403`;
|
||||
- verify effective access resolution across all five scope modes, especially that archived projects do not appear in accessible-project results;
|
||||
- verify scope transitions clear the incompatible access rows so the existing migration guards continue to succeed;
|
||||
- verify the admin detail page preview matches the effective active project set for the key.
|
||||
100
docs/agents/handoffs/06-client-api-ui.md
Normal file
100
docs/agents/handoffs/06-client-api-ui.md
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 06 - Client API And Admin UI
|
||||
|
||||
Stage: Client API And Admin UI
|
||||
|
||||
Date: 2026-04-15
|
||||
|
||||
## Scope
|
||||
|
||||
Implemented the usable end-to-end product flow for admins and client applications on top of the existing project, release, and API key work from Agents 04 and 05.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added bearer-authenticated client endpoints under `/api/v1` for:
|
||||
- listing accessible active projects;
|
||||
- looking up the latest active release for an accessible project;
|
||||
- fetching release metadata by release ID for an accessible project;
|
||||
- downloading private release artifacts by release ID after auth, permission, and scope checks;
|
||||
- reused the existing API key middleware and scope-evaluation service so disabled or expired keys return `401`, missing download permission returns `403`, and inaccessible projects or releases return `404` to avoid leaking unauthorized resources;
|
||||
- added project slug lookup and latest-active-release repository queries so client handlers can resolve project-scoped metadata cleanly from persisted release rows;
|
||||
- added a safe artifact-open path on top of the existing private local storage so downloads stream from the artifact root instead of exposing raw filesystem paths or static URLs;
|
||||
- updated the API index and the home or dashboard copy so the live client API is discoverable instead of still looking like a placeholder;
|
||||
- added small admin UI improvements on project detail and API key detail pages that show the client API paths and a bearer-auth quick-start example after an admin uploads a release or creates a key;
|
||||
- added integration coverage for the client flow, including auth failures, scope enforcement, latest-release selection, release metadata lookup, and authorized or unauthorized download behavior.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/db/projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/releases.go`
|
||||
- `/Users/delete/projects/update_server/internal/storage/local.go`
|
||||
- `/Users/delete/projects/update_server/internal/releases/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_common.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_projects.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/client_api.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/client_api_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/projects_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_detail.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_key_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_keys.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/static/app.css`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/06-client-api-ui.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no new migrations or schema changes were required;
|
||||
- added repository queries against the existing `projects` and `releases` tables:
|
||||
- project lookup by slug;
|
||||
- latest active release lookup ordered by persisted `created_at DESC, id DESC`;
|
||||
- continued using the existing API key scope tables and scope modes without redesign.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- kept `GET /api/v1` public and upgraded it from a placeholder to a real client API index;
|
||||
- added protected client routes behind bearer API key auth plus `can_download` permission:
|
||||
- `GET /api/v1/projects`
|
||||
- `GET /api/v1/projects/{projectSlug}/releases/latest`
|
||||
- `GET /api/v1/releases/{releaseID}`
|
||||
- `GET /api/v1/releases/{releaseID}/download`
|
||||
- resource access behavior for client routes:
|
||||
- missing, invalid, disabled, or expired API key -> `401`
|
||||
- authenticated key without download permission -> `403`
|
||||
- inaccessible or archived project or release -> `404`
|
||||
- admin UI additions:
|
||||
- project detail page now shows the relevant client API paths for that project and latest release;
|
||||
- API key detail page now shows a bearer-auth quick-start example plus the accessible project metadata paths.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/db/projects.go internal/db/releases.go internal/storage/local.go internal/http/view_data.go internal/http/admin_common.go internal/http/admin_projects.go internal/http/router.go internal/http/handlers.go internal/http/client_api.go internal/releases/service.go internal/http/api_keys_integration_test.go internal/http/projects_integration_test.go internal/http/client_api_integration_test.go` - passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-http GOMODCACHE=/tmp/go-mod-agent06-http go test ./internal/http ./internal/releases ./internal/db ./internal/apikeys` - initially failed in sandbox because module downloads could not resolve DNS, then passed after rerunning with approval
|
||||
- `GOCACHE=/tmp/go-build-agent06-all GOMODCACHE=/tmp/go-mod-agent06-http go test ./...` - passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-build GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-server-agent06 ./cmd/server` - passed
|
||||
- `GOCACHE=/tmp/go-build-agent06-migrate GOMODCACHE=/tmp/go-mod-agent06-http go build -o /tmp/update-migrate-agent06 ./cmd/migrate` - passed
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- “Latest” currently means the newest active persisted release by `created_at` and `id`, not semantic-version comparison;
|
||||
- the optional client query parameters mentioned in the product spec (`current_version`, `channel`, `platform`, `arch`) are still not implemented;
|
||||
- the client API does not yet expose full per-project release listing; this stage focused on the required list, latest-metadata, metadata-by-ID, and download flow;
|
||||
- the admin quick-start example can show the real raw key only on the one-time create response; later detail views intentionally fall back to a placeholder token;
|
||||
- broader hardening work such as CSRF completion, rate limiting, security headers, audit logging polish, and deployment proxy setup remains out of scope for this stage.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Run the validation pass for Agent 06, then move to Agent 07 to implement the planned hardening and deployment-focused follow-up: CSRF, security headers, rate limiting, audit/logging polish, and deployment readiness around the now-working end-to-end product flow.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that client routes require `Authorization: Bearer <api_key>` and that disabled or expired keys are rejected with `401`;
|
||||
- verify that client routes require `can_download` and return `403` when the key authenticates but lacks download permission;
|
||||
- verify that unauthorized, archived, or out-of-scope projects and releases return `404` from metadata and download paths rather than leaking through a `403`;
|
||||
- verify that `GET /api/v1/projects` returns only active projects allowed by the key’s scope evaluation;
|
||||
- verify that the latest-release endpoint selects the newest active persisted release row for the project;
|
||||
- verify that the download endpoint streams bytes from private artifact storage and does not expose static URLs or raw filesystem paths;
|
||||
- verify that the project detail and API key detail admin pages visibly expose the new client API quick-start information.
|
||||
134
docs/agents/handoffs/07-security-deploy.md
Normal file
134
docs/agents/handoffs/07-security-deploy.md
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
# Agent
|
||||
|
||||
Name: Agent 07 - Security And Deployment Hardening
|
||||
|
||||
Stage: Security And Deployment Hardening
|
||||
|
||||
Date: 2026-04-15
|
||||
|
||||
## Scope
|
||||
|
||||
Hardened the existing Go/chi/SQLite application for internet-facing deployment without changing the product model or admin/client flow.
|
||||
|
||||
Completed in this stage:
|
||||
|
||||
- added stricter HTTP server defaults:
|
||||
- `ReadHeaderTimeout`
|
||||
- `MaxHeaderBytes`
|
||||
- higher default read/write/idle timeouts suitable for uploads and authenticated downloads
|
||||
- added global security headers and route-specific cache controls:
|
||||
- `Content-Security-Policy`
|
||||
- `X-Frame-Options`
|
||||
- `X-Content-Type-Options`
|
||||
- `Referrer-Policy`
|
||||
- `Permissions-Policy`
|
||||
- `Cross-Origin-Opener-Policy`
|
||||
- `Cross-Origin-Resource-Policy`
|
||||
- `Strict-Transport-Security` when `APP_BASE_URL` is `https`
|
||||
- `Cache-Control: no-store` on admin and protected client API responses
|
||||
- `Vary: Cookie` or `Vary: Authorization` on the appropriate routes
|
||||
- added trusted-proxy awareness so forwarded headers are only trusted when `TRUST_PROXY_HEADERS=true`;
|
||||
- added in-memory rate limiting for:
|
||||
- `POST /admin/login`
|
||||
- protected client API routes under `/api/v1`
|
||||
- added CSRF protection for all admin POST flows, including login, logout, project/tag/API key forms, tag attach or detach, archive or restore, and multipart release upload;
|
||||
- rotated or cleared the admin CSRF cookie on login and logout, and scoped both session and CSRF cookies to `/admin`;
|
||||
- tightened local data directory permissions for SQLite and data storage;
|
||||
- added regression coverage for CSRF rejection, hardened cookie defaults, security headers, and both rate-limited route groups;
|
||||
- added first-pass deployment assets:
|
||||
- multi-stage `Dockerfile`
|
||||
- hardened `docker-compose.yml`
|
||||
- Caddy example
|
||||
- Nginx example
|
||||
- env example
|
||||
- deployment, Proxmox, backup, and restore notes.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `/Users/delete/projects/update_server/internal/config/config.go`
|
||||
- `/Users/delete/projects/update_server/internal/app/app.go`
|
||||
- `/Users/delete/projects/update_server/internal/db/open.go`
|
||||
- `/Users/delete/projects/update_server/internal/auth/service.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/router.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/security.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/rate_limit.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/csrf.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_handlers.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_common.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/admin_api_keys.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/view_data.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/auth_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/projects_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/api_keys_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/internal/http/security_integration_test.go`
|
||||
- `/Users/delete/projects/update_server/web/templates/layouts/base.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/login.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/project_detail.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/tag_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/pages/api_key_form.gohtml`
|
||||
- `/Users/delete/projects/update_server/web/templates/partials/csrf_field.gohtml`
|
||||
- `/Users/delete/projects/update_server/.dockerignore`
|
||||
- `/Users/delete/projects/update_server/Dockerfile`
|
||||
- `/Users/delete/projects/update_server/docker-compose.yml`
|
||||
- `/Users/delete/projects/update_server/deploy/Caddyfile.example`
|
||||
- `/Users/delete/projects/update_server/deploy/nginx.update-server.conf.example`
|
||||
- `/Users/delete/projects/update_server/deploy/update-server.env.example`
|
||||
- `/Users/delete/projects/update_server/docs/DEPLOYMENT.md`
|
||||
- `/Users/delete/projects/update_server/docs/agents/handoffs/07-security-deploy.md`
|
||||
|
||||
## Database Changes
|
||||
|
||||
- no migrations or schema changes were required;
|
||||
- SQLite remains the production database;
|
||||
- deployment notes now explicitly call out WAL-mode backup and restore handling for:
|
||||
- `db.sqlite`
|
||||
- `db.sqlite-wal`
|
||||
- `db.sqlite-shm`
|
||||
- `artifacts/`.
|
||||
|
||||
## API Or Route Changes
|
||||
|
||||
- no new product endpoints were added;
|
||||
- middleware behavior changed for existing routes:
|
||||
- all `/admin` responses now emit hardened headers and `no-store` caching rules;
|
||||
- all `/admin` POST routes now require a valid CSRF token;
|
||||
- `POST /admin/login` is rate limited by client IP;
|
||||
- protected `/api/v1` routes now emit hardened headers and `no-store` caching rules;
|
||||
- protected `/api/v1` routes are rate limited by client IP before API-key auth;
|
||||
- session cookies are now scoped to `/admin` and retain `HttpOnly`, `SameSite=Lax`, and conditional `Secure`;
|
||||
- CSRF cookies are now scoped to `/admin` and use `HttpOnly`, `SameSite=Strict`, and conditional `Secure`.
|
||||
|
||||
## Commands And Tests Run
|
||||
|
||||
- `gofmt -w internal/config/config.go internal/app/app.go internal/db/open.go internal/auth/service.go internal/http/router.go internal/http/security.go internal/http/rate_limit.go internal/http/csrf.go internal/http/auth_handlers.go internal/http/view_data.go internal/http/admin_common.go internal/http/admin_api_keys.go internal/http/auth_integration_test.go internal/http/projects_integration_test.go internal/http/api_keys_integration_test.go internal/http/security_integration_test.go` - passed
|
||||
- `go test ./internal/http` - passed
|
||||
- `go test ./...` - passed
|
||||
- `go build ./cmd/server` - passed
|
||||
- `go build ./cmd/migrate` - passed
|
||||
- `docker compose config` - could not run in this environment because `docker` is not installed
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- rate limiting is in-memory and per-process, so counters reset on restart and are not shared across multiple app instances;
|
||||
- Docker and reverse-proxy examples were added and reviewed statically, but they were not live-validated here because Docker is unavailable in this workspace;
|
||||
- `Strict-Transport-Security` only appears when `APP_BASE_URL` is configured with `https`, which is the intended production setup behind TLS termination;
|
||||
- the proxy still must be configured correctly to keep the app private and to strip or control forwarded headers before `TRUST_PROXY_HEADERS=true` is safe.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Run the Agent 07 validation pass, with special attention to:
|
||||
|
||||
- CSRF enforcement on every admin POST flow, including multipart upload;
|
||||
- security headers and private-cache headers on admin and protected client API responses;
|
||||
- login and client API rate limiting behavior;
|
||||
- cookie flags and `/admin` cookie scoping;
|
||||
- deployment docs and example proxy/container files on a host that has Docker and a reverse proxy available.
|
||||
|
||||
## Notes For Validator
|
||||
|
||||
- verify that a missing or invalid admin CSRF token returns `403` and that the normal admin flows still succeed when the token is present;
|
||||
- verify that session cookies are only scoped to `/admin` and that secure-cookie behavior follows the configured `APP_BASE_URL` scheme;
|
||||
- verify that `TRUST_PROXY_HEADERS=false` leaves client IP handling on the socket remote address;
|
||||
- verify that protected `/api/v1` responses include `Cache-Control: no-store`, `Vary: Authorization`, and the shared security headers;
|
||||
- if possible, validate `docker compose up --build` plus one reverse-proxy example on a real machine, since that could not be executed in this environment.
|
||||
13
docs/agents/handoffs/README.md
Normal file
13
docs/agents/handoffs/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Handoffs Directory
|
||||
|
||||
Save one handoff markdown file here after every implementation stage.
|
||||
|
||||
Naming convention:
|
||||
|
||||
- `01-foundation.md`
|
||||
- `02-database.md`
|
||||
- `03-auth.md`
|
||||
- `04-projects-releases.md`
|
||||
- `05-api-keys.md`
|
||||
- `06-client-api-ui.md`
|
||||
- `07-security-deploy.md`
|
||||
Loading…
Add table
Add a link
Reference in a new issue