7.4 KiB
7.4 KiB
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:
ReadHeaderTimeoutMaxHeaderBytes- higher default read/write/idle timeouts suitable for uploads and authenticated downloads
- added global security headers and route-specific cache controls:
Content-Security-PolicyX-Frame-OptionsX-Content-Type-OptionsReferrer-PolicyPermissions-PolicyCross-Origin-Opener-PolicyCross-Origin-Resource-PolicyStrict-Transport-SecuritywhenAPP_BASE_URLishttpsCache-Control: no-storeon admin and protected client API responsesVary: CookieorVary: Authorizationon 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.
- multi-stage
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.sqlitedb.sqlite-waldb.sqlite-shmartifacts/.
API Or Route Changes
- no new product endpoints were added;
- middleware behavior changed for existing routes:
- all
/adminresponses now emit hardened headers andno-storecaching rules; - all
/adminPOST routes now require a valid CSRF token; POST /admin/loginis rate limited by client IP;- protected
/api/v1routes now emit hardened headers andno-storecaching rules; - protected
/api/v1routes are rate limited by client IP before API-key auth;
- all
- session cookies are now scoped to
/adminand retainHttpOnly,SameSite=Lax, and conditionalSecure; - CSRF cookies are now scoped to
/adminand useHttpOnly,SameSite=Strict, and conditionalSecure.
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- passedgo test ./internal/http- passedgo test ./...- passedgo build ./cmd/server- passedgo build ./cmd/migrate- passeddocker compose config- could not run in this environment becausedockeris 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-Securityonly appears whenAPP_BASE_URLis configured withhttps, 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=trueis 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
/admincookie 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
403and that the normal admin flows still succeed when the token is present; - verify that session cookies are only scoped to
/adminand that secure-cookie behavior follows the configuredAPP_BASE_URLscheme; - verify that
TRUST_PROXY_HEADERS=falseleaves client IP handling on the socket remote address; - verify that protected
/api/v1responses includeCache-Control: no-store,Vary: Authorization, and the shared security headers; - if possible, validate
docker compose up --buildplus one reverse-proxy example on a real machine, since that could not be executed in this environment.