feat(frontend): serve RFC 9116 security.txt at /.well-known/security.txt - #7
Open
JRojowski wants to merge 9 commits into
Open
feat(frontend): serve RFC 9116 security.txt at /.well-known/security.txt#7JRojowski wants to merge 9 commits into
JRojowski wants to merge 9 commits into
Conversation
* fix(checkoutservice): use %s verb in status.Errorf for error message
go 1.26's go vet rejects passing a non-constant string (err.Error()) as the
format argument to status.Errorf. Pass it via %s so the error can never be
misinterpreted as a format string. Surfaced while wiring the dev-kit quality
gate (go test ./... runs vet).
* chore(dev-kit): bootstrap spec-driven pipeline (vendor runtime + configure quality gate, workflow anchor, e2e runbook)
Vendor the dev-kit runtime (v0.5.5) into the repo so every teammate gets the
pipeline on git pull with no per-user setup:
- .claude/skills/{dev-kit,work-*}, .claude/agents/{coder,e2e-tester},
.claude/hooks/quality-gate.sh, dev-kit.manifest
- Routed quality gate (.claude/quality-gate.routes): per-service Go + C# build/test
(shipping, productcatalog, frontend, checkout, cartservice) + protos composite;
Node/Python/Java left to each task's acceptance check (not CI-tested).
- CLAUDE.md workflow anchor + per-service Commands + Structure.
- docs/test/README.md e2e runbook: full-stack skaffold bring-up + per-service smokes.
- Branch-per-unit + squash-PR policy.
Extract package-level securityTxtHandler + registerSecurityTxtRoute so the route can be exercised via httptest without running main() or dialing gRPC backends. Placeholder body only; compliant response follows. Refs docs/work/001-security-txt (P3-01, P3-02).
Given-When-Then httptest coverage for T-001..T-007 against a router built via registerSecurityTxtRoute (no main(), no gRPC). Expected-red: T-003..T-006 fail against the placeholder body until the handler is implemented; T-001/T-002/ T-007 already pass (routing + content sniffing). Refs docs/work/001-security-txt (P3-03).
Emit the two required fields — Contact (mailto:security@example.com) and a computed Expires (now + 1 year, RFC 3339) so it never goes stale — with an explicit Content-Type: text/plain; charset=utf-8. Turns T-002..T-006 green. Refs docs/work/001-security-txt (P3-04).
No code changes needed; frontend build + full test suite green (107 tests), gofmt clean on main.go and security_txt_test.go. Refs docs/work/001-security-txt (P3-05).
Brought up the full stack via skaffold on a kind cluster and curled GET /.well-known/security.txt through the frontend: 200, Content-Type text/plain; charset=utf-8, Contact + future RFC 3339 Expires present. Refs docs/work/001-security-txt (P3-06).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new public HTTP endpoint to the frontend service:
GET /.well-known/security.txt, returning an RFC 9116-compliant response.RFC 9116 requires exactly two fields; this endpoint emits only those:
Contact(required, §2.5.3) —mailto:security@example.com(demo placeholder).Expires(required, §2.5.5) — computed at request time asnow + 1 year(RFC 3339), so it never goes stale and always satisfies the <1-year recommendation.All optional/recommended fields (Encryption, Acknowledgments, Preferred-Languages, Canonical, Policy, Hiring) are intentionally omitted. Response is served with an explicit
Content-Type: text/plain; charset=utf-8.Implementation
securityTxtHandler+registerSecurityTxtRoute(r, baseUrl), called by bothmain()and tests (sohttptestruns without dialing gRPC backends).HandleFuncpath (notPathPrefix), mirroring the existingrobots.txt/_healthzhandlers.Verification
cd src/frontend && go build ./... && go test ./...— green (107 tests).skaffold run—curl -ireturned200, correct Content-Type,Contact, and a future RFC 3339Expires. Evidence indocs/test/001-security-txt/.Pipeline artifacts
Spec-driven pipeline (research → tests → plan → execute → docs):
docs/work/001-security-txt/.Docs reconcile: no drift — no doc enumerates frontend routes (consistent with the undocumented
robots.txt/_healthz), so no doc changes were needed.Squash-merge to
main; team reviews and merges manually.