14 KiB
14 KiB
title, source_type, status, branch, parent_branch, related_projects, tags, created, target_merge, status_label, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, contract_packet_sha256
| title | source_type | status | branch | parent_branch | related_projects | tags | created | target_merge | status_label | id | kind | project | work_item | inherits | refines | overrides | depends_on | contract_packet | contract_packet_sha256 | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| branch / feature-sample-portfolio-public-access | branch-note | raw | feature-sample-portfolio-public-access |
|
|
2026-07-03 | in-progress | BR-CA-SKELETON-OPERATIONAL-CONTRACT-057 | project-work-item | ca-skeleton-operational-contract | WI-CA-SKELETON-OPERATIONAL-CONTRACT-057 |
|
|
1 | 48cb041d3ff0bcd03ab8fb89745313d975a25f44f39b64d8eb849eb1d466e501 |
branch: feature-sample-portfolio-public-access
Layer:
raw/branch-notes/— sample-portfolio standalone demo URL 공개 정책과 관련 테스트 보정 기록.
부모 (필수)
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
1 - 패킷 스키마:
contract_packet: 1 - 완료 조건: sample public endpoint allowlist와 authenticated endpoint negative test가 명시된다
상속한 프로젝트 결정
| Decision Ref | Project Summary | Branch Application | Source |
|---|---|---|---|
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-MODULE-LAYOUT-001@1 |
Gradle multi-module에서 domain-core·application-core·adapter-*·shared-contract·app-bootstrap·sample-portfolio 책임을 분리한다 | Work Item 완료 조건에 적용 | raw/project-notes/ca-skeleton-operational-contract |
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-FRAMEWORK-001@1 |
framework는 Spring Boot 3.5.14다 | Work Item 완료 조건에 적용 | raw/project-notes/ca-skeleton-operational-contract |
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-TEST-001@1 |
test framework는 JUnit 5다 | Work Item 완료 조건에 적용 | raw/project-notes/ca-skeleton-operational-contract |
브랜치 지역 결정
기존 branch-local 결정은 아래
## Decision Evidence Map / 결정-근거 매핑의 D-row가 소유하며 이 packet에서 복제하지 않는다.
| Decision ID | Decision | Relation | Supporting Claims | Status |
|---|
선언한 예외
| Override ID | Overrides | Reason | Approval | Status |
|---|
목표
- 이슈: sample-portfolio는 별도 로그인/IdP 플로우가 없는 참고 구현인데, URL 확인 시 JWT와 method-security가 같이 걸려 데모 접근성이 떨어졌다.
- PR: 없음.
범위
포함 범위
- sample-portfolio standalone composition root에서 production JWT
SecurityConfig와MethodSecurityConfig를 스캔 제외한다. - sample-portfolio 전용
SecurityFilterChain을 추가해 모든 demo URL을permitAll로 공개한다. - sample actuator chain도 sample-local 정책으로 전체
permitAll처리한다. - 기존
:sample-portfolio:test포트 충돌을 막기 위해 web integration test의management.server.port를 랜덤 포트로 둔다.
제외 범위
- production
adapter-webJWT/authz 정책 변경. app-bootstrapproduction actuator 보안 정책 변경.- sample에 실제 로그인/IdP 플로우 추가.
근거 (필수, 최소 1개+)
| Source | 정당화하는 결정 |
|---|---|
| raw/official-docs/spring-security-authorization-architecture | method security가 AOP 기반으로 service/use case 호출을 가로채므로 sample runtime에서 URL 공개만으로는 write endpoint가 완전히 열리지 않는다는 판단 |
| raw/official-docs/actuator-endpoint-exposure-spring-official | custom SecurityFilterChain이 있으면 actuator auto-security에 의존할 수 없으므로 sample-local actuator chain을 명시해야 한다는 판단 |
| raw/official-docs/actuator-management-port-spring-official | management.server.port가 별도 HTTP port로 설정 가능하므로 테스트에서는 0으로 격리할 수 있다는 판단 |
TODO
- sample runtime에서 production JWT
SecurityConfig스캔 제외 — 등급:actually-implemented - sample runtime에서 production
MethodSecurityConfig스캔 제외 — 등급:actually-implemented - sample 전용 public
SecurityFilterChain추가 — 등급:actually-implemented - sample actuator chain 전체 공개 — 등급:
actually-implemented - sample web integration tests의 management port collision 제거 — 등급:
locally-verified
진행 중 메모
SecurityFilterChain만 공개하면 HTTP 필터는 통과하지만,@RequiresPermission이 붙은 sample use case는MethodSecurityConfigAOP advisor에 의해 여전히 unauthenticated/unauthorized로 막힌다.- 따라서 sample standalone runtime에서는 production authn/authz configuration을 composition root에서 제외해야 한다.
- 기존 권한 계약 테스트(
WorkLogAuthorizationContractTest,WorkLogAuthorizationE2ETest)는MethodSecurityConfig를 직접 import하는 보안 프레임워크 fixture로 유지했다.
결정 사항
- 2026-07-03: sample-portfolio standalone app은 로그인/IdP 없는 공개 데모로 취급하고 모든 sample URL을 permit-all로 연다. / 이유: 사용자가 브라우저/URL 접근으로 sample API를 확인할 수 있어야 한다. / 검토한 대안: public-paths에 sample 경로 열거, mock/demo login 추가, production security 그대로 유지. / 근거:
UNSUPPORTED_DECISION— 제품 정책 판단이며 외부 공식 문서가 직접 정당화하지 않는다. - 2026-07-03:
SecurityConfig뿐 아니라MethodSecurityConfig도 sample component scan에서 제외한다. / 이유: method security AOP가 write use case를 필터 이후에도 막기 때문이다. / 근거: raw/official-docs/spring-security-authorization-architecture - 2026-07-03: test-only web contexts는
management.server.port=0을 명시한다. / 이유: local process가 9001을 사용 중이어도:sample-portfolio:test가 deterministic하게 통과해야 한다. / 근거: raw/official-docs/actuator-management-port-spring-official
결정-근거 매핑
| Decision ID | Decision | 선택 조건 (언제 이 결정 / 언제 대안) | Supporting Claims | Evidence Strength | Open Risk |
|---|---|---|---|---|---|
| D1 | sample-portfolio standalone URL은 전부 공개한다. | 로그인/IdP 없는 sample demo일 때 이 결정. 운영 서비스나 민감 actuator가 있는 앱이면 production security 정책 유지. | UNSUPPORTED_DECISION |
project-policy |
sample을 운영 배포하면 actuator/loggers까지 공개되므로 별도 production profile 또는 sample 제거 필요 |
| D2 | sample composition root에서 SecurityConfig와 MethodSecurityConfig를 제외하고 sample-local permit-all chain을 둔다. |
sample runtime에서 write endpoint까지 열어야 할 때 이 결정. authz contract fixture는 별도 test import로 유지. | raw/official-docs/spring-security-authorization-architecture.md#SS-AUTHZ-ARCH-C2, raw/official-docs/spring-security-authorization-architecture.md#SS-AUTHZ-ARCH-C3 |
official-vendor-doc + UNSUPPORTED_DECISION |
Spring Security auto-config 조건 변화 시 sample chain 조건 재검증 필요 |
| D3 | sample actuator chain은 sample-local로 전체 permitAll한다. |
sample demo 확인성이 우선인 local/reference app일 때 이 결정. production actuator는 app-bootstrap 정책 유지. | raw/official-docs/actuator-endpoint-exposure-spring-official.md#SB-ACT-EXP-C2, raw/official-docs/actuator-endpoint-exposure-spring-official.md#SB-ACT-EXP-C3 |
official-vendor-doc + project-policy |
sample config를 운영에 재사용하면 노출 위험 |
| D4 | web integration tests는 management.server.port=0으로 격리한다. |
test context가 management server를 띄우고 local fixed port 충돌 가능성이 있을 때 이 결정. runtime default port는 유지. | raw/official-docs/actuator-management-port-spring-official.md#SB-ACT-PORT-C3 |
official-vendor-doc |
parallel test에서 다른 fixed port가 남아 있으면 별도 격리 필요 |
구현 가이드
1. sample runtime security override
Trace: D1, D2.
- UNSUPPORTED_IMPL_DECISION: sample config class/package naming은 repo local convention (
bootstrap.security)에 맞춘 결정.
| File | Implementation |
|---|---|
src/sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/SamplePortfolioApplication.java |
@ComponentScan exclude filter에 SecurityConfig, MethodSecurityConfig 추가 |
src/sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/bootstrap/security/SamplePublicAccessSecurityConfig.java |
servlet web app일 때만 /** matcher, CSRF disable, stateless, anyRequest().permitAll() chain 등록 |
src/sample-portfolio/src/main/java/dev/caskeleton/sample/portfolio/bootstrap/management/SampleManagementSecurityConfig.java |
servlet web app일 때 actuator endpoint chain 전체 permitAll() |
2. test port isolation
Trace: D4.
- UNSUPPORTED_IMPL_DECISION: affected tests에 property를 직접 붙이는 방식은 가장 좁은 변경을 위한 repo-local 판단.
| File | Implementation |
|---|---|
OpenApiSnapshotTest |
management.server.port=0 |
OpenApiDriftContractTest |
management.server.port=0 |
DateHeaderContractTest |
management.server.port=0 |
VirtualThreadMdcE2ETest |
management.server.port=0 |
엣지·실패·의존
- 실패·엣지 경로:
webEnvironment=NONEcontext에는HttpSecurity가 없으므로 sample security configs는@ConditionalOnWebApplication(SERVLET)로 제한해야 한다. - 실패·엣지 경로: sample URL 공개는 method-security 제외 없이는 write endpoint까지 보장하지 못한다.
- 다른 계약 의존: raw/branch-notes/feature-authentication-authorization-contract — production authn/authz contract는 변경하지 않고 sample fixture에서만 우회한다.
- 다른 계약 의존: raw/branch-notes/feature-management-actuator-security-contract — production actuator posture는 app-bootstrap 소유로 유지한다.
검증해야 할 주장
| Claim | Why uncertain | How to verify | Status |
|---|---|---|---|
| sample write endpoint가 Authorization 헤더 없이 통과한다. | filter-chain 공개와 method-security 제외가 함께 필요하다. | ./gradlew :sample-portfolio:test --tests dev.caskeleton.sample.portfolio.bootstrap.security.SamplePublicAccessSecurityConfigTest |
locally-verified |
| sample full context는 webEnvironment NONE에서도 뜬다. | HttpSecurity가 없는 context에서 security config bean 생성이 실패할 수 있다. |
./gradlew :sample-portfolio:test --tests dev.caskeleton.sample.portfolio.SampleApplicationContextTest --tests dev.caskeleton.sample.portfolio.bootstrap.security.SamplePublicAccessSecurityConfigTest |
locally-verified |
| sample-portfolio 전체 테스트가 fixed management port 충돌 없이 통과한다. | local 9001 process가 떠 있으면 기존 test가 실패했다. | ./gradlew :sample-portfolio:test |
locally-verified |
| 전체 repository check가 통과한다. | sample change가 ArchUnit/Spotless/Checkstyle/SpotBugs와 충돌할 수 있다. | ./gradlew check |
locally-verified |
마주친 문제
SamplePublicAccessSecurityConfigTest작성 직후SamplePublicAccessSecurityConfig가 없어서 컴파일 실패했다. TDD red 단계로 의도된 실패.@WebMvcTest에서HttpSecurity가 제공되지 않아 테스트 부트스트랩을 최소@SpringBootTest로 전환했다.SampleApplicationContextTest는webEnvironment=NONE이라 sample security configs에 servlet web app 조건을 추가했다../gradlew check1차 재실행은 Spotless import/indent 위반으로 실패했고:sample-portfolio:spotlessApply후 통과했다.- 기존 포트 충돌은 raw/errors/sample-portfolio-tomcat-port-in-use-check-2026-07-03 로 분리 기록했다.
묶음 (이 branch에서 파생된 자료)
- raw/errors/sample-portfolio-oauth2-resource-server-dependency-2026-05-27
- raw/errors/sample-portfolio-tomcat-port-in-use-check-2026-07-03
Sub-branches (세부 작업)
- 없음.
오류 기록 (이 branch 작업 중 발생)
- raw/errors/sample-portfolio-tomcat-port-in-use-check-2026-07-03 — sample web integration tests의 management fixed port 충돌을 test-only random port로 해결.
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- 없음 — 별도 면접 질문으로 추출할 만큼 독립적인 새 개념 없음.
강의 (이 작업을 위해 학습한 강의)
- 없음.
job-posting tie-ins (이 작업에서 파생된 글감)
- 추출할 별도 글감 없음.
관련 일일 노트
- 없음 — 2026-07-03 daily note가 아직 없어 broken wikilink를 만들지 않음.
완료 후 정리
- PR 링크:
- 리뷰 메모:
- 머지 결과 / 배포 환경: local verification only.
- wiki 추출 대상:
actually-implemented항목: sample runtime public access override.locally-verified항목: sample-portfolio tests and fullcheck.
- 추출하지 않을 항목:
- production security posture 변경 없음.